c++strptime在解析时会忽略时区
c++ strptime ignores Timezone when parsing
本文关键字:时区 c++strptime 更新时间:2023-10-16
当我运行以下代码时,strptime似乎忽略了时区值。只设置本地时区的值(即+10)。
这是输出,(在Linux上运行,使用gcc 4.6.3编译):
-----------2013-04-24T9:47:06+400 - %Y-%m-%dT%H:%M:%S%z
TM Break H:9 is DST:0 GMT Off:0
The epoch value: 1366760826
DateTime in String: 04/24/13 - 09:47AM +1000
-----------2013-04-24T11:47:06+800 - %Y-%m-%dT%H:%M:%S%z
TM Break H:11 is DST:0 GMT Off:36000
The epoch value: 1366768026
DateTime in String: 04/24/13 - 11:47AM +1000
-----------2013-04-24T9:47:06+0 - %Y-%m-%dT%H:%M:%S%z
TM Break H:9 is DST:0 GMT Off:36000
The epoch value: 1366760826
DateTime in String: 04/24/13 - 09:47AM +1000
-----------2013-04-24T9:47:06+4 - %Y-%m-%dT%H:%M:%S%z
TM Break H:9 is DST:0 GMT Off:36000
The epoch value: 1366760826
DateTime in String: 04/24/13 - 09:47AM +1000
这是代码:
void date_Test(){
string dateStrings[] = {"2013-04-24T9:47:06+400"
, "2013-04-24T11:47:06+800"
, "2013-04-24T9:47:06+0"
, "2013-04-24T9:47:06+4"};
string formatStrings[] = {"%Y-%m-%dT%H:%M:%S%z"
, "%Y-%m-%dT%H:%M:%S%z"
, "%Y-%m-%dT%H:%M:%S%z"
, "%Y-%m-%dT%H:%M:%S%z"};
process_Timezone(dateStrings, formatStrings);
}
void process_Timezone(string dateStrings[], string formatStrings[]){
int num = 4;
for (int i = 0; i < num; i++) {
cout << endl << "-----------" << dateStrings[i] << " - " << formatStrings[i] << endl;
tm *dtm = new tm;
strptime(dateStrings[i].c_str(), formatStrings[i].c_str(), dtm);
cout << "TM Break tH:" << dtm->tm_hour << " is DST:" << dtm->tm_isdst << " GMT Off:" << dtm->tm_gmtoff << endl;
time_t ep_dt = mktime(dtm);
cout << "The epoch value: t" << ep_dt << endl;
char buffer[40];
strftime(buffer, 40,"%x - %I:%M%p %z", dtm);
cout << "DateTime in String: t" << buffer << endl;
delete dtm;
}
}
根据http://en.wikipedia.org/wiki/ISO_8601
,您的一位和三位时区偏移不是有效的ISO 8601值(strptime
至少在Linux上使用的形式),这需要hh[:][mm]
作为格式。
可能晚了,但strptime
确实正确解析了%z
说明符,它将其存储在tm.tm_gmtoff
变量中。这个变量不在标准中,而是一个gnu扩展。mktime
没有使用这个变量。
你可以试试
strptime(<time_string>, dtm);
std::cout << dtm->tm_gmtoff;
以查看解析的时间偏移。
注意.tm_gmtoff
在秒,所以要获得正确的历元时间,可以进行
auto offset = dtm->tm_gmtoff;
auto _epoch = mktime(dtm);
auto final_epoch = _epoch + offset
来源
- https://www.gnu.org/software/libc/manual/html_node/Broken_002ddown-Time.html
- https://github.com/andikleen/glibc/blob/master/time/strptime_l.c#L749
@Nguyen Ha Kien的回答帮助了我,但为了获得正确的历元时间,我也需要在mktime填写本地UTC偏移量后,将其考虑在内,而不是在此处覆盖libc对DST是否在指定时间活动的确定:
int offset = dtm->tm_gmtoff;
// Ask libc to work out whether the local timezone is in DST at this time.
dtm->tm_isdst = -1;
time_t ep_dt = mktime(dtm);
ep_dt -= offset - dtm->tm_gmtoff;
int而不是auto,只是因为我是在2011年的时代设置上编译的,希望像pt123最初使用的那样,以表明Mark B的答案会得到strptime来为我解析tm_gmtoff:
(ia32)martind@sirius:~/playpen$ ls /lib/libc-2.11.3.so
/lib/libc-2.11.3.so
(ia32)martind@sirius:~/playpen$ gcc -v
...
gcc version 4.4.5 (Debian 4.4.5-8)
(ia32)martind@sirius:~/playpen$ g++ c-strptime-ignores-timezone-when-parsing.cpp
(ia32)martind@sirius:~/playpen$ ./a.out
-----------2013-04-24T9:47:06+0400 - %Y-%m-%dT%H:%M:%S%z
TM Break H:9 is DST:0 GMT Off:14400
唯一的附加代码是:
#include <iostream>
#include <string>
using namespace std;
void process_Timezone(string dateStrings[], string formatStrings[]);
void date_Test();
int main(){
date_Test();
}
相关文章:
- Log4cpp:以UTC/GMT时区打印日期
- std::strftime 在 Windows 中使用 GMTIME 将时区 UTC 显示为 UTC+1
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- C++日期库因时区而失败
- C++:获取时区偏差
- 如何在Arduino上将时间设置为中部时区?
- structtm是否将时区信息存储为其数据成员
- C++:将Unix时间转换为非本地时区
- 获取指定时区的日期和时间
- 如何以正确的时区从XTS索引中获取数字时间?
- 将带有时区的纪元时间转换为Excel格式的时间?
- 快速将带有时区的日期时间字符串转换为 UNIX 时间戳(C++)
- 使用C 在特定时区获取当前时间
- 生成包含分数和时区的完整 iso 日期时间表示字符串
- C :如何使用ICU通过给定的时区偏移来获得当前时间
- 使用Boost或STD在特定时区中获取当前的本地时间
- Poco 日期时间格式化程序 - 使用当前时区打印时间戳
- 无UTC时区中的正确时间总和
- C/C 获得时区偏移信息的时间戳
- c++strptime在解析时会忽略时区