2012-11-13 21 views
11

Spojrzałem na DateTime Równa realizacja:Porównywanie dat według czasu według wewnętrznych znaczników?

public bool Equals(DateTime value) 
{ 
    return (this.InternalTicks == value.InternalTicks); 
} 

a następnie spojrzeć na internalticks

internal long InternalTicks 
{ 
    [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 
    get 
    { 
     return (((long) this.dateData) & 0x3fffffffffffffffL); 
    } 
} 

I wtedy zauważyłem, że ten numer: 0x3fffffffffffffffL

która jest: 4611686018427387903

Ale więcej interesujące jest jego binarny reprezentacja:

00111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
^^ 
|| 

Proszę zauważyć strzałkami

mogłem zrozumieć jeśli tylko w lewo strzałka byłby 0 (dodatnia reprezentacja)

  • Ale dlaczego drugi jest również 0?

  • Ponadto, dlaczego chciałbym, aby każdy miał numer & z numerem 1111....? jeśli chcę, aby wyświetlić 5 Nie mam zrobić 5 & 1, zaledwie 5.

pomocy?

Odpowiedz

7

Możesz uzyskać tego rodzaju informacje z Reference Source. Najbardziej odpowiednie deklaracje w dd/NPR/clr/src/bcl/system/datetime.cs:

private const UInt64 TicksMask    = 0x3FFFFFFFFFFFFFFF; 
    private const UInt64 FlagsMask    = 0xC000000000000000; 
    private const UInt64 LocalMask    = 0x8000000000000000; 
    private const Int64 TicksCeiling   = 0x4000000000000000; 
    private const UInt64 KindUnspecified  = 0x0000000000000000; 
    private const UInt64 KindUtc    = 0x4000000000000000; 
    private const UInt64 KindLocal    = 0x8000000000000000; 
    private const UInt64 KindLocalAmbiguousDst = 0xC000000000000000; 
    private const Int32 KindShift = 62; 

zauważyć, jak odwzorować Kind wartości tych dwóch bitów.

public DateTime(long ticks, DateTimeKind kind) { 
     // Error checking omitted 
     //... 
     this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift)); 
    } 
+0

Złożenie zer po lewej stronie (2 zera) przypomina porównywanie bez DateTimeKind ... prawda? –

+1

Dobrze. Jest to * maska ​​*, za pomocą operatora & maskuje wartości tych bitów i czyni je zerowymi. –

+2

@RoyiNamir Tak, podczas porównywania ignoruje 'Kind', maskując go. (Zła decyzja IMO) – CodesInChaos

4

Pole dateData jest używane jak bit field do przechowywania wielu wartości w kompaktowym formacie.

Dwa najlepsze bity przechowuje DateTimeKind, który ma jedną z czterech możliwych wartości: Nieokreślony, Lokalny (wewnętrznie istnieją dwa warianty) lub Utc. Te cztery wartości mogą być przechowywane w dwóch bitach.

Dno 62 bity przechowuje znaczniki. Operacja x & 0x3fffffffffffffffL jest operacją bitową - i czasami nazywana jest także masking. Zwraca tylko te bity, które odpowiadają kleszczom.

+1

Wewnętrznie ma 4 różne wartości. Istnieją dwa różne warianty 'Local', które współdziałają inaczej z przełączaniem DST. – CodesInChaos

+0

Proszę zobaczyć moją edycję- nie ma wartości dołączone do niego. –

+0

@RoyiNamir Nie rozumiem, co twoja zmiana chce powiedzieć, ale odpowiedź Marka jest prawidłowa. – CodesInChaos

Powiązane problemy