C++ strftime在iOS上返回不正确的星期几
我有以下代码:C++ strftime在iOS上返回不正确的星期几,c++,ctime,C++,Ctime,我有以下代码: #include <iostream> #include <ctime> using namespace std; int main() { tm _tm; strptime("2017-04-17", "%Y-%m-%d", &_tm); char buf[16]; strftime(buf, sizeof(buf), "%A", &_tm); cout << buf <&
#include <iostream>
#include <ctime>
using namespace std;
int main() {
tm _tm;
strptime("2017-04-17", "%Y-%m-%d", &_tm);
char buf[16];
strftime(buf, sizeof(buf), "%A", &_tm);
cout << buf << endl;
}
#包括
#包括
使用名称空间std;
int main(){
tm_tm;
STRTIME(“2017-04-17”,%Y-%m-%d”,&U tm);
char-buf[16];
strftime(buf,sizeof(buf),“%A”和_tm);
coutstrptime()
仅更新提供的struct tm
中格式字符串中指定的字段。其他字段单独保留(在您的情况下未初始化)。有两个问题导致问题中的行为
strtime
似乎在解析日期时意外地使本地时区生效(但仅用于设置一周中的某一天!)。它似乎在解析“2017-04-17”时,至少对于一周中的某一天,它将其视为类似UTC午夜的东西——这意味着UTC在该“时间”的一周中的某一天会出现负偏移是早了一天
基本上,strtime
总是给我tm_wday
一个小于正确值的值。当解析“2017-04-17”(星期一)和“2017-04-18”(星期二)时,它将返回0
(星期日)
非常奇怪的是,它不会填充其他时区数据,如tm_isdst
或tm_gmtoff
。它会保持这些数据不变——只需为tm_wday
选择一个不正确的值
我可以通过调用从strptime
返回的生成的tm
结构上的mktime
来解决这个问题。我没有使用从mktime
返回的time
,但是在tm
结构上调用mktime
的行为正确地设置了tm\u-wday
的值,并且纠正了错误仅设置tm_isdst
、tm_gmtoff
等的值
我没有将tm
结构初始化为零。这只有在我开始调用mktime
时才真正起作用。没有正确的初始化,mktime
会因为tm\gmtoff
的垃圾值而损坏日期。正确初始化后,调用mktime
会给出一个格式良好的日期正确的tm_wday
设置
因此,一个有效的例子如下:
tm _tm = {};
strptime("2017-04-17", "%Y-%m-%d", &_tm); // Incorrect tm_wday after this call
mktime(&_tm); // Correct tm_wday after this call
char buf[16];
strftime(buf, sizeof(buf), "%A", &_tm);
这不是一个答案,但可能是一个解决方案:
如果您可以在C++11或更高版本中工作,您可以在两种平台上得到相同的答案
#include "date.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
istringstream in{"2017-04-17"};
date::year_month_day ymd;
in >> parse("%Y-%m-%d", ymd);
cout << format("%A\n", ymd);
}
此库将解析和格式化解释为以UTC隐式表示,没有时区或计算机当前本地时区的诡计。如果您需要该功能,它将存在于一个数据库中
“%F”
也可用作“%Y-%m-%d”
的简写,作为POSIXstrtime
规范的扩展
in >> parse("%F", ymd);
这是一个非常完整的DATE时间库,可以处理一年中的粗糙特征,以及与纳秒一样高的时间戳。它都是在C++的代码> < /C>库中建立的,因此完全是类型安全的。随后比C/POSIX API更容易使用,在编译时检测到许多逻辑错误。/p> 在man7.org上,“使用了环境变量TZ和LC_TIME。”运行程序时,您可能需要检查每个系统上的两个值。@WeatherVane我认为这也是一个有效的C问题。请不要删除标记。@Olaf您真的需要我将其重新格式化为C以显示它也是一个有效的C问题吗?@Aardvark…是吗?在其当前形式中,问题中没有与C相关的内容on.和
strtime
不是标准函数。ideone当然不是自动循环引用。在这种情况下,tm_wday
实际上设置为0。我尝试手动将其设置为1,但strtime
将其重置为0(星期日,而不是星期一)。因此,我不认为这是问题所在,尽管将结构初始化为零显然是我的最佳实践。但这并不能解决问题。我认为@yellowantphil可能是对的?这可能是一个时区问题。我提供的日期被解释为时间(可能是UTC)。因为我的UTC偏移量是负数,所以它会将工作日计算为前一天?这是我的运行理论……我相信它可能与tm_isdst
(与时区相关)。我不太确定这个答案-在删除它之前,我会让它保留一段时间,但我想有人会想出一个更好的答案。哦,mktime
确实需要零初始化值,否则它会将日期转换为一个非常不稳定的值!所以基本上我必须对值retu进行零初始化并调用mktime
从strtime
调用,将其转换为本地时区值,以便检索正确的wday
值。
Monday
in >> parse("%F", ymd);