C# DateTime ToFileTime和ToFileTimeUtc具有相同的输出

C# DateTime ToFileTime和ToFileTimeUtc具有相同的输出,c#,datetime,C#,Datetime,我打开一个文件,使用ToUniversalTime()和ToLocalTime()输出不同的时间。但是,当我使用ToFileTime()和ToFileTimeUtc()时,得到的数字是相同的。为什么会这样 DateTime creationTime = File.GetCreationTime(@"c:\windows\setupact.log"); Console.WriteLine("utc time: " + creationTime.ToUniversalTime()); Console

我打开一个文件,使用
ToUniversalTime()
ToLocalTime()
输出不同的时间。但是,当我使用
ToFileTime()
ToFileTimeUtc()
时,得到的数字是相同的。为什么会这样

DateTime creationTime = File.GetCreationTime(@"c:\windows\setupact.log");
Console.WriteLine("utc time: " + creationTime.ToUniversalTime());
Console.WriteLine("file time: " + creationTime.ToLocalTime());
Console.WriteLine("file: " + creationTime.ToFileTime());
Console.WriteLine("utc: " + creationTime.ToFileTimeUtc());
输出

utc时间:2013年8月22日下午2:46:17

存档时间:2013年8月22日上午7:46:17

档案号码:130216563774628355

utc:130216563774628355

文件和utc不应该不同吗?

与文档不同:

Windows文件时间是一个64位的值,表示 从午夜12:00开始的100纳秒间隔, 公元1601年1月1日,协调世界时(UTC)。窗户 使用文件时间记录应用程序创建、访问或删除的时间 写入文件

自1-1-1601 UTC起的纳秒数,无论您在哪个时区都不会改变

从.net框架的来源:

public long ToFileTime() {
    // Treats the input as local if it is not specified
    return ToUniversalTime().ToFileTimeUtc();
}

public long ToFileTimeUtc() {
    // Treats the input as universal if it is not specified
    long ticks = ((InternalKind & LocalMask) != 0) ? ToUniversalTime().InternalTicks : this.InternalTicks;
    ticks -= FileTimeOffset;
    if (ticks < 0) {
        throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
    }
    return ticks;
}
public long-ToFileTime(){
//如果未指定输入,则将其视为本地输入
返回ToUniversalTime().ToFileTimeUtc();
}
公共长ToFileTimeUtc(){
//如果未指定输入,则将其视为通用输入
长滴答声=((InternalKind&LocalMask)!=0)?ToUniversalTime();
ticks-=FileTimeOffset;
如果(刻度<0){
抛出新ArgumentOutOfRangeException(null,Environment.GetResourceString(“ArgumentOutOfRange_FileTimeInvalid”);
}
返回滴答声;
}
因此,当您使用
ToFileTimeUtc
时,如果您有一个未指定的
DateTime
,它将为您提供自1601年1月1日起的NanoSec,无论它最初来自哪个时区。如果时区有DST给你一个无效的时间,每年可能有一个小时

如果您查看上的文档,它会说:

Windows文件时间是一个64位值,表示自公元1601年1月1日午夜12:00(C.E.)协调世界时(UTC)以来经过的100纳秒间隔数。Windows使用文件时间记录应用程序创建、访问或写入文件的时间

所有文件时间都存储在UTC中。然后,诸如Explorer之类的应用程序将UTC时间转换为本地时间,以便显示


如果您进一步查看的备注部分,您将看到“来电者注意事项”部分。这进一步解释了如何使用和预期使用。

现有答案中有很好的信息,但让我尝试一个务实的总结:

只有当实例的
.Kind
属性等于
未指定的
时,
System.DateTime.ToFileTime()
System.DateTime.ToFileTimeUtc()
之间的区别才有意义,也就是说,如果不清楚时间值是表示本地时间还是UTC时间
这个信息实际上是他自己删除的答案

换句话说:对于
System.DateTime
实例,其
.Kind
属性等于
Local
Utc
(唯一其他可能的值),
System.DateTime.ToFileTime()
System.DateTime.ToFileTimeUtc()
行为相同
-这是OP所经历的,因为他的输入值是
.Kind
本地的
(由
文件.GetCreationTime()返回的类型)

请注意,相关的
System.DateTimeOffset
设计类型始终带有明确的UTC偏移量信息,因此从不存在歧义,这可能就是该类型只有
.ToFileTime()
方法(而不是
.ToFileTimeUtc()
)的原因

正如其他人所指出的,返回值始终表示UTC时间:

  • 根据定义,文件时间值始终表示UTC中的一个时间点。

  • 因此,无论是
    .ToFileTime()
    还是
    .ToFileTimeUtc()
    都会创建一个时间点,表示为自UTC 1601年1月1日午夜以来的100ns间隔计数

要用
.ToFileTime()
.ToFileTimeUtc()
在结果上有所不同的例子来补充OP自己的例子:

// Create a DateTime instance with .Kind equal to Unspecified;
// use the earliest date that can be represented as a file time.
DateTime dtUnspecified = DateTime.Parse("1601-01-01");

Console.WriteLine(
    dtUnspecified.ToFileTime() + "\n" +
    dtUnspecified.ToFileTimeUtc()
);
美国东部时区的样本输出:

180000000000  // 1601-01-01T05:00:00Z - 5 AM UTC
0             // 1601-01-01T00:00:00Z - midnight UTC

链接文档提供了更多信息detail@DStanley,我不知道链接的文档是否是最新的。到GotDotNet的链接已断开,谷歌搜索没有找到GotDotNet的网页。此外,我还测试了C++中对LoalFielTimeFieleTeMe()的数字。这需要本地时间并将其转换为UTC。ToFileTimeUtc的输出与C++中的本地时间相同,而不是UTC时间。北美洲的西海岸是什么时候?