在 C++ 中将日期转换为 unix 时间戳

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21679056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:46:25  来源:igfitidea点击:

Convert date to unix time stamp in c++

c++unixtimestamp

提问by user2366975

As some websites that convert those unix time stamps say, the stamp of

正如一些转换这些 un​​ix 时间戳的网站所说,

2013/05/07 05:01:00 (yyyy/mm/dd, hh:mm:ss) is 1367902860.

The way I do it in C++, the stamp differs from the date. Here is the code:

我在 C++ 中的做法是,戳记与日期不同。这是代码:

time_t rawtime;
struct tm * timeinfo;

int year=2013, month=5, day=7, hour = 5, min = 1, sec = 0;

/* get current timeinfo: */
time ( &rawtime ); //or: rawtime = time(0);
/* convert to struct: */
timeinfo = localtime ( &rawtime ); 

/* now modify the timeinfo to the given date: */
timeinfo->tm_year   = year - 1900;
timeinfo->tm_mon    = month - 1;    //months since January - [0,11]
timeinfo->tm_mday   = day;          //day of the month - [1,31] 
timeinfo->tm_hour   = hour;         //hours since midnight - [0,23]
timeinfo->tm_min    = min;          //minutes after the hour - [0,59]
timeinfo->tm_sec    = sec;          //seconds after the minute - [0,59]

/* call mktime: create unix time stamp from timeinfo struct */
date = mktime ( timeinfo );

printf ("Until the given date, since 1970/01/01 %i seconds have passed.\n", date);

The resulting time stamp is

结果时间戳是

1367899260, but not 1367902860.

What is the problem here? Even if I change to hour-1 or hour+1, it does not match. EDIT: Well yes if i add 1 to hour, it works. previously also added 1 to minutes.

这里有什么问题?即使我更改为hour-1 或hour+1,它也不匹配。编辑:嗯,是的,如果我将 1 添加到小时,它会起作用。以前还加1到分钟。

回答by José María

You must use timegm() instead of mktime(), and that's all. Because mktime is for localtime and timegm for UTC/GMT time.

您必须使用 timegm() 而不是 mktime(),仅此而已。因为 mktime 用于本地时间,而 timegm 用于 UTC/GMT 时间。

Converting Between Local Times and GMT/UTC in C/C++

在 C/C++ 中在本地时间和 GMT/UTC 之间转换

回答by Phil Rosenberg

Do you have daylight saving time when you are from? The tm::tm_isdst parameter is a flag for daylight saving time. This will get filled by the localtime call based on where you are and the time of year and you do not reset it. So even if both you and the web page are using the same time, if you have the daylight saving flag set and the web page doesn't then you will end up different by 1 hour.

你从哪里来的时候有夏令时吗?tm::tm_isdst 参数是夏令时的标志。这将根据您所在的位置和一年中的时间由本地时间调用填充,并且您不会重置它。因此,即使您和网页都使用相同的时间,如果您设置了夏令时标志而网页没有设置,那么您最终会相差 1 小时。

Note you don't really need the localtime call. You can just fill in all the parts manually because tm::tm_wday and tm::tm_yday are ignored by mktime. Check out http://www.cplusplus.com/reference/ctime/tm/and http://www.cplusplus.com/reference/ctime/mktime/

请注意,您实际上并不需要 localtime 电话。您可以手动填写所有部分,因为 tm::tm_wday 和 tm::tm_yday 被 mktime 忽略。查看http://www.cplusplus.com/reference/ctime/tm/http://www.cplusplus.com/reference/ctime/mktime/

回答by neverhoodboy

mktime()converts localcalendar time to a time since epoch as a time_tobject, so your result will be different from the website's if you are in a different time-zone. The website takes 2013/05/07 05:01:00as a UTC time. The same code on my machine has a result of 1367874060, which is 8 hour away from the website's value. I'm in UTC+8:00 time-zone, so mktime()on my machine takes the input 2013/05/07 05:01:00as a UTC+8:00 time, thus causing the difference.

mktime()本地日历时间转换为自纪元以来的时间作为time_t对象,因此如果您处于不同的时区,您的结果将与网站的不同。该网站采用2013/05/07 05:01:00UTC 时间。我机器上的相同代码的结果为1367874060,与网站的值相差 8 小时。我在 UTC+8:00 时区,所以mktime()在我的机器上将输入2013/05/07 05:01:00作为 UTC+8:00 时间,从而导致差异。

PS: localtime()returns a pointer to a static internal struct tmobject. The structure may be shared between gmtime(), localtime(), and ctime(), and may be overwritten on each invocation. So it's a better practice to have your own local copy of a struct tmobject.

PS:localtime()返回一个指向静态内部struct tm对象的指针。该结构可以在gmtime()localtime()和之间共享ctime(),并且可以在每次调用时被覆盖。因此,拥有自己的struct tm对象本地副本是更好的做法。

回答by cup

Don't use a pointer to localtime. Save the actual value

不要使用指向本地时间的指针。保存实际值

struct tm timeinfo;
...
timeinfo = *localtime(&rawtime);
...
date = mktime(&timeinfo);

You don't know what else may be using the pointer that localtime is returning. mktime might possibly be using it.

您不知道还有什么可能使用 localtime 返回的指针。mktime 可能正在使用它。

回答by Mike Seymour

It looks like the website is assuming the time is in the UTC timezone, and your computer is set to some other timezone.

看起来该网站假设时间在 UTC 时区,并且您的计算机设置为其他时区。

You can call gmtimerather than localtimeto use UTC for that; but I've just noticed that you're not actually using localtimeto do anything except get a pointer to a tm. You'd be better off declaring a local tm; the one used by localtimecould be reused whenever you call another time library function.

为此,您可以调用gmtime而不是localtime使用 UTC;但我刚刚注意到,localtime除了获取指向tm. 你最好声明一个 local tm; localtime每当您调用另一个时间库函数时,都可以重用by使用的那个。

Unfortunately, there's no standard variation of mktimeusing UTC. If you want UTC, your options are:

不幸的是,没有mktime使用 UTC 的标准变体。如果你想要 UTC,你的选择是:

  • Set the timezone using setenv("TZ", "", 1);. Note that this affects the whole program, so can be awkward if you also need to deal with local time.
  • Use a library like Boost.DateTime, which is slightly better at handling dates and timezones than the C library.
  • 使用setenv("TZ", "", 1);. 请注意,这会影响整个程序,因此如果您还需要处理本地时间,则可能会很尴尬。
  • 使用像 Boost.DateTime 这样的库,它在处理日期和时区方面比 C 库稍好。