日期操作,以毫秒为单位 [英] Date operations with milliseconds
问题描述
我需要一种管理日期的方法,包括毫秒:获取当前日期和时间,为其添加给定的毫秒数。第一部分完成。
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 thetv_usec
s overflows (>= 1E6), incrementtv_sec
and subtract 1E6 fromtv_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 thetimeval
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 fromFILETIME
.
[/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屋!