gpt4 book ai didi

c++ - 如何获取特定年份中指定周数(1-53)的第一个和最后一个日期(日和月)?

转载 作者:搜寻专家 更新时间:2023-10-31 01:53:45 24 4
gpt4 key购买 nike

如果给定特定年份的周数,我如何使用 C/C++ 轻松确定一周的第一个和最后一个日期(日和月)?提前致谢!

最佳答案

旧问题的新答案。

此答案包括提议用于标准化但被拒绝的代码。我提到的原因是代码在命名空间 std::chrono 中为提案的目的。但重要的是要意识到这个提议没有被接受,因此如果你使用它,你应该将提议的部分移到你自己的命名空间中。它们不是任何标准的一部分,甚至不被考虑用于标准化!

这里是 user documentation for my date class这使得这个计算相当容易(假设 ISO 标准周编号)。文档指向一个标题 <date> 和一个来源date.cpp实现提案。

使用这些资源和下面显示的两个非常简短的辅助函数,这里是一个程序,它需要周数和年份,并以民用(公历)打印出该周的第一天(星期一)和最后一天(星期日) ) 日历:

#include "date"
#include <utility>
#include <iostream>

std::chrono::date
week_to_date(int weeknum, std::chrono::weekday wd, std::chrono::year y)
{
using namespace std::chrono;
return (mon <= jan/_4th/y) + days((weeknum - 1)*7 + (wd == 0 ? 6 : wd - 1));
}

std::pair<std::chrono::date, std::chrono::date>
get_dates(unsigned week_num, unsigned y)
{
using namespace std::chrono;
return std::make_pair(week_to_date(week_num, mon, year(y)),
week_to_date(week_num, sun, year(y)));
}

int main()
{
auto p = get_dates(9, 2013);
std::cout << p.first << '\n';
std::cout << p.second << '\n';
}

对我来说,这是打印出来的:

2013-02-25
2013-03-03

week_to_date 中的返回语句可以使用一些解释:

(mon <= jan/_4th/y)

上述表达式构造了一个日期,它是 y 年 1 月 4 日或之前的星期一。然后我在 weeknum 之前每周添加 7 天到那个日期:

+ days((weeknum - 1)*7

最后如果工作日 ( wd ) 是星期天,我添加 6 天,否则我添加 wd-1星期一 == 1,星期二 == 2,星期六 == 6(星期日 == 0)。

+ (wd == 0 ? 6 : wd - 1))

最后一步是考虑到基于 ISO 周的日历周从星期一开始,而这个日期类的实现遵循从星期日开始的一周的 C/C++ 约定。

proposal实际上包括 week_to_date 的定义和基于 ISO 周的年份,尽管这些在提案中只是作为如何使用日期类的示例,而不是提案的一部分。

请随意使用代码,但我强烈建议先将其从命名空间 std 中删除。源代码足够短,像这样的小修改应该不难。


更新

这个答案的链接已经过时了,所以我更新了它们。但是,除了更新链接之外,我还想提请注意重新设计上面链接的库。重新设计将新的重点放在效率上,包括在编译时已知所有输入时的编译时日期计算。

如果支持 C++14,“日期常量”现在是真实的。

这个重新设计的库是 documented here使用从文档链接的单个 header 实现。语法与上面的语法相似,但不完全相同:

#include "date.h"
#include <iostream>

constexpr
date::year_month_day
week_to_date(int weeknum, date::weekday wd, date::year y)
{
using namespace date;
auto const dp = sys_days(jan/4/y);
auto const wdjan4 = weekday(dp);
return dp - (wdjan4 - mon)
+ days((weeknum - 1)*7 + (wd == sun ? 6 : static_cast<unsigned>(wd) - 1));
}

constexpr
std::pair<date::year_month_day, date::year_month_day>
get_dates(int week_num, date::year y)
{
using namespace date;
return std::make_pair(week_to_date(week_num, mon, y),
week_to_date(week_num, sun, y));
}

int
main()
{
using namespace date;
constexpr auto p = get_dates(9, 2013_y);
static_assert(p.first == feb/25/2013, "");
static_assert(p.second == 2013_y/mar/3, "");
std::cout << p.first << '\n';
std::cout << p.second << '\n';
}

两个主要区别是(在 C++14 中)可以进行计算 constexpr .和 operator<=不再可用于查找工作日等于或早于某个日期的日期。相反,此功能由“工作日减法”处理,这始终会产生正数(从工作日 1 到工作日 2 需要多少天?)。

这个程序的输出和之前的版本一样:

2013-02-25
2013-03-03

现在最大的不同是编译时常量被输出到 std::cout .但是相同的代码(减去 static_asserts )在运行时输入时工作得很好。

节拍继续

将上面介绍的库与新的兼容的 "iso_week.h" 相结合库,大大简化了上述计算的语法:

#include "date.h"
#include "iso_week.h"
#include <iostream>

int
main()
{
using namespace iso_week::literals;
auto y = 2013_y;
auto wn = 9_w;
std::cout << "The dates for " << y/wn << " are "
<< date::year_month_day{y/wn/mon} << " through "
<< date::year_month_day{y/wn/sun} << '\n';
}

哪些输出:

The dates for 2013-W09 are 2013-02-25 through 2013-03-03

关于c++ - 如何获取特定年份中指定周数(1-53)的第一个和最后一个日期(日和月)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10672461/

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