创建一个boost ::从64位整数秒计数了posix_time ::的ptime对象 [英] Creating a boost::posix_time::ptime object from a 64 bit integer second count

查看:990
本文介绍了创建一个boost ::从64位整数秒计数了posix_time ::的ptime对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个32位的Linux系统中,我有记录被时间戳与UINT32从1901年1月1日零点00分零零秒划时代第二偏移数据。

计算时间戳是确定对我来说,我可以使用64位蜱()计数器和 TICKS_PER_SECOND( )函数生成的纪元以来的秒数如下(我只需要第二级分辨率)

  const的分组时间ptime_origin(time_from_string(1901年1月1日00:00:00));
TIME_DURATION my_utc = microsec_clock :: universal_time() - ptime_origin;
提高:: tick_per_sec的int64_t = my_utc.ticks_per_second();
提高:: tick_count的int64_t = my_utc.ticks();
提高:: sec_since_epoch的int64_t = tick_count / tick_per_sec;

这对我的作品,因为我知道,作为一个无符号整数,秒数将不会超过最大UINT32值(也很多年没有这样)。

我的问题是,我的应用程序能够接收包含我必须设置与使用的ioctl 电话硬件和系统时钟UINT32值Modbus信息 RTC_SET_TIME 。这是UINT32再次以秒为单位,因为我的纪元1901年1月1日00:00:00抵消。

我现在的问题是,我没有办法为创建使用64位整数的分组时间对象 - 在 TIME_DURATION 对象是私处,我只能使用这对我32位系统仅仅是一个4字节有符号整数不够大,不能存储秒从我的时代所抵消。

我在时代的价值没有控制权,所以我真的很为难,我怎么可以从我的创建要求的boost ::了posix_time ::分组时间对象数据我有。
我可以通过计算很难分秒必争,以特定的时间间隔,并使用一个额外的时代做一个桥梁,让这个可能获得一个肮脏的解决方案,但我不知道是否有东西在升压 code,让我完全使用升压日期时间库来解决问题。
我已阅读所有的文档,我能找到,但我看不到任何明显的方式做到这一点。

编辑:我发现这个相关的问题转换来的int64_t TIME_DURATION 但接受的答案有没有为我工作的时代


解决方案

您可以在允许的最大增量适用TIME_DURATION秒(即的std :: numeric_limits<长> :: MAX())因为 total_seconds 字段限制在(签字)。

注意:我的措辞为 int32_t 下面,这样,如果在64位平台上编译它仍然会正常工作。

下面是一个小的演示:

 的#include助推/ date_time.hpp
#包括LT&;&iostream的GT;使用空间boost ::格利高;
使用空间boost ::了posix_time;诠释的main()
{
    uint64_t中偏移量= 113ul * 365ul * 24ul * 60ul * 60ul; //113年给予或采取一些闰秒/天等?    静态常量的ptime time_t_epoch(DATE(1901,1,1));
    静态常量uint32_t的max_long =的std :: numeric_limits< int32_t> :: MAX();
    性病::法院LT&;< 划时代<< time_t_epoch<< \\ n;    分组时间ACCUM = time_t_epoch;
    而(偏移> max_long)
    {
        ACCUM + =秒(max_long);
        偏移 - = max_long;
        性病::法院LT&;< 累计:<< ACCUM<< \\ n;
    }    ACCUM + =秒(偏移);
    性病::法院LT&;< 最后的:<< ACCUM<< \\ n;
}

打印:

 时代:1901-JAN-01 00:00:00
积累:1969-JAN-19 3时14分07秒
决赛:2013 - 12月04日00:00:00

看它的 住在Coliru

I have a 32 bit Linux system in which I have to record data that is timestamped with a UINT32 second offset from an epoch of 1901-01-01 00:00:00.

Calculating the timestamp is ok for me as I can use the 64 bit ticks() counter and ticks_per_second() functions to generate the seconds since epoch as follows (I only require second level resolution)

const ptime ptime_origin(time_from_string("1901-01-01 00:00:00"));
time_duration my_utc = microsec_clock::universal_time() - ptime_origin;
boost::int64_t tick_per_sec = my_utc.ticks_per_second();
boost::int64_t tick_count = my_utc.ticks();
boost::int64_t sec_since_epoch = tick_count/tick_per_sec;

This works for me since I know that as an unsigned integer, the seconds count will not exceed the maximum UINT32 value (well not for many years anyway).

The problem I have is that my application can receive a modbus message containing a UINT32 value for which I have to set the hardware and system clock with an ioctl call using RTC_SET_TIME. This UINT32 is again the offset in seconds since my epoch 1901-01-01 00:00:00.

My problem now is that I have no way to create a ptime object using 64 bit integers - the ticks part of the time_duration objects is private and I am restricted to using long which on my 32 bit system is just a 4-byte signed integer not large enough to store the seconds offset from my epoch.

I have no control over the value of the epoch and so I am really stumped as to how I can create my required boost::posix_time::ptime object from the data I have. I can probably obtain a dirty solution by calculating hard second counts to particular time intervals and using an additional epoch to make a bridge to allow this but I was wondering if there is something in the boost code that will allow me to solve the problem entirely using the boost datetime library. I have read all the documentation I can find but I cannot see any obvious way to do this.

EDIT: I found this related question Convert int64_t to time_duration but the accepted answer there does NOT work for my epoch

解决方案

You could apply time_durations in the maximum allowable increments (which is std::numeric_limits<long>::max()) since the total_seconds field is limited to long (signed).

Note: I worded it as int32_t below so that it will still work correctly if compiled on a 64-bit platform.

Here's a small demonstration:

#include "boost/date_time.hpp"
#include <iostream>

using namespace boost::gregorian; 
using namespace boost::posix_time;

int main()
{
    uint64_t offset = 113ul*365ul*24ul*60ul*60ul; // 113 years give or take some leap seconds/days etc.?

    static const ptime time_t_epoch(date(1901,1,1)); 
    static const uint32_t max_long = std::numeric_limits<int32_t>::max();
    std::cout << "epoch: " << time_t_epoch << "\n";

    ptime accum = time_t_epoch;
    while (offset > max_long)
    {
        accum  += seconds(max_long);
        offset -= max_long;
        std::cout << "accumulating: " << accum << "\n";
    }

    accum += seconds(offset);
    std::cout << "final: " << accum << "\n";
}

Prints:

epoch: 1901-Jan-01 00:00:00
accumulating: 1969-Jan-19 03:14:07
final: 2013-Dec-04 00:00:00

See it Live on Coliru

这篇关于创建一个boost ::从64位整数秒计数了posix_time ::的ptime对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆