C++ strftime-将周数ISO8601转换为公历标准C++;
我使用strftime获得ISO 8601格式(%V)的周数,并希望将其转换为outlook中显示的周数(猜测它是格里高利) Outlook日历设置为:C++ strftime-将周数ISO8601转换为公历标准C++;,c++,iso8601,strftime,week-number,gregorian-calendar,C++,Iso8601,Strftime,Week Number,Gregorian Calendar,我使用strftime获得ISO 8601格式(%V)的周数,并希望将其转换为outlook中显示的周数(猜测它是格里高利) Outlook日历设置为: 一周的第一天(星期日) 一年的第一周从1月1日开始 在某些年份,strftime与outlook中显示的weeknumber匹配,但在某些年份则不匹配 一个简单的代码检查: #包括 #包括 对于上面带有输入的代码,输出将是2018-W35,它与my outlook calendar()匹配 然而,如果将年份改为2019年,输出将为2019-
- 一周的第一天(星期日)
- 一年的第一周从1月1日开始
#包括 对于上面带有输入的代码,输出将是2018-W35,它与my outlook calendar()匹配 然而,如果将年份改为2019年,输出将为2019-W35,但在我看来,它将落在2019-W36() 是否可以将ISO8601周编号映射为格里高利风格 任何建议或代码示例都将非常有用
谢谢大家! 您参考的网站似乎使用了一种非常独特的周编号系统。它对周数的定义似乎反映了ISO的定义,但一周的第一天是星期天而不是星期一。这意味着一年的第一天是一年中第一个星期四之前的星期日 没有strftime标志提供具有此定义的周数。但是您可以使用C++20
工具轻松地计算它。不幸的是,它们还没有上市,但是您可以使用C++11/14/17
除了计算周数,您还需要计算年份,因为有时公历年与周关联的年份不匹配。例如,根据统计,2018年12月31日是2019年第1周
因此,这里有一个函数,在给定日期的情况下计算年份和周数:
#include "date/date.h"
#include <chrono>
#include <iostream>
#include <utility>
// {year, week number}
std::pair<int, int>
outlook_weeknum(date::sys_days sd)
{
using namespace date;
auto y = year_month_day{sd + (Thursday - Sunday)}.year();
auto year_start = sys_days{Thursday[1]/January/y} - (Thursday - Sunday);
if (sd < year_start)
{
--y;
year_start = sys_days{Thursday[1]/January/y} - (Thursday - Sunday);
}
return {int{y}, (sd - year_start)/weeks{1} + 1};
}
其中,y
是周编号系统中的年份(通常,但并不总是与公历年相同)。当日期在一年中很晚的时候,即12月28日至31日,它可能在下一年的第一周。为了抓住这种可能性,首先将日期增加4天(星期日和星期四之间的差值),然后计算当前年份
S M T W T F S
y-1 WL 21 22 23 24 25 26 27
y W1 28 29 30 31 1 2 3
完成此操作后,计算年初。如果一年的开始恰好在日期之后,那么你的日期就属于上一年。在这种情况下,周数年可能比公历年少一个。这可能发生在1月1日星期五或星期六
S M T W T F S
y-1 WL 27 28 29 30 31 1 2
y W1 3 4 5 6 7 8 9
总之,12/28-12/31日期的周年数可以等于其公历年,也可以大于一周。而日期01/01和01/02的周年数可以等于公历年,也可以小于公历年所有这些都取决于一月的第一个星期四在哪一天[1-7]
一旦计算出年份的周数(y
),那么周数就是日期和一年中第一个日期之间的差值除以7天(1周),再加上1,将第一周偏移为1,而不是0
这可以像这样进行:
int
main()
{
using namespace date;
auto [i, w] = outlook_weeknum(2019_y/9/1);
std::cout << i << "-W" << w << '\n';
}
要将此代码移植到C++20,请执行以下操作:
#包括“date/date.h”
命名空间日期
更改为命名空间std::chrono
2019年
更改为2019年
你读过这个吗?我们的环境。目前有gcc-c++-4.8.5,我们已经使用您的逻辑构建了我们自己的函数,并且运行良好。非常感谢。伟大的如果有帮助,以下是公共领域中一些非常有效的底层算法:
S M T W T F S
y-1 WL 27 28 29 30 31 1 2
y W1 3 4 5 6 7 8 9
int
main()
{
using namespace date;
auto [i, w] = outlook_weeknum(2019_y/9/1);
std::cout << i << "-W" << w << '\n';
}
2019-W36