DateTime ToFileTime and ToFileTimeUtc have same output
There's good information in the existing answers, but let me attempt a pragmatic summary:
The only time the distinction between System.DateTime.ToFileTime()
and System.DateTime.ToFileTimeUtc()
matters is when the instance's .Kind
property equals Unspecified
, i.e., if it's unclear whether the time value represents a local or UTC time.
This information was actually in an answer by Hans Passant that he himself deleted.
In other word: for System.DateTime
instances whose .Kind
property equals either Local
or Utc
(the only other possible values), System.DateTime.ToFileTime()
and System.DateTime.ToFileTimeUtc()
behave identically - this is what the OP experienced, because his input value was of .Kind
Local
(the kind returned by File.GetCreationTime()
).
Note that the related System.DateTimeOffset
type by design always carries explicit UTC offset information, so there's never ambiguity, which is probably why that type has only a .ToFileTime()
method (and not also .ToFileTimeUtc()
).
As others have noted, the return value always represents a UTC time:
File time values by definition, invariably represent a point in time in UTC.
Thus, both
.ToFileTime()
and.ToFileTimeUtc()
create a point in time expressed as the count of 100ns intervals since midnight January 1, 1601 UTC.
To complement the OP's own example with one where .ToFileTime()
and .ToFileTimeUtc()
do differ in outcome:
// 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()
);
Sample output in the US Eastern time zone:
180000000000 // 1601-01-01T05:00:00Z - 5 AM UTC
0 // 1601-01-01T00:00:00Z - midnight UTC
From the docs:
A Windows file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC). Windows uses a file time to record when an application creates, accesses, or writes to a file.
The number of nanoseconds since 1-1-1601 UTC, don't change no matter in which timezone you are.
From the source of the .net framwork:
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;
}
So when you use ToFileTimeUtc
and you have an unspecified DateTime
it gives you the nanosecs since 1-1-1601, no matter what timezone it's originally from. Which could for an hour each year if the timezone has DST give you an invalid time.