英文:
How to create date object in C++?
问题
在C++中创建Date对象的正确方法是使用std::chrono::year_month_day
结构,然后转换为std::chrono::system_clock::time_point
。以下是类似于Python代码的C++示例:
#include <iostream>
#include <chrono>
int main() {
std::chrono::year_month_day ymd{std::chrono::year{2020}, std::chrono::month{5}, std::chrono::day{17}};
std::chrono::system_clock::time_point tp = std::chrono::sys_days(ymd);
std::chrono::days delta(1);
tp += delta;
// 输出日期
std::time_t tt = std::chrono::system_clock::to_time_t(tp);
std::tm tm = *std::localtime(&tt);
std::cout << "Year: " << tm.tm_year + 1900 << ", Month: " << tm.tm_mon + 1 << ", Day: " << tm.tm_mday << std::endl;
return 0;
}
这段代码演示了如何在C++中创建日期对象,并进行日期运算,类似于Python中的示例。
英文:
What is the proper way to create Date object in C++?
I want C++ analogy of this python code:
import datetime
x = datetime.date(2020, 5, 17)
delta = datetime.timedelta(days=1)
x = x + delta
I was reading about chrono and found only time_point https://en.cppreference.com/w/cpp/chrono/time_point
but I don't see constructor like this date(year=2020, month=1, day=2)
答案1
得分: 10
chrono直到C++20才添加了日历支持,各种实现仍在努力改进。Microsoft VC++目前已经实现并发布了完整的规范。否则,你可以使用我的免费、开源库,支持C++11/14/17,它实现了新的chrono日历支持,但位于date命名空间。我会介绍C++20,只要知道如果不可用,有一种解决方法。
C++20有两种(或更多)日期类型,主要是以下两种:
sys_days
year_month_day
sys_days
是基于system_clock
的chrono::time_point
,但精度为days
。实际上,它是以下类型的类型别名:
time_point<system_clock, days>
这个类型只是保存自1970-01-01以来的天数的整数计数(对于负值来说是之前的天数)。这使得它非常高效地进行面向天的算术运算。它还很擅长转换为日期时间类型,即具有比days
更精确的精度的任何system_clock
基础的time_point
,比如system_clock::time_point
(通常是微秒到纳秒精度)。
year_month_day
是一个{year, month, day}
数据结构。它非常适合进行年份和月份的算术运算,并且可以非常高效地访问年份、月份和日期字段。
可以在sys_days
和year_month_day
之间进行隐式转换,无论是在哪个方向都不会丢失信息。
year_month_day ymd = ...; // 一些日期
sys_days sd = ymd; // 不同数据结构中的相同日期
ymd = sd; // 往返转换 - 值不变
可以使用“传统语法”轻松创建year_month_day
,例如:
auto ymd = 2020y/5/17;
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
你的示例代码可以写成:
sys_days x = 2020y/5/17;
x += days{1};
- 传统语法创建了一个
year_month_day
,它隐式转换为sys_days
。 - 将一天添加到值,创建了一个等于2020y/5/18的
sys_days
。
C++20中的其他日期类型包括:
local_days
:适用于保留时区本地日期与UTC日期之间的差异。year_month_weekday
:适用于指定日期,例如2020年5月的第三个星期日(Sunday[3]/May/2020
)。
可以在各种日期类型之间进行互相转换,例如:
year_month_day ymd4{Sunday[3]/May/2020}; // ymd4 == ymd
英文:
chrono doesn't add calendrical support until C++20, and the various implementations are still working on that. Microsoft VC++ is solidly out front and currently shipping the full spec. Otherwise you can use my free, open source library with C++11/14/17 which implements the new chrono calendrical support, except it is in namespace date. I'll describe C++20, just know that if that isn't available to you, there's a workaround for that.
C++20 has two (or more) date types. These are the main two:
sys_days
year_month_day
sys_days
is a chrono::time_point
based on system_clock
, but with a precision of days
. It is actually a type alias for:
time_point<system_clock, days>
All this type does is hold an integral count of days after 1970-01-01 (or before for negative values). This makes it very efficient at day-oriented arithmetic. It is also good at converting to a date-time type, which is just any system_clock
-based-time_point
with a precision finer than days
, such as system_clock::time_point
(typically microseconds to nanoseconds precision).
year_month_day
is a {year, month, day}
data structure. It is very good at year and month arithmetic. And it has very efficient access to the year, month and day fields.
One can implicitly convert between sys_days
and year_month_day
, in either direction, with no information loss.
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
One can easily create a year_month_day
with "conventional syntax", for example:
auto ymd = 2020y/5/17;
ymd
has type year_month_day
, with the year 2020, the month 5 (or May), and the day 17. The y
suffix on 2020 denotes a value of year
, and the '/' operators assume the next two integers represent month and day in that order.
Two other orders are permissible: month/day/year
and day/month/year
. As long as the first field is strongly typed, the following two fields can be either strongly typed, or just int.
auto ymd2 = May/17/2020; // ymd2 == ymd
auto ymd3 = 17d/5/2020; // ymd3 == ymd
Your example code can be written:
sys_days x = 2020y/5/17;
x += days{1};
- The conventional syntax creates a
year_month_day
which implicitly converts tosys_days
. - One day is added to the value creating a
sys_days
equal to 2020y/5/18.
Other date types in C++20 include:
local_days
: good for keeping the difference between the date local to a time zone, as opposed to UTC.year_month_weekday
: good for specifying dates such as the third Sunday of May 2020 (Sunday[3]/May/2020
).
One can inter-convert among the various date types, for example:
year_month_day ymd4{Sunday[3]/May/2020}; // ymd4 == ymd
答案2
得分: 4
A date object is available in the standard library since c++20.
#include <chrono>
#include <iostream>
int main ()
{
std::chrono::year_month_day date(
std::chrono::year(2023),
std::chrono::month(5),
std::chrono::day(7));
std::cout << "Year: " << static_cast<int>(date.year())
<< ", Month: " << static_cast<unsigned>(date.month())
<< ", Day: " << static_cast<unsigned>(date.day()) << '\n';
}
Even though stream output should exist it is not available in the demo environment above, hence the manual cast of each value prior to output.
Arithmetic operations like the one you mention are provided either as:
- member functions (e.g.
date += months
) - non-member functions (e.g.
date1 + months
)
Note that the year(), month(), day()
methods return objects that are not the same as the corresponding specializations for duration (std::chrono::years
, std::chrono::months
, std::chrono::days
) but merely integral representations of the count of such quantities (hence the static cast to int
is ok). That said, you can perform arithmetic operations with the corresponding durations.
英文:
A date object is available in the standard library since c++20.
#include <chrono>
#include <iostream>
int main ()
{
std::chrono::year_month_day date(
std::chrono::year(2023),
std::chrono::month(5),
std::chrono::day(7));
std::cout << "Year: " << static_cast<int>(date.year())
<< ", Month: " << static_cast<unsigned>(date.month())
<< ", Day: " << static_cast<unsigned>(date.day()) << '\n';
}
Even though stream output should exist it is not available in the demo environment above, hence the manual cast of each value prior to output.
Arithmetic operations like the one you mention are provided either as:
- member functions (e.g.
date += months
) - non member functions (e.g.
date1 + months
)
Note that the year(), month(), day()
methods return object that are not the same as the corresponding specializations for duration (std::chrono::years
, std::chrono::months
, std::chrono::days
) but merely integral representation of the count of such quantities (hence the static cast to int
is ok). That said, you can perform arithmetic operations with the corresponding durations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论