Как мы можем преобразовать datetime в строку, представляющую временную метку Unix в наносекундах, используя Matlab? - PullRequest
1 голос
/ 16 июня 2020

Я пытаюсь использовать Matlab для создания строки, которая содержит временную метку Unix в наносекундах (т.е. наносекунды с 01 января 1970 г. 00:00:00, Unix эпоха ) из строка даты ввода.

Например, если мой ввод составляет всего 1 нс после начала эпохи, то работает следующий код:

t0 = datetime('01-Jan-1970 00:00:00.000000000','Format','dd-MMM-yyyy HH:mm:ss.SSSSSSSSS');
t1 = datetime('01-Jan-1970 00:00:00.000000001','Format','dd-MMM-yyyy HH:mm:ss.SSSSSSSSS');

dt_ns = seconds(t1 - t0)*1e9
dt_ns_string = sprintf('%.0f',dt_ns)

dt_ns_string =

    '1'

и у меня точность наносекунд Мне нужно.

Однако, если я вместо t1 использую дату примерно сегодня:

t1 = datetime('16-Jun-2020 00:00:00.000000001','Format','dd-MMM-yyyy HH:mm:ss.SSSSSSSSS');

, то результат будет следующим:

dt_ns_string =

    '1592265600000000000'

и Я потерял последнюю наносекунду с точностью до конца строки (последний символ должен быть «1»).

Как я могу решить эту проблему?


EDIT

Как было предложено в комментариях, существует также функция Matlab posixtime(), которая устраняет необходимость вручную вычитать дату и время, соответствующие 01 января 1970 года. Однако это приводит к той же проблеме:

dt_ns_posix = posixtime(t1)*1e9
sprintf('%.0f',dt_ns_posix)

    '1592265600000000000'

1 Ответ

1 голос
/ 17 июня 2020

Вот подход, который позволяет избежать потери точности, присущей double:

  1. Используйте between с необязательным третьим входом, чтобы получить разницу во времени как calendarDuration скаляр, указывающий дни, часы, минуты и секунды.
  2. Преобразуйте в char и извлеките отдельные числа дней, часов, минут и секунд.
  3. Умножьте каждое значение на 1e9 и преобразовать в uint64. Обратите внимание, что каждое отдельное значение, умноженное на 1e9, дает целое число, которое находится в пределах точности с плавающей запятой (т.е. не превышает 2^53).
  4. Используйте умножение и sum с опцией 'native', чтобы получить общее количество наносекунд в виде uint64 значения.

t0 = datetime('01-Jan-1970 00:00:00.000000000','Format','dd-MMM-yyyy HH:mm:ss.SSSSSSSSS');
t1 = datetime('16-Jun-2020 00:00:00.000000001','Format','dd-MMM-yyyy HH:mm:ss.SSSSSSSSS');
b = between(t0, t1, {'Days', 'Time'});
t = str2double(regexp(char(b), '(?<=(^| )).+?(?=[dhms$])', 'match')); % split d, h, m, s
if numel(t)==3 % if the number of days is 0 it will not be present
  t = [0 t];
end
result = sum(uint64(t*1e9).*uint64([86400 3600 60 1]), 'native'); % sum as uint64

Это дает

result =
  uint64
   1592265600000000001
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...