От байта[] до метки времени в миллисекундах

#c# #datetime #datetime-format #asp.net-core-3.1

Вопрос:

У меня есть такой простой буфер, как этот:

 Byte[] buffer = new byte[] { 0x01, 0x72, 0x60, 0x77, 0x59, 0x80};
 

И мне нужно получить дату из этого значения (оно указано в миллисекундах метки времени Unix).

Поэтому я попытался преобразовать в long, а затем перейти к функции, которую я нашел для преобразования из long в дату и время, вот так:

 public static DateTime unixTimeStampToDateTime(long unixTimeStamp)
{
    // Unix timestamp is seconds past epoch
    DateTime  dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime();
    return dtDateTime;
}
 

Я пытаюсь получить длинное значение из массива вот так:

     long timestamp = BitConverter.ToInt64(buffer,0);
 

Но я получаю эту ошибку:

 System.ArgumentException: 'Destination array is not long enough to copy all the items in the collection. Check array index and length. '
 

Что я здесь упускаю? Заранее спасибо.

ИЗМЕНИТЕ ожидаемое значение преобразования следующим образом: 05/29/2020 14:45

Комментарии:

1. Необычно представлять целое число в виде шести байтов. Это всегда шесть байтов? Что это за конец? (Есть ли где-нибудь спецификация, на которую вы можете указать нам?)

2. Я бы рекомендовал установить дату и время. Метод FromUnixTimeMilliseconds(Int64)

3. @JonSkeet, к сожалению, нет, конечность, с которой, я думаю, я мог бы справиться, если что, и, согласно документации, ожидаемый результат после преобразования в DateTime должен быть 29.05.2020 14:45, и да, это всегда шесть байт

4. Добавляю к тому, что говорит @jonskeet… в какое значение вы ожидаете преобразовать этот буфер? Откуда взялись эти 6 байтов?

5. «согласно документации» — какая документация? Простое знание того, откуда берутся эти байты, вероятно, будет иметь здесь все значение.

Ответ №1:

Вы можете попытаться Aggregate упорядочить элементы массива с помощью Linq, чтобы получить Int64 значение:

   using System.Linq;

  ... 

  byte[] buffer = new byte[] { 0x01, 0x72, 0x60, 0x77, 0x59, 0x80 };

  ...

  long shift = buffer.Aggregate(0L, (s, a) => s * 256   a);

  DateTime result = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
    .AddMilliseconds(shift);

  Console.WriteLine($"{result:d MMMM yyyy HH:mm:ss}");
 

Исход:

   29 May 2020 12:45:33
 

Как видите, времени 12:45 нет 14:45 , поэтому вы , наверное, захотите разобраться с DateTimeKind.Utc фрагментом. Если buffer представляет местное время, а не UTC:

   DateTime result = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddMilliseconds(shift);
 

если buffer представляет UTC, но вы хотите иметь местное время:

   DateTime result = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
    .AddMilliseconds(shift);

  result = result.ToLocalTime();