2012-11-13 12 views
11

Ho guardato DateTime Uguale applicazione:DateTime confrontando con tick interni?

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

e poi guardare internalticks

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

E poi ho notato questo numero: 0x3fffffffffffffffL

che è: 4611686018427387903

Ma altro interessante è il suo binario rappresentazione:

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

Si prega di notare le frecce

ho potuto capire se solo il freccia a sinistra sarebbe stato 0 (rappresentazione positiva)

  • Ma perché il secondo è anche 0?

  • Inoltre, perché vorrei che fosse & con un numero 1111....? se voglio visualizzare 5 non ho a che fare 5 & 1, appena 5.

Qualsiasi aiuto?

risposta

7

È possibile ottenere questo tipo di informazioni dallo Reference Source. Le dichiarazioni più rilevanti gg/NDP/CLR/src/BCL/Sistema/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; 

notare come la saluti valori della mappa a quei due bit.

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

Quindi mettere gli zero a sinistra (2 zeri) è come confrontare senza il DateTimeKind ... giusto? –

+1

Giusto. È una * maschera *, che usa l'operatore & nasconde i valori di quei bit e li rende zero. –

+2

@RoyiNamir Sì, ignora il "Tipo" quando lo si confronta mascherandolo. (Decisione errata IMO) – CodesInChaos

4

Il campo dateData viene utilizzato come un bit field per memorizzare più valori in un formato compatto.

I primi due bit memorizzano DateTimeKind, che ha uno dei quattro valori possibili: Non specificato, Locale (internamente ci sono due varianti) o Utc. Questi quattro valori possono essere memorizzati in due bit.

I 62 bit inferiori memorizzano i segni di graduazione. L'operazione x & 0x3fffffffffffffffL è un'operazione bit a bit e talvolta chiamata anche masking. Restituisce solo i bit che corrispondono ai tick.

+1

Internamente in realtà ha 4 valori diversi. Esistono due diverse varianti di 'Local' che interagiscono in modo diverso con la commutazione dell'ora legale. – CodesInChaos

+0

per favore vedi la mia modifica- non ha valori ad essa associati. –

+0

@RoyiNamir Non capisco cosa voglia dire la tua modifica, ma la risposta di Mark è corretta. – CodesInChaos