You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net中如何实现SystemTime与FileTime之间的相互转换?

嘿,我来帮你搞定.NET里SystemTime和FileTime的转换问题!

首先得说,你对FileTime的理解完全没错——它就是个64位值,记录从1601年1月1日UTC零点开始的100纳秒间隔数。至于为啥在Stack Overflow搜不到太多相关结果?其实是因为.NET里已经把这些Windows API的功能封装成了更易用的方法,大家很少直接用SystemTimeToFileTime这种原生API名称来提问,所以才会搜不到。

下面给你两种最常用的实现方式,按需选就行:

1. 用.NET内置的DateTime方法(最简单,推荐)

如果你不需要直接操作原生的SYSTEMTIME或FILETIME结构体,只是要在“类似SystemTime的日期时间”和FileTime数值之间转换,用DateTime的内置方法就够了,完全不用碰Windows API:

把日期时间(对应SystemTime)转成FileTime

直接调用ToFileTime()或者ToFileTimeUtc()方法,就能得到对应的64位FileTime值:

// 假设你有一个要转换的DateTime(比如当前UTC时间)
DateTime targetTime = DateTime.UtcNow;
// 转成UTC的FileTime
long fileTime = targetTime.ToFileTimeUtc();

把FileTime转成日期时间(对应SystemTime)

用FromFileTime()或FromFileTimeUtc()方法把64位数值转成DateTime,之后你可以直接获取年、月、日、时这些SystemTime包含的字段:

long fileTime = 133245678901234567;
// 转成UTC的DateTime
DateTime targetTime = DateTime.FromFileTimeUtc(fileTime);
// 现在可以获取各个字段,比如targetTime.Year、targetTime.Hour等等

2. 直接和原生SYSTEMTIME/FILETIME结构体交互

如果因为业务需求(比如和原生Windows API交互)必须直接操作这两个结构体,也有两种方式:

方式A:通过DateTime中转(不用P/Invoke)

先把结构体转成DateTime,再转成目标结构体,代码更简洁:

using System.Runtime.InteropServices.ComTypes;

// SYSTEMTIME转FILETIME
SYSTEMTIME systemTime = new SYSTEMTIME
{
    Year = 2024,
    Month = 5,
    Day = 20,
    Hour = 10,
    Minute = 30
};
// 先转成DateTime
DateTime dateTime = new DateTime(
    systemTime.Year, systemTime.Month, systemTime.Day,
    systemTime.Hour, systemTime.Minute, systemTime.Second,
    systemTime.Millisecond, DateTimeKind.Utc);
// 再转成FileTime数值,然后填充FILETIME结构体
long fileTimeValue = dateTime.ToFileTimeUtc();
FILETIME fileTimeStruct = new FILETIME
{
    dwLowDateTime = (int)(fileTimeValue & 0xFFFFFFFF),
    dwHighDateTime = (int)(fileTimeValue >> 32)
};

// FILETIME转SYSTEMTIME
FILETIME inputFt = new FILETIME();
// 假设已经给inputFt赋值了dwLowDateTime和dwHighDateTime
long inputFtValue = ((long)inputFt.dwHighDateTime << 32) | (uint)inputFt.dwLowDateTime;
DateTime inputDt = DateTime.FromFileTimeUtc(inputFtValue);
SYSTEMTIME outputSt = new SYSTEMTIME
{
    Year = (ushort)inputDt.Year,
    Month = (ushort)inputDt.Month,
    Day = (ushort)inputDt.Day,
    Hour = (ushort)inputDt.Hour,
    Minute = (ushort)inputDt.Minute,
    Second = (ushort)inputDt.Second,
    Millisecond = (ushort)inputDt.Millisecond,
    DayOfWeek = (ushort)inputDt.DayOfWeek
};

方式B:直接调用Windows API(P/Invoke)

如果你一定要用原生的SystemTimeToFileTime和FileTimeToSystemTime函数,也可以用P/Invoke来实现:

using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SystemTimeToFileTime([In] ref SYSTEMTIME lpSystemTime, out FILETIME lpFileTime);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FileTimeToSystemTime([In] ref FILETIME lpFileTime, out SYSTEMTIME lpSystemTime);

// 使用示例
SYSTEMTIME inputSt = new SYSTEMTIME { Year = 2024, Month = 5, Day = 20 };
FILETIME outputFt;
if (SystemTimeToFileTime(ref inputSt, out outputFt))
{
    // 转换成功,outputFt就是结果
}

SYSTEMTIME outputSt;
if (FileTimeToSystemTime(ref outputFt, out outputSt))
{
    // 转换成功,outputSt就是结果
}

总结一下:日常开发优先用第一种DateTime内置方法,简单省心;如果要和原生API交互,再选第二种方式。

内容的提问来源于stack exchange,提问作者user1889116

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:20:00