Метод C# DateTime.Parse теряет наносекундную точность строки метки времени

Мне нужно преобразовать временную метку в формате RFC-3339 (например, «2024-01-04T14:30:00.119919872Z») в наносекундную временную метку Unix (например, 1704378600119919872). Однако максимальная точность структур DateTime в C# составляет всего 100 наносекунд. Например:

string timestamp = "2024-01-04T14:30:00.119919872Z";
DateTime dt = DateTime.Parse(timestamp);
Console.WriteLine(dt.ToString("O")); // outputs: 2024-01-04T09:30:00.1199199-05:00

Таким образом, доли секунды в метке времени округляются до 1199199 — ближайших 100 наносекунд. Судя по всему, 100 наносекунд — это точность структур DateTime.

Чтобы избежать потери точности, я написал свой собственный метод синтаксического анализа, но он очень уродлив:

public static long ToUnixNanoseconds(string str)
{
    string dateTimeStr = str[..19];
    DateTime utcDateTime = DateTime.Parse(dateTimeStr + "Z");
    long unixTimeSeconds = (new DateTimeOffset(utcDateTime)).ToUnixTimeSeconds();
    string fractionalSecondsStr = str[19..(str.Length - 1)];
    decimal fractionalSeconds = decimal.Parse(fractionalSecondsStr);
    long unixNano = (long)((unixTimeSeconds + fractionalSeconds) * 1000000000);
    return unixNano;
}

Какие существуют лучшие способы преобразования временной метки RFC-3339 в временную метку Unix с точностью до наносекунды в C#?

Это верно. Значения C# DateTime и DateTimeOffset измеряются в ticks с «12:00 полуночи, 1 января 0001 года нашей эры (CE)», где интервал составляет 100 наносекунд. (Learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libra‌​ries/…)

Jeremy Lakeman 25.03.2024 06:00

Итак, нет ли поддержки времени анализа с полной наносекундной точностью? :(

Treker 25.03.2024 06:14

Проверьте github.com/nodatime/nodatime

shingo 25.03.2024 06:28

Я думаю, что это реализация, хотя сомневаюсь, что вы захотите использовать ее повторно. github.com/dotnet/runtime/blob/…

Jeremy Lakeman 25.03.2024 06:30

зачем вам нужна точность меньше 100 наносекунд. ?

Mitch Wheat 25.03.2024 12:28

@MitchWheat В моем случае я анализирую объекты данных финансового рынка с наносекундными временными метками Unix. Округление на два порядка точности будет означать, что порядок, в котором происходят события, не сохраняется. В мире финансов все происходит очень быстро.

Treker 25.03.2024 17:05

@Treker: Я бы сказал, что если вы полагаетесь на порядок с точностью менее 100 наносекунд, то ваш дизайн может быть сломан. Например: эти события происходят из нескольких систем? У них у всех есть атомные часы?

Mitch Wheat 26.03.2024 00:11

Событиями являются сделки и котировки, которые происходят на различных фондовых биржах и обрабатываются и консолидируются организациями, называемыми SIP (обработчиками информации о ценных бумагах). В США в основном существует два SIP — CTA для акций, котирующихся на NYSE, и UTP для акций, котирующихся на NASDAQ.

Treker 27.03.2024 03:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш метод синтаксического анализа кажется приемлемым, если вы всегда ожидаете одного и того же формата ввода и не хотите включать полную библиотеку только для этого одного варианта использования (хотя Noda Time действительно хорош.)

Можно было бы немного подправить. Вот мой подход:

public static long ToUnixNanoseconds(ReadOnlySpan<char> timestamp)
{
    var seconds = DateTimeOffset.Parse(timestamp[0..19], CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToUnixTimeSeconds();
    var fractionalSeconds = decimal.Parse(timestamp[19..^1], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture);
    return (long)((seconds + fractionalSeconds) * 1000000000);
}

Другие вопросы по теме