Сначала вам понадобится метод утилиты, который считывает байты из потока и обрабатывает значение endian-ness. Это может выглядеть следующим образом:
public static byte[] ReadBytes(Stream s, int size, bool littleEndian) {
var bytes = new byte[size];
var len = s.Read(bytes, 0, size);
if (len != size) throw new InvalidOperationException("Unexpected end of file");
if (BitConverter.IsLittleEndian != littleEndian) Array.Reverse(bytes);
return bytes;
}
даты Окна легко, поддерживаются DateTime.FromFileTimeUtc() непосредственно:
public static DateTime ConvertWindowsDate(byte[] bytes) {
if (bytes.Length != 8) throw new ArgumentException();
return DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0));
}
Тестирование это с значением:
var date1 = DateReaders.ConvertWindowsDate(DateReaders.ReadBytes(
new MemoryStream(new byte[]{0xFF,0x03,0xD2,0x31,0x5F,0xE1,0xC7,0x01}), 8, true));
Производит {8/18/2007 6:15:37 AM}, как и ожидалось.
Даты OLE просты, поддерживаемые DateTime.FromOADate() непосредственно:
public static DateTime ConvertOLEDate(byte[] bytes) {
if (bytes.Length != 8) throw new ArgumentException();
return DateTime.FromOADate(BitConverter.ToDouble(bytes, 0));
}
Тестирование это с значением:
var date2 = DateReaders.ConvertOLEDate(DateReaders.ReadBytes(
new MemoryStream(new byte[] {0xFB,0xE8,0xDF,0x97,0x5D,0x3F,0xE3,0x40 }), 8, true));
Производит {12/2/2007 10:11:41 PM}
значения даты Unix являются миллисекунд с 1 января 1970 года, 0:00 утра UTC:
public static DateTime ConvertUnixDate(byte[] bytes) {
if (bytes.Length != 4) throw new ArgumentException();
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(
BitConverter.ToUInt32(bytes, 0));
}
Тестирование это с вашим значением:
var date3 = DateReaders.ConvertUnixDate(DateReaders.ReadBytes(
new MemoryStream(new byte[] {0x46,0xC3,0xB4,0x00}), 4, false));
Производит {8/16/2007 2:18:40 AM}
Apple Mac абсолютное время is documented зависеть CPU и требует преобразования на машине который породил его. Показанное значение «219216022» является изворотливым, оно представляется десятичным, а не шестнадцатеричным, как и все остальные. Я буду следовать примеру Baldrick с:
public static DateTime ConvertAppleDate(byte[] bytes) {
if (bytes.Length != 4) throw new ArgumentException();
return new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(
BitConverter.ToUInt32(bytes, 0));
}
даты HFS являются секунд с 1 января 1904 года, 0:00 AM. Обратите внимание, что даты HFS - это местное время, но даты HFS Plus - UTC. Я предполагаю, местный, так как это результат, который вы документально:
public static DateTime ConvertHFSDate(byte[] bytes) {
if (bytes.Length != 4) throw new ArgumentException();
return new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(
BitConverter.ToUInt32(bytes, 0));
}
Тестирование это с значением:
var date5 = DateReaders.ConvertHFSDate(DateReaders.ReadBytes(
new MemoryStream(new byte[] {0xCD,0x4E,0x55,0xC3 }), 4, true));
Производит {11/5/2007 10:50:53 PM}
Пусть я начинаю с очевидного вопроса: проверили ли вы фактические спецификации для этих форматов? – quetzalcoatl
BTW. вы имеете в виду [этот HFS] (http://en.wikipedia.org/wiki/Hierarchical_File_System)? – quetzalcoatl