日期操作,以毫秒为单位 [英] Date operations with milliseconds

查看:94
本文介绍了日期操作,以毫秒为单位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种管理日期的方法,包括毫秒:获取当前日期和时间,为其添加给定的毫秒数。第一部分完成。

C ++版本高达C ++ 14。

谢谢。



更新:一些背景。我有一个开头时间戳的文件和记录数,每个记录包含从这个初始时间开始的毫秒数:



 2108 6 21 15 14 56 588 
1000条消息
5577消息
10000条消息
...



所以,我需要用全时打印每条消息。由于我已经有time_point到时间戳转换,我实际上需要一个相反的转换,这看起来有点棘手。



我尝试了什么:



  #include   <   chrono  >  
#include < ctime >

struct timestamp
{
int year; // 0-based
int 月; // [1-12]
int 天; // [1-31]
int 小时; // [0-23]
int 分钟; // [0-59]
int 秒; // [0-59]
int 毫秒; // [0-999]
};

// 完成
timestamp get_local_date()
{
时间戳t;

auto now = std :: chrono :: system_clock :: now();
auto seconds = std :: chrono :: time_point_cast< std :: chrono :: seconds>(now);
auto fraction = now - seconds;
auto milliseconds = std :: chrono :: duration_cast< std :: chrono :: milliseconds>(fraction);

time_t tnow = std :: chrono :: system_clock :: to_time_t(now);
tm * ptm = localtime(& tnow);

t.year = ptm-> tm_year + 1990 ;
t.month = ptm-> tm_mon + 1 ;
t.day = ptm-> tm_mday;
t.hour = ptm-> tm_hour;
t.minute = ptm-> tm_min;
t.sec = ptm-> tm_sec;
t.ms = static_cast< int>(milliseconds.count());

return t;
}

// ??
时间戳add( const timestamp& t, int ms)
{
// 通过将给定的ms计数添加到t来计算新的标准化时间戳
}

解决方案

为简化计算,我会使用一个不包含单个字段但只包含一个或两个值的结构。



如果您只想支持Windows,可以使用 FILETIME结构(Windows) [ ^ ]。



或者,对于一般操作系统支持,请使用 timeval结构(Windows) [ ^ ]。这里只添加成员,当 tv_usec s的添加溢出(> = 1E6)时,增加 tv_sec 并且从 tv_usec 中减去1E6。



对于这两种结构,都有转换功能到其他时间格式,这样你就可以得到访问各个日期和时间字段。 timeval 结构的优点是,当转换后的格式不支持时,您可以直接访问第二个字段的分数。





如果您仍想使用您的结构,请将转换函数写入上述结构之一并使用它们执行计算。



另请注意,您的结构与 SYSTEMTIME结构(Windows) [ ^ ]。如果你使用它,那么现有的转换函数可以来自 FILETIME

[/ EDIT]





从头开始的未经测试的例子:

 timeval add( const  timeval& tv, int  ms)
{
timeval tv_res = {ms / 1000 1000 *(ms% 1000 )};
tv_res.tv_sec + = tv.tv_sec;
tv_res.tv_usec + = tv.tv_usec;
if (tv_res.tv_usec> = 1000000
{
tv_res.tv_sec ++;
tv_res.tv_usec - = 1000000 ;
}
return tv_res;
}

时间戳添加( const 时间戳& t, int ms)
{
return TimeValToTimeStamp(add(TimeStampToTimeVal(t),ms));
}

现在你只需要转换函数(TimeValToTimeStamp()作为练习):

 timeval TimeStampToTimeVal(< span class =code-keyword> const  timestamp& t)
{
struct tm tmt = { 0 };
tmt.tm_year = t.year;
tmt.tm_mon = t.month;
tmt.tm_mday = t.day;
tmt.tm_hour = t.hour;
tmt.tm_min = t.minute;
tmt.tm_sec = t.sec;
timeval tv;
tv.sec =( long )mktime(& tmt);
tv.usec = t.ms * 1000 ;
return tv;
}

[/ EDIT2]


比你需要高分辨率时间功能。注意细节作为分辨率和数据类型及其大小。


我会

  • 扔掉 get_local_date function。
  • 制作 time_point_to_timestamp 函数。
  • 制作 timestamp_to_timepoint function。
  • 使用上述函数和 time_point :: operator + = 实现add。

I need a way to manage a date, including milliseconds: get current date and time, add given number of milliseconds to it. The first part is completed.
C++ version up to C++14.
Thanks.

Update: some background. I have a file with timestamp in the beginning, and number of records, each one contains number of milliseconds from this initial time:

2108 6 21 15 14 56 588
1000 message
5577 message
10000 message
...


So, I need to print every message with its full time. Since I already have time_point to timestamp conversion, I actually need an opposite conversion, which looks a bit tricky.

What I have tried:

#include <chrono>
#include <ctime>

struct timestamp
{
    int year;    // 0-based 
    int month;   // [1-12]
    int day;     // [1-31]
    int hour;    // [0-23]
    int minute;  // [0-59]
    int sec;     // [0-59]
    int ms;      // [0-999]
};

// Done
timestamp get_local_date()
{
    timestamp t;

    auto now = std::chrono::system_clock::now();
    auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
    auto fraction = now - seconds;
    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(fraction);

    time_t tnow = std::chrono::system_clock::to_time_t(now);
    tm* ptm = localtime(&tnow);

    t.year = ptm->tm_year + 1990;
    t.month = ptm->tm_mon + 1;
    t.day = ptm->tm_mday;
    t.hour = ptm->tm_hour;
    t.minute = ptm->tm_min;
    t.sec = ptm->tm_sec;
    t.ms = static_cast<int>(milliseconds.count());

    return t;
}

// ??
timestamp add(const timestamp& t, int ms)
{
    // compute new normalized timestamp by adding given ms count to t
}

解决方案

To simplify calculations I would use a structure that does not contain the individual fields but a single or two values.

If you only want to support Windows you can use the FILETIME structure (Windows)[^].

Alternatively and for general OS support use the timeval structure (Windows)[^]. Here just add the members and when the addtion of the tv_usecs overflows (>= 1E6), increment tv_sec and subtract 1E6 from tv_usec.

For both structures there are conversion functions to other time formats so that you can get access to the individual date and time fields. The advantage of the timeval structure is that you have direct access to the fraction of second field when the converted format does not support such.

[EDIT]
If you still want to use your structure, write conversion functions to and from one of the above mentioned structures and use those to perform the caluclation.

Note also that your structure is very similar to the SYSTEMTIME structure (Windows)[^]. If you use that, there are existing conversion functions to and from FILETIME.
[/EDIT]

[EDIT2]
Untested examples from scratch:

timeval add(const timeval& tv, int ms)
{
    timeval tv_res = { ms / 1000, 1000 * (ms % 1000)};
    tv_res.tv_sec += tv.tv_sec;
    tv_res.tv_usec += tv.tv_usec;
    if (tv_res.tv_usec >= 1000000)
    {
        tv_res.tv_sec++;
        tv_res.tv_usec -= 1000000;
    }
    return tv_res;
}

timestamp add(const timestamp& t, int ms)
{
    return TimeValToTimeStamp(add(TimeStampToTimeVal(t), ms));
}

All you need now are the conversion functions (TimeValToTimeStamp() left as an exercise):

timeval TimeStampToTimeVal(const timestamp& t)
{
    struct tm tmt = { 0 };
    tmt.tm_year = t.year;
    tmt.tm_mon = t.month;
    tmt.tm_mday = t.day;
    tmt.tm_hour = t.hour;
    tmt.tm_min = t.minute;
    tmt.tm_sec = t.sec;
    timeval tv;
    tv.sec = (long)mktime(&tmt);
    tv.usec = t.ms * 1000;
    return tv;
}

[/EDIT2]


Than you need the High resolution time functions for Windows. Pay attention to the details as resolution and data type and its size.


I would
  • Throw away the get_local_date function.
  • Make a time_point_to_timestamp function.
  • Make a timestamp_to_timepoint function.
  • Implement add using the above functions and the time_point::operator+=.


这篇关于日期操作,以毫秒为单位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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