Наносекунд до DateTimeOffset - PullRequest
       24

Наносекунд до DateTimeOffset

0 голосов
/ 28 января 2020

Я использую. Net версия 4.6, и я использую DateTimeOffset.FromUnixTimeMilliseconds для преобразования наносекунд в DateTimeOffset.

long j = 1580122686878258600;
var X = DateTimeOffset.FromUnixTimeMilliseconds(Convert.ToInt64(j * 0.000001));

Я сохраняю наносекунды как long, все же мне нужно сделать преобразование до Int64 при умножении на 0,000001 для преобразования нано секунд в миллисекунды.

Есть ли другой лучший способ?

1 Ответ

0 голосов
/ 28 января 2020

Да, если вы не хотите снова преобразовывать это значение в (long), вы можете вместо этого делить на 1000000 вместо умножения на 0.000001.

Но если вам нужно умножить, то нет, в этом случае вы должны преобразовать результат умножения long и double обратно в long. Во-первых, значение 0.000001 имеет тип double. Во-вторых, компилятор подразумевает преобразование long в double для умножения между этими двумя типами, и результатом будет также double. Причина подразумеваемого преобразования заключается в том, что при преобразовании обратно в long будет потеря точности (десятичных знаков). Метод DateTimeOffset.FromUnixTimeMilliseconds() принимает только один параметр long (long и Int64 - это один и тот же тип данных, long - просто псевдоним для Int64), поэтому вы должны преобразовать свой результат обратно.

В случае деление на 1000000, деление на два значения long все еще приводит к делению, но любые десятичные разряды усекаются.

В обоих случаях вы можете рассмотреть влияние округления и потери точности, при желании Вы получите другое значение, если вы используете нано значение 1580122686878999999. Для умножения long и double (т.е. (long)(1580122686878999999 * 0.000001)) получается 1580122686879. Но, используя деление long, вы вместо этого получаете 1580122686878.

У меня также есть некоторые побочные комментарии к реализации, предлагающие несколько альтернатив:

Если вы этого не сделаете как и запись Convert.ToInt64() самого вызова, тогда вы можете использовать стандартное приведение (то есть (long)(j * 0.000001)). Если вам не нравится это делать, вы можете сконструировать DateTimeOffset, используя конструктор, который вместо этого принимает «галочки», который вы можете получить из структуры TimeSpan, которая имеет метод FromMilliseconds(), который принимает double (например, new DateTimeOffset(TimeSpan.FromMilliseconds(j * 0.000001).Ticks, TimeSpan.Zero)). Тем не менее приведение является наиболее простым и лаконичным кодом.

Далее, расширив описанный выше конструктор "ticks", лучшим решением может стать разделение на "ticks", которые равны 100- наносекунды и точнее, чем миллисекунды. В этом случае вы можете достичь «тиков», разделив наносекунды на 100 (умножив на 0,01), чтобы получить еще большую точность, например, new DateTimeOffset((long)(j * 0.01), TimeSpan.Zero). Я предлагаю это только с мыслью, что вам может потребоваться максимально возможная точность из начального значения наносекунд.

...