Отметка времени VMS для POSIX time_t — ошибка Boost.DateTime?

Как я могу написать функцию C ++, которая принимает long long значение, представляющее метку времени VMS, и возвращает соответствующий time_t значение, при условии, что преобразование дает действительный time_t? (Я буду анализировать двоичные данные, отправленные по сети на стандартный сервер CentOS, если это будет иметь какое-либо значение.)

Я заглянул в документ под названием «Почему среда 17 ноября 1858 года является базовым временем для VAX / VMS» но я не думаю, что смогу написать правильную реализацию без тестирования с фактическими данными, которых у меня сейчас нет, к сожалению.

Если я не ошибаюсь, это должна быть простая арифметика в таком виде:

time_t vmsTimeToTimeT(long long v) {
return v/10'000'000 - OFFSET;
}

Может ли кто-нибудь сказать мне, какую ценность вкладывать в OFFSET ?

Вещи, которые меня беспокоят:

  • Я не хочу быть укушенным моим местным часовым поясом
  • Я не хочу быть укушенным 0,5 (днем против полуночи) в определении модифицированной юлианской даты (хотя это должно помочь мне здесь; модифицированная юлианская эпоха и эпоха Unix должны отличаться в 24 раза благодаря определение)

Я попытался вычислить его самостоятельно с помощью Boost.DateTime, только чтобы получить таинственное отрицательное значение …

int main() {
boost::posix_time::ptime x(
boost::gregorian::date(1858, boost::gregorian::Nov, 17),
boost::posix_time::time_duration(0, 0, 0) );
boost::posix_time::ptime y(
boost::gregorian::date(1970, boost::gregorian::Jan,  1),
boost::posix_time::time_duration(0, 0, 0) );
std::cout << (y - x).total_seconds() << std::endl;
std::cout << (y > x ? "y is after x" : "y is before x") << std::endl;
}

-788250496
у после х

я использовал Boost 1.60 для этого:

Текущая реализация поддерживает даты в диапазоне от 1400-Jan-01 до 9999-Dec-31.

Обновить

Дерьмо, sizeof(total_seconds()) было 4, несмотря о чем говорится в документе

Итак, я получил 3506716800 от

auto diff = y - x;
std::cout << diff.ticks() / diff.ticks_per_second() << std::endl;

что не выглядит слишком неправильно, но … кто может заверить, что это действительно правильно?

0

Решение

Вау, вы, ребята, заставляете все это казаться таким сложным с библиотеками и все такое.
Итак, вы прочитали 17 ноября 1858 года и обнаружили, что VMS хранит время как 100 нс «стуков» с этой даты. Правильно?

Время Unix — секунды (или микросекунды) с 1 января 1970 года. Правильно?

Таким образом, все, что вам нужно сделать, это вычесть значение смещения времени OpenVMS для 1 января 1970 года из отчетного времени деления времени OpenVMS на 10 000 000 (секунд) или 10 (микросекунд).
Вам нужно найти это значение только один раз, используя тривиальную программу OpenVMS.
Ниже я даже не использовал выделенную программу, просто использовал интерактивный отладчик OpenVMS, запускающий случайную исполняемую программу:

 $ run tmp/debug
DBG> set rad hex
DBG> dep/date 10000 = "01-JAN-1970 00:00:00"  ! Local time
DBG> examin/quad 10000
TMP\main:       007C95674C3DA5C0
DBG> examin/quad/dec  10000
TMP\main:       35067168005400000

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

В простейшей форме вы предварительно делите входящее время OpenVMS на 10 000 000 и вычитаете 3506716800 (десятичное число), чтобы получить секунды эпохи.
Будьте уверены, чтобы сохранить математику, в том числе вычитать к длинным-длинным целым

НТН,
Хайн.

1

Другие решения

Согласно этому:
https://www.timeanddate.com/date/durationresult.html?d1=17&m1 = 11&y1 = 1858&d2 = 1&м2 = январь&у2 = 1970

Вы хотите, чтобы 40587 дней, время 86400 секунд, составляло 3506716800 в качестве смещения в ваших расчетах.

1

Используя это бесплатная библиотека с открытым исходным кодом который расширяется <chrono> К календарным вычислениям я могу подтвердить вашу цифру смещения в секундах:

#include "chrono_io.h"#include "date.h"#include <iostream>

int
main()
{
using namespace date;
using namespace std::chrono;
using namespace std;
seconds offset = sys_days{jan/1/1970} - sys_days{nov/17/1858};
cout << offset << '\n';
}

Выход:

3506716800s
1
По вопросам рекламы [email protected]