Nano Hash - криптовалюты, майнинг, программирование

Время UTC с Java на С++ - поиск смещения времени UTC Zone в секундах

Мне нужно сериализовать экземпляр даты и времени UTC из java в С++, используя минимальную длину чистого ByteBuffer беззнаковых символов. Мне нужна точка времени, чтобы иметь возможность поддерживать минимальную точность в наносекундах.

Со стороны java я просмотрел классы ZonedDateTime и OffsetDateTime и увидел, какой примитив они используют для хранения времени, и все вместе это равно 17 байтам, что довольно много.

Обратите внимание, что здесь я не передаю саму зону, так как не нашел способа сопоставить эти строки зоны из IANA с целыми числами. Таким образом, я думаю, смещения зоны будет достаточно. Поскольку купленные стороны должны будут преобразовать свою точку времени в определенное смещение перед отправкой на сервер, скажем, это будет UTC 0. Я ищу решение, которое ищет местное время, то есть без участия NTP-серверов!

сторона java выглядит так:

        // 4 byte
        Integer year = offsetDateTime.getYear();
        // 1 byte           
        Integer month = offsetDateTime.getMonthValue();
        // 1 byte
        Integer day = offsetDateTime.getDayOfMonth();
        // 1 byte
        Integer hour = offsetDateTime.getHour();
        // 1 byte
        Integer minutes = offsetDateTime.getMinute();
        // 1 byte
        Integer seconds = offsetDateTime.getSecond();
        // 4 byte
        Integer nanoSeconds = offsetDateTime.getNano();
        // 4 byte
        Integer utcZoneTimeTotalSecondsOffset = offsetDateTime.getOffset().getTotalSeconds(); 

на стороне С++ мне нужно сделать то же самое, а также иметь возможность построить момент времени из всех этих целых чисел выше. Я нашел, как получить указанную выше информацию, кроме utcOffset, т.е. последнего целого числа.

я хотел бы использовать chrono для использования этого буфера и создания из него момента времени. однако я не могу найти способ получить смещение времени в С++. Как мне получить смещение времени с помощью хроно, а затем построить момент времени из приведенной выше информации?

auto now = std::chrono::system_clock::now();
time_t itt = std::chrono::system_clock::to_time_t(now);

tm utc_tm = *gmtime(&itt);

std::cout << utc_tm.tm_year + 1900 << '-';
std::cout << utc_tm.tm_mon + 1 << '-';
std::cout << utc_tm.tm_mday << ' ';
std::cout << utc_tm.tm_hour << ':';
std::cout << utc_tm.tm_min << ':';
std::cout << utc_tm.tm_sec << '\n';

? wher is the time zoneOffset here ?

если я использую

 utc_tm.tm_gmtoff 

это дает мне неверную информацию. по крайней мере в моем случае. Итак, я считаю, что gmtoff - это не путь, но если gmtoff не путь, то что?

11.09.2019

  • Похоже, в С++ у нас нет часового пояса. До тех пор, пока используемый часовой пояс С++ 20 не зависит от реализации, после этого он должен быть UTC. 11.09.2019
  • В С++ является ли конечный продукт точкой времени UTC или точкой местного времени? 11.09.2019
  • @HowardHinnant большое спасибо за ваш повтор, я посмотрел 3 ваших видео на c++ con о библиотеке TZ. Поскольку вы человек, который занимается библиотекой TZ, не могли бы вы посоветовать, какую оболочку примитивов мы используем во время сериализации сейчас, чтобы перевести время из java в c++, я имею в виду, например, что секунды в cpp длинны, как у вас есть сказал это сам, но в моем примере я использую 1 байт для секунд и 4 байта для наносекунд, каков будет минимальный размер, необходимый для передачи точки времени UTC в С++ в С++ 20? 11.09.2019
  • @sklott спасибо за отзыв, это большая проблема, когда вы хотите сравнить время в разных часовых поясах. Я ищу код, который должен работать и в веб-сборке. Я не ожидал этого. 11.09.2019
  • Можно выразить точку времени UTC с точностью до наносекунд в C++, используя в общей сложности 8 байтов, если точка времени находится примерно в диапазоне от 1678 до 2262 лет. Если нужны часовые пояса или смещения UTC, для этого потребуется больше места для хранения. 11.09.2019
  • @HowardHinnant спасибо за отзыв, есть ли где-нибудь пример с минимальным пространством, необходимым для смещения часовых поясов и UTC? Я просматривал github.com/HowardHinnant/date/wiki/ но там вы всегда указываете часовой пояс, например auto zt = make_zoned(tz_name, tp); то есть я пытаюсь понять, сколько байтов требуется для этого в С++ 20 и как инициализировать экземпляр времени хроно из всех отдельных частей. Знаете ли вы, есть ли какой-либо пример для этого? 11.09.2019
  • Что такое «восприятие»? 11.09.2019
  • точность, извините, английский не мой родной язык 11.09.2019
  • Какова точно ваша цель? Сообщить момент в UTC с разрешением в наносекунды в минимальном количестве октетов для чтения на С++? Почему наносекунды, вы понимаете, что обычные компьютерные часы не точны до наносекунд? Если вы хотите UTC, почему вы продолжаете говорить о смещениях и зонах? Действительно ли критично минимальное количество октетов? Рекомендуемый способ обмена значениями даты и времени — через текст в стандартном формате ISO 8601. 11.09.2019
  • Зачем иметь дело со смещением? Просто создайте OffsetDateTime или ZonedDateTime с UTC ZoneId. 11.09.2019
  • @BasilBourque, причина, по которой я говорю о смещениях и зонах, заключается в том, что нужно иметь возможность сравнивать время между клиентами и сервером, и поскольку они могут быть в разных часовых поясах, при сравнении моментов времени и регистрации их на сервере вам нужно знать точную зону и смещение от клиента, чтобы потом иметь возможность сравнивать логи с сервером, принимая во внимание, что серверов по всему миру несколько. И да, я понимаю, что обычные компьютерные часы неточны и не поддерживают наносекунды. 11.09.2019
  • Если все клиенты/серверы всегда общаются друг с другом в формате UTC, то становится очень легко сравнивать метки времени. Если, конечно, по какой-то причине вам не нужно знать, например, была ли отметка времени открыта/закрыта по местному времени клиента/сервера. 11.09.2019

Ответы:


1

Неполный ответ, но вот один из способов сериализации точки локального времени C++ с использованием бесплатного времени Говарда Хиннанта с открытым исходным кодом. библиотека зон.

#include "date/tz.h"
#include <iostream>
#include <sstream>

std::string
to_string(date::zoned_time<std::chrono::nanoseconds> t)
{
    using namespace std;
    using namespace date;
    ostringstream out;
    out << t.get_sys_time().time_since_epoch().count()
        << ' ' << t.get_time_zone()->name();
    return out.str();
}

date::zoned_time<std::chrono::nanoseconds>
from_string(const std::string& s)
{
    using namespace std;
    using namespace std::chrono;
    using namespace date;
    istringstream in{s};
    long long ns;
    std::string tz_name;
    in >> ns >> tz_name;
    return {tz_name, sys_time<nanoseconds>{nanoseconds{ns}}};
}

int
main()
{
    using namespace std;
    using namespace std::chrono;
    using namespace date;
    zoned_time<nanoseconds> zt{current_zone(), system_clock::now()};
    cout << zt << '\n';
    auto s = to_string(zt);
    cout << s << '\n';
    zt = from_string(s);
    cout << zt << '\n';
}

Я использую std::string для представления сериализации, которую можно отправить по сети.

Этот пример начинается в main с создания точки местного времени с точностью до наносекунды, хранящейся в date::zoned_time<nanoseconds>, с использованием текущего локального часового пояса компьютера и текущего времени UTC. main сначала просто печатает эту отметку времени, которая для меня просто выводится:

2019-09-11 12:37:04.846272000 EDT

это моя текущая местная дата/время и аббревиатура часового пояса.

Затем программа преобразует это в строку с небольшим (но не обязательно минимальным) количеством символов ASCII, чтобы полностью описать местный момент времени. Я выбрал формат:

<Number of nanoseconds since epoch> <IANA time zone name>

В этом примере эта строка:

1568219824846272000 America/New_York

Этот string формируется в to_string, который просто выводит «время с начала эпохи» системного времени zoned_time. Затем добавляет пробел и выводит название часового пояса.

from_string отменяет эту операцию, считывая число наносекунд, а затем считывая имя часового пояса. Затем он формирует zoned_time<nanoseconds>, соединяя имя часового пояса и формируя sys_time<nanoseconds> с целым числом, которое было проанализировано.

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

2019-09-11 12:37:04.846272000 EDT

Чтобы получить преобразование без потерь, включающее местное время, действительно необходимо передать имя часового пояса IANA, а не только текущее смещение UTC. Только со смещением UTC можно восстановить точную точку времени UTC. Но нельзя выполнять какие-либо арифметические операции с локальным временем или сравнивать его с другими точками местного времени, потому что нельзя знать правила изменения смещения UTC. Только с полным именем часового пояса IANA можно передавать информацию об этих правилах.

11.09.2019
  • Говард, большое спасибо за ответ и пару дополнительных моментов. Знаете ли вы, есть ли способ сопоставить строку зоны America/New_York с целым числом? Я пытаюсь избежать строкового представления для сериализации и по этой причине использую вместо этого целые числа фиксированной длины. Поскольку я хотел бы иметь один и тот же DTO для java и C++ в качестве структуры для обмена информацией. Еще один вопрос: знаете ли вы, тестировался ли date/tz.h с Webassembly ранее? 11.09.2019
  • Официального имени‹-›целочисленное отображение не существует. Однако вы можете создать свой собственный. В настоящее время с часовыми поясами связано 593 имени. Некоторые из этих имен на самом деле относятся к одной и той же зоне, но большинство операционных систем рассматривают их как отдельные копии зон. 11.09.2019
  • Я не знаю об использовании tz.h с Webassembly. 11.09.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..