构造日期的区域设置与当前区域设置不同
construct date in a different locale than current
我有一个要求,其中日期时间、区域设置和夏令时作为固定长度的字符串输入,例如YYMMDDHHMMCY
,下面提供了图例。
- YY(年)
- MM(月)
- DD(天)
- HH(小时)
- MM(分钟)
- 时区(C代表中部,P代表太平洋,M代表山区,E代表东部)
- 夏令时(如果夏令时有效,则为Y,反之为N)
所需要的是能够在指定的时区中构造时间,然后用C/C++将其转换为本地时区。我们不使用Boost,是否存在允许需求的现有功能。我知道strptime
,在对数据进行一些处理后,我可以使用它,但我想知道是否有如上所述的函数可以允许我在指定的区域设置中构造结构。
使用sscanf()
或strptime()
提取大部分字段。时区字符和DST字符需要自行解码。由于您只使用2位数的年份,因此需要定义您的范围。以下示例使用1970-2069。使用提取的时区字符形成常用时区名称。在调用mktime()
之前,请将TZ设置为时区名称。然后,拿着time_t
,转换为您的当地时间。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
extern time_t mktime_TZ(struct tm *tm, const char *tz);
extern time_t DecodeTimeString_time_t(const char *time_string);
void DecodeTimeString_Local(const char *time_string, struct tm *local) {
// Various error handling not shown
time_t t;
t = DecodeTimeString_time_t(time_string);
*local = *localtime(&t);
}
time_t DecodeTimeString_time_t(const char *time_string /* YYMMDDHHMMCY */) {
struct tm tm;
char Zone, DST;
int result = sscanf(time_string, "%2d%2d%2d%2d%2d%[CEMP]%[NY]",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &Zone, &DST);
if (result != 7) {
; // handle error
}
// Your need to decide how to handle 2 digits years
// Assume 70-99 is 1970-1999 and 0 to 69 is 2000-2069
if (tm.tm_year < 70) tm.tm_year += 2000-1900;
tm.tm_mon--; // Assume DateString used "01" for January, etc.
tm.tm_sec = 0;
tm.tm_isdst = Zone == 'Y';
const char *TZ;
switch (Zone) {
case 'P': TZ = "PST8PDT"; break; // Pacific
case 'M': TZ = "MST7MDT"; break; // mountain
case 'C': TZ = "CST6CDT"; break; // central
case 'E': TZ = "EST5EDT"; break; // eastern
}
time_t t = mktime_TZ(&tm, TZ);
return t;
}
// Form time_t from struct tm given a TZ
time_t mktime_TZ(struct tm *tm, const char *tz) {
time_t t;
const char *old_tz = getenv("TZ");
if (setenv("TZ", tz, 1 /* overwrite */)) {
return -1; // handle error
}
tzset();
t = mktime(tm);
if (old_tz) {
if (setenv("TZ", old_tz, 1 /* overwrite */)) {
return -1; // handle error
}
}
else {
if (unsetenv("TZ")) {
return -1; // handle error
}
}
tzset();
return t;
}
相关文章:
- 在 Linux 中存储区域设置名称的缓冲区大小应该是多少?
- 提升区域设置规范化带状字符,但不规范化重音
- 是否有任何区域设置会影响宽字符编码?
- 提升获取文本的区域设置"Conversion failed"
- 提升 1.41.0 : 提升::区域设置替代方案?
- std::locale 向"en_US.UTF-8"区域设置抛出runtime_error异常
- 默认情况具有哪个区域设置
- 区域设置是否有定义负号的方面?
- QT 将文本翻译成特定的区域设置
- 我可以强制 QFileDialog 使用系统区域设置而不是系统语言吗?
- 如何调用 GetAltMonthNames 来填充外部区域设置月份字符串的安全数组
- 提升区域设置不完整类型boundary_indexing<char32_t>
- 默认区域设置"root"在 ICU 中如何工作?
- std::regex总是可以识别区域设置吗?
- std::string 的运算符<是否应该受到当前区域设置的影响?
- C++为任何区域设置区域设置
- 如何显示与系统不同的区域设置的QDate月
- C++获取用户首选的编码或区域设置编码
- 使用cstring.format()中区域设置的小数分离器
- 当区域设置需要"3,14"时,如何使用scanf解析像"3.14"这样的数字