3 votes

Quelle est la différence entre DateTime.ToBinary() et DateTime.ToFileTime() ?

Quelqu'un peut-il m'expliquer la différence entre DateTime.ToBinary() y DateTime.ToFileTime() ? Pour autant que je sache, ils semblent toujours renvoyer la même valeur (lorsqu'il s'agit d'heures UTC, du moins). Il en va de même pour DateTime.FromBinary() y DateTime.FromFileTime() .

J'ai essayé d'utiliser Réflecteur et je peux voir certaines différences, mais je ne comprends pas la pertinence des chiffres magiques :

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);
}

3voto

Hans Passant Points 475940

ToBinary() et ToFileTimeUtc() font pas renvoient la même valeur. ToBinary fournit une valeur aller-retour, un Int64 qui peut conserver les propriétés d'un DateTime. Il utilise la même base de temps, le 1er janvier de l'année 0. La valeur est toujours UTC. Le bit 62 est activé pour le cas extrême où une heure locale proche du 1/1/00 serait négative lorsqu'elle est convertie en UTC (attention aux détails ici :)). Le bit 63 est activé lorsque le Kind est UTC. Convertissez le nombre magique en hexadécimal pour le voir.

ToFileTimeUtc() utilise la même base de temps que FILETIME de Windows, le 1er janvier de l'année 1601. Le nombre magique est le nombre de ticks pour 12h, 1/1/1601.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X