0

假设转换产生一个有效的值,我如何编写一个 C++ 函数,该函数接受一个long long表示 VMS 时间戳的值并返回相应的值?(我将在商用 CentOS 服务器上解析通过网络发送的二进制数据,如果这有什么不同的话。)time_ttime_t

我查看了一篇名为“为什么 1858 年 11 月 17 日星期三是 VAX/VMS 的基准时间”的文档,但我认为如果不使用我没有的实际数据进行测试,我无法编写正确的实现不幸的是,现在手。

如果我没记错的话,应该是这种形式的简单算术:

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

有人能告诉我要投入什么价值OFFSET吗?

我关心的事情:

  • 我不想被我当地的时区咬伤
  • 我不想被修改后的 Julian 日期定义中的 0.5(下午与午夜)所困扰(尽管它在这里应该对我有所帮助;修改后的 Julian 纪元和 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
y 在 x 之后

我为此使用了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;

这看起来不太错,但是......谁能保证这真的是正确的?

4

3 回答 3

2

哇,你们让图书馆和所有的一切看起来都如此困难。因此,您在 1858 年 11 月 17 日阅读并发现 VMS 将时间存储为自该日期以来的 100nS 'clunks'。对?

自 1970 年 1 月 1 日起,Unix 时间为秒(或微秒)。对?

因此,您需要做的就是从报告的 OpenVMS 时间广告除以 10,000,000(秒)或 10(微秒)减去 1970 年 1 月 1 日的 OpenVMS 时间值“偏移量”。您只需要使用一个简单的 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

因此,您可以在 HEX 和 DECIMAL 中使用您认为合适的偏移量。

在最简单的形式中,您将传入的 OpenVMS 时间预先除以 10,000,000 并减去 3506716800(十进制)以获得 Epoch 秒。一定要保留数学,包括对 long-long int 的减法

嗯,海因。

于 2017-03-18T17:05:15.357 回答
1

据此: https ://www.timeanddate.com/date/durationresult.html?d1=17&m1=11&y1=1858&d2=1&m2=jan&y2=1970

您需要 40587 天乘以 86400 秒,将 3506716800 作为计算中的偏移量。

于 2017-03-17T23:29:03.307 回答
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
于 2017-03-18T15:54:22.537 回答