Чем отличаются DateTime.ToBinary () и DateTime.ToFileTime ()? - PullRequest
1 голос
/ 25 октября 2010

Кто-нибудь может помочь объяснить разницу между DateTime.ToBinary () и DateTime.ToFileTime () ?Насколько я могу судить, они, похоже, всегда возвращают одно и то же значение (по крайней мере, когда речь идет о времени UTC).То же самое относится к DateTime.FromBinary () и DateTime.FromFileTime () .

Я пытался использовать Reflector , и я вижунекоторые различия, я просто не понимаю актуальность магических чисел:

public long ToBinary()
{
    if (this.Kind != DateTimeKind.Local)
    {
        return (long) this.dateData;
    }
    TimeSpan utcOffset = TimeZoneInfo.Local.GetUtcOffset(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
    long num2 = this.Ticks - utcOffset.Ticks;
    if (num2 < 0L)
    {
        num2 = 0x4000000000000000L + num2;
    }
    return (num2 | -9223372036854775808L);
}

public long ToFileTime()
{
    return this.ToUniversalTime().ToFileTimeUtc();
}

public long ToFileTimeUtc()
{
    long num = ((this.InternalKind & 9223372036854775808L) != 0L) ? this.ToUniversalTime().InternalTicks : this.InternalTicks;
    num -= 0x701ce1722770000L;
    if (num < 0L)
    {
        throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
    }
    return num;
}

public static DateTime FromFileTime(long fileTime)
{
    return FromFileTimeUtc(fileTime).ToLocalTime();
}

public static DateTime FromFileTimeUtc(long fileTime)
{
    if ((fileTime < 0L) || (fileTime > 0x24c85a5ed1c03fffL))
    {
        throw new ArgumentOutOfRangeException("fileTime", Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
    }
    return new DateTime(fileTime + 0x701ce1722770000L, DateTimeKind.Utc);
}

public static DateTime FromBinary(long dateData)
{
    long num2;
    if ((dateData & -9223372036854775808L) == 0L)
    {
        return FromBinaryRaw(dateData);
    }
    long ticks = dateData & 0x3fffffffffffffffL;
    if (ticks > 0x3fffff36d5964000L)
    {
        ticks -= 0x4000000000000000L;
    }
    bool isAmbiguousLocalDst = false;
    if (ticks < 0L)
    {
        num2 = TimeZoneInfo.Local.GetUtcOffset(MinValue, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
    }
    else if (ticks > 0x2bca2875f4373fffL)
    {
        num2 = TimeZoneInfo.Local.GetUtcOffset(MaxValue, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
    }
    else
    {
        DateTime time = new DateTime(ticks, DateTimeKind.Utc);
        bool isDaylightSavings = false;
        num2 = TimeZoneInfo.GetUtcOffsetFromUtc(time, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
    }
    ticks += num2;
    if (ticks < 0L)
    {
        ticks += 0xc92a69c000L;
    }
    if ((ticks < 0L) || (ticks > 0x2bca2875f4373fffL))
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), "dateData");
    }
    return new DateTime(ticks, DateTimeKind.Local, isAmbiguousLocalDst);
}

1 Ответ

2 голосов
/ 25 октября 2010

ToBinary () и ToFileTimeUtc () делают , а не возвращают одно и то же значение.ToBinary предоставляет значение туда-обратно, Int64, которое может сохранять свойства DateTime.Он использует ту же базу времени, 1 января года 0. Значение всегда UTC.Бит 62 установлен для крайнего углового случая, когда местное время около 1/1/00 будет отрицательным при преобразовании в UTC (обращая внимание на детали здесь :)).Бит 63 устанавливается, когда типом является UTC.Преобразуйте магическое число в шестнадцатеричное, чтобы увидеть это.

ToFileTimeUtc () использует ту же базу времени, что и Windows FILETIME, 1 января 1601 года. Магическое число - это количество тиков за 12 часов, 1/1/1601.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...