在 C++ 中创建 Date 对象的正确方法是什么?我想要这个 python 代码的 C++ 类比:
import datetime
x = datetime.date(2020, 5, 17)
delta = datetime.timedelta(days=1)
x = x + delta
Run Code Online (Sandbox Code Playgroud)
我正在阅读有关 chrono 的内容,只发现 time_point https://en.cppreference.com/w/cpp/chrono/time_point
但我没有看到这样的构造函数date(year=2020, month=1, day=2)
How*_*ant 10
chrono 直到 C++20 才添加日历支持,并且各种实现仍在致力于此。Microsoft VC++ 稳居领先地位,目前发布了完整的规范。否则,您可以使用我的免费开源库与 C++11/14/17,它实现了新的计时日历支持,但它位于命名空间 date 中。我将描述 C++20,只要知道如果您无法使用它,有一个解决方法。
C++20 有两种(或更多)日期类型。主要有以下两个:
sys_daysyear_month_daysys_days是chrono::time_point基于system_clock,但精度为days. 它实际上是以下类型的别名:
time_point<system_clock, days>
Run Code Online (Sandbox Code Playgroud)
该类型所做的只是保存 1970 年 1 月 1 日之后(或负值之前)的整数天数。这使得它在面向日的算术中非常高效。它还擅长转换为日期时间类型,该类型只是精度比 更精细的任何system_clock-based- ,例如(通常为微秒到纳秒精度)。time_pointdayssystem_clock::time_point
year_month_day是一种{year, month, day}数据结构。它非常擅长年和月的算术。它可以非常有效地访问年、月和日字段。
人们可以在sys_days和 之间year_month_day以任一方向隐式转换,而不会丢失任何信息。
year_month_day ymd = ...; // some date
sys_days sd = ymd; // the same date in a different data structure
ymd = sd; // round trip - no change in value
Run Code Online (Sandbox Code Playgroud)
人们可以轻松地使用“常规语法”创建一个year_month_day,例如:
auto ymd = 2020y/5/17;
Run Code Online (Sandbox Code Playgroud)
ymd类型为year_month_day,其中年份为 2020 年、月份 5(或五月)和日期 17。2020 的y后缀表示值year,并且“/”运算符假定接下来的两个整数按该顺序表示月份和日期。
另外两个命令也是允许的: month/day/year和day/month/year。只要第一个字段是强类型的,后面的两个字段就可以是强类型的,也可以只是 int。
auto ymd2 = May/17/2020; // ymd2 == ymd
auto ymd3 = 17d/5/2020; // ymd3 == ymd
Run Code Online (Sandbox Code Playgroud)
您的示例代码可以写成:
sys_days x = 2020y/5/17;
x += days{1};
Run Code Online (Sandbox Code Playgroud)
year_month_day它隐式转换为sys_days.sys_days2020 年 5 月 18 日。C++20 中的其他日期类型包括:
local_days:有利于保持时区本地日期(与 UTC 不同)之间的差异。year_month_weekday:适合指定日期,例如 2020 年 5 月的第三个星期日 ( Sunday[3]/May/2020)。各种日期类型之间可以相互转换,例如:
year_month_day ymd4{Sunday[3]/May/2020}; // ymd4 == ymd
Run Code Online (Sandbox Code Playgroud)