Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获取特定年份中指定周数(1-53)的第一个和最后一个日期(天和月)?_C++_Date - Fatal编程技术网

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

C++ 如何获取特定年份中指定周数(1-53)的第一个和最后一个日期(天和月)?,c++,date,C++,Date,如果给定了特定年份的周数,如何使用C/C++以简单的方式确定一周的第一个和最后一个日期(天和月)?提前谢谢你 Lee这受到当地周编号规则的严重影响。关于星期几是一周的开始,至少有两条通用规则,关于年初编号为1的星期,有三条通用规则 避免无休止地修补此类代码和使用库。ICU图书馆通过其日历类涵盖了这一点。相关介绍页。检查页面底部“年中的一周”字段中的注释。旧问题的新答案 这个答案包括为标准化而提出并被拒绝的代码。我提到这一点的原因是,出于提案的目的,代码位于名称空间std::chrono。但是重要

如果给定了特定年份的周数,如何使用C/C++以简单的方式确定一周的第一个和最后一个日期(天和月)?提前谢谢你


Lee

这受到当地周编号规则的严重影响。关于星期几是一周的开始,至少有两条通用规则,关于年初编号为1的星期,有三条通用规则


避免无休止地修补此类代码和使用库。ICU图书馆通过其日历类涵盖了这一点。相关介绍页。检查页面底部“年中的一周”字段中的注释。

旧问题的新答案

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

以下是使计算相当容易的方法(假设ISO标准周编号)。文档指向一个标题和一个实现提案的来源

使用这些源代码和下面显示的两个非常简短的助手函数,下面是一个程序,该程序使用周数和年份,并在民事(公历)日历中打印出该周的第一(星期一)和最后(星期日):

#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';
}
week\u to\u date
中的return语句需要一些解释:

(mon <= jan/_4th/y)
最后,如果一周的一天(
wd
)是星期天,我加上6天,否则我加上
wd-1
天,其中星期一=1,星期二=2,直到星期六=6(星期日=0)

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

实际上,包含了
周到日期的定义和基于ISO周的年份,尽管这些在建议书中只是作为如何使用日期类的示例,不属于建议书的一部分

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


更新

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

也就是说,在C++14支持的情况下,“日期常量”现在是真实的

此重新设计的库具有与文档链接的单个标题实现。语法类似,但与上面给出的语法不完全相同:

#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';
}
现在最大的区别是编译时常量被输出到
std::cout
。但是相同的代码(减去
static_断言
)在运行时输入时可以正常工作

节拍继续

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

#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';
}

如果你不表现出你是否做了任何努力,人们会集体否决你的问题!!你可能需要更加精确。有不同类型的周编号标准。你必须知道你想要哪一个。我已经很久没有做C了,我不记得它是如何处理日期的。在格式的构造中,是否有什么东西可以让您在时间上向前或向后拉出不同的日期掩码()?在哪里?在我居住的地区,我们过去的周数与美国模式相似,但现在改为ISO标准周数。我知道给定年份的第一周可能包括前一年的最后一天或多天。我们通常会及时向前推进。我最好使用ISO标准周编号惯例。谢谢大家对我的问题的关注。
这严重受周数当地规则的影响。
不,周数是非常清楚的。除非,唉,你的用户不使用它。嗯,典型的ISO产品。这不是一个标准,这是一个让每个人都同样不快乐的妥协。我不明白。WP将其描述为一项国际标准[…]
。如果这不是一个标准,那是什么?
+ (wd == 0 ? 6 : wd - 1))
#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';
}
2013-02-25
2013-03-03
#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