gpt4 book ai didi

c++ - strftime-将周数ISO8601转换为格里高标准C++

转载 作者:行者123 更新时间:2023-12-01 14:38:58 28 4
gpt4 key购买 nike

我使用strftime获得ISO 8601格式(%V)的星期数,并希望转换为前景中显示的星期数(猜测是格里高利历法)。
Outlook日历设置为:

  • 一周的第一天(星期日)
  • 一年的第一周1月1日开始

  • 在某些年份中,strftime与Outlook中显示的周号匹配,但在某些情况下则不匹配。
    一个简单的代码检查:
    #include
    #include
    int main ()
    {
    time_t rawtime;
    struct tm *tmDate;
    char buffer [80];

    time (&rawtime);
    tmDate = localtime(&rawtime);
    tmDate->tm_hour = 12;
    tmDate->tm_mday = 1; //Day of the Month
    tmDate->tm_mon = 8; //Month (0=Jan...8=Sep)
    tmDate->tm_year = 2018-1900; //Year
    mktime(tmDate);

    strftime (buffer,80,"%Y-W%V",tmDate);
    puts (buffer);

    return 0;
    }
    对于上面输入的代码,输出为2018-W35,与我的Outlook日历( https://www.calendar-365.com/2018-calendar.html)相匹配。
    而如果将年份更改为2019,则输出将为2019-W35,但在我看来,它应为2019-W36( https://www.calendar-365.com/2019-calendar.html)。
    是否可以将ISO8601周号映射为格里高利风格?
    任何建议或代码示例都将有所帮助!
    谢谢!

    最佳答案

    您引用的网站似乎使用了非常独特的星期编号系统。它对星期数的定义似乎与ISO定义类似,但一周的第一天是星期日而不是星期一。这意味着一年的第一天是该年的第一个星期四之前的星期日。
    没有strftime标志可使用此定义给出星期数。但是您可以使用C++ 20 <chrono>工具轻松地对其进行计算。不幸的是,他们还没有发货,但是您可以使用此free, open-source C++20 chrono preview library,它可与C++ 11/14/17一起使用。
    除了计算周数外,您还需要计算年份,因为有时公历年份与与该周关联的年份不匹配。例如根据https://www.calendar-365.com/2019-calendar.html,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};
    }
    逻辑有点棘手。困难的部分是查找该日期的一年中的第一天,即该年的第一个星期四之前的星期日。这名义上是:
    auto year_start = sys_days{Thursday[1]/January/y} - (Thursday - Sunday);
    其中 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改为0而不是0。 。
    可以这样执行:
    int
    main()
    {
    using namespace date;

    auto [i, w] = outlook_weeknum(2019_y/9/1);
    std::cout << i << "-W" << w << '\n';
    }
    输出:
    2019-W36
    要将代码移植到C++ 20:
  • 删除#include "date/date.h"
  • namespace date更改为namespace std::chrono
  • 2019_y更改为2019y
  • 关于c++ - strftime-将周数ISO8601转换为格里高标准C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63133926/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com