2013-04-10 18 views
6

Bir DateTime nesnesini (örneğin bir BinaryWriter kullanarak) düzgün şekilde serileştirir ve tüm durumunu korur muyum?Serialize DateTime ikili olarak

Bir tarihin yalnızca dahili bir uzun tamsayı ile temsil edildiğinin ve bu tamsayıya DateTime'ın Ticks özelliğinin erişilebilir olduğu izlenimindeydim.

public long InternalTicks 
{ 
    get { return (long) this.dateData & 4611686018427387903L; } 
} 

: Ancak, uygulama bakarak, Keneler özelliği aslında bir ulong depolanan gerçek iç verilerin bir alt kümesi dateData

Keneler (sadece InternalTicks alır) şöyle uygulanır denilen döndürür Görebildiğim kadarıyla, dateData, Ticks özelliği tarafından açığa çıkmayan bilgiler içerebilir.

henüz yabancı bir DateTime BinaryFormatter Serile GetObjectData() yapar: çıktısı akışında iki uzun ürünler, bunlardan biri kolayca diğerinden recovererd olacağını

info.AddValue("ticks", this.InternalTicks); 
info.AddValue("dateData", this.dateData); 

!

DateTime'ımı dahili durumlardan herhangi birini kaybetme riski olmadan nasıl serileştirebilirim (tercihen yalnızca 8 bayt ve yansıma olmadan). Düşünüyorum belki de direk (güvensiz), direk bir ulonga olabilir mi?

Yoksa hiçbir neden için endişeleniyorum, Ticks özelliği aslında gerekli tüm durumu kodlayacak mı?

+1

Şahsen sadece DateTim kullanayım Yerel tarihler için "UTC" tarihleri ​​ve "DateTimeOffset" e. O halde 'Kind''i saklamaktan endişelenmenize gerek yok, sadece 'UTC' dır. – CodesInChaos

+0

Serileştirilmiş tarihlerin türlerini denetlemiyorum. –

cevap

8

endişelenecek iki bilgi vardır: bunlar hem tek bir uzun kodlanmasını

  • Keneler
  • DateTimeKind Dahili

, şöyle dateData:

this.dateData = (ulong) (ticks | (((long) kind) << 62)); 

Yani Ticks özelliği olacaktır. tüm durumu kodlar. DateTimeKind bilgileri eksik olacak.

dateData kodlamak tüm verileri yapar, bu yüzden garip bir duygudur o serialiser depolar de o veTicks olduğunu!

Peki yapabileceği şudur:

ulong dataToSerialise = (ulong) (date.Ticks | ((long) date.Kind) << 62); 

Ve deserializing zaman bunu yapabilirsiniz:

long ticks = (long)(deserialisedData & 0x3FFFFFFFFFFFFFFF); 
DateTimeKind kind = (DateTimeKind)(deserialisedData >> 62); 
DateTime date = new DateTime(ticks, kind); 

Bu DateTime donanımları hakkında bilgi faydalanmak yapar ve o olabilir Bu tür bir serileştirmeyi kırabilecek gelecekteki teorik olarak değişir.


DÜZENLEME

yerel saat ayarı ile ilgisi Bazı FRİKİKLERİNDEN vardır.

Yani bunu yerine yukarıdaki tüm ile uğraşmaktansa önermek için gidiyorum, sen bir sürece getirilmeye izin verecek DateTime.ToBinary() ve DateTime.FromBinary() yöntemlerle yerel ilişkin uyarılar tabi bakmak zaman ayarı. Bu uyarılar, yukarıdaki MSDN bağlantılarında tam olarak belgelenmiştir.

+0

Teşekkürler, soru şudur: özel alan dateData bir BinaryWriter nasıl yazılır. Yani: içsel durumu olan ulong'a nasıl bir güvensizlik yaparım? –

+0

Sadece iç uygulamanın ne yaptığını kopyalayın. Bir dakika içinde bir örnekle güncelleyeceğim. –

+0

ah, değerleri bir araya getirmek ya da demek. Zeki. –

5

i TCP Sockets burada

tarih iletmek için serileştirme ile yapmış sen BinaryFormatter

//uses 8 byte 
DateTime tDate = DateAndTime.Now; 
long dtVal = tDate.ToBinary(); 
//64bit binary 

byte[] Bits = BitConverter.GetBytes(tDate.ToBinary()); 
//your byte output 

//reverse 
long nVal = BitConverter.ToInt64(Bits, 0); 
//get 64bit binary 
DateTime nDate = DateTime.FromBinary(nVal); 
//convert it to date 
olmadan bu

public static byte[] DateToBytes(DateTime _Date) 
{ 
    using (System.IO.MemoryStream MS = new System.IO.MemoryStream()) { 
     BinaryFormatter BF = new BinaryFormatter(); 
     BF.Serialize(MS, _Date); 
     return MS.GetBuffer(); 
    } 
} 


public static DateTime BytesToDate(byte[] _Data) 
{ 
    using (System.IO.MemoryStream MS = new System.IO.MemoryStream(_Data)) { 
     MS.Seek(0, SeekOrigin.Begin); 
     BinaryFormatter BF = new BinaryFormatter(); 
     return (DateTime)BF.Deserialize(MS); 
    } 
} 

EDIT'e

gibi herhangi bir nesne seri bir koddur

+1

Belki daha açık olsaydı: Yansıma veya binaryformatter kullanmak istemiyorum ve nedeni hızlı olması ve yalnızca 8 bayt kullanması gerektiğidir. –

+0

BitConverter, yeni sınıf bana ve basit bir çözüm temizliği için sahne. :-) –