考虑闰年,在COledateTime中添加一年的正确方法是什么



我有这个代码:

COleDateTime datStart = COleDateTime::GetCurrentTime(), datEnd;
// Update end date (one year later)
datEnd.SetDateTime(datStart.GetYear() + 1,
datStart.GetMonth(),
datStart.GetDay(),
datStart.GetHour(),
datStart.GetMinute(),
datStart.GetSecond());

上述代码昨天(2020年2月29日(失败,因为datEnd导致2021年2月29无效。

考虑到闰年,安全地在datStart中添加一年的正确方法是什么?

C#有:

DateTime theDate = DateTime.Now;
DateTime yearInTheFuture = theDate.AddYears(1);

MFC/C++的等价物是什么?

一种可能性是:

COleDateTimeSpan spnYear;
spnYear.SetDateTimeSpan(365, 0, 0, 0);
datEnd = datStart + spnYear;

但由于闰年有366天,它仍然存在潜在的缺陷。那么什么是正确的方法呢?

我看到了类似的问题:

C++添加1年至今的

这意味着使用CCD_ 3。虽然我从来没有把它用于日期操纵,但我的项目确实有进步。想知道这是否可以与COleDateTime对象一起使用?

使用boost:

boost::gregorian::date dStart{ datStart.GetYear(), datStart.GetMonth(), datStart.GetDay() };
boost::gregorian::date dEnd = dStart + boost::gregorian::years(1);
datEnd.SetDateTime(
dEnd.year(),
dEnd.month(),
dEnd.day(),
datStart.GetMonth(),
datStart.GetMinute(),
datStart.GetSecond());

不编译。

4>D:My Programs2019MeetSchedAssistMeeting Schedule AssistantPublishersDatabaseDlg.cpp(354,49): error C2398: Element '1': conversion from 'int' to 'boost::gregorian::date::year_type' requires a narrowing conversion
4>D:My Programs2019MeetSchedAssistMeeting Schedule AssistantPublishersDatabaseDlg.cpp(354,70): error C2398: Element '2': conversion from 'int' to 'boost::gregorian::date::month_type' requires a narrowing conversion
4>D:My Programs2019MeetSchedAssistMeeting Schedule AssistantPublishersDatabaseDlg.cpp(354,89): error C2398: Element '3': conversion from 'int' to 'boost::gregorian::date::day_type' requires a narrowing conversion

COleDateTime是围绕(令人惊讶的(DATE类型的包装器。在内部,它存储一个64位浮点值,其中整数表示自1899年12月30日(午夜(以来的天数。小数部分表示一天中的时间(例如0.25表示上午6点,0.5表示中午(。每个浮点值都是一个合法值,代表一个唯一的1时间点。

将一年添加到COleDateTime值等于将值365.0(或适合您需要的值(添加到其内部表示中。这可以通过直接访问m_dt成员来实现

COleDateTime datEnd{ datStart.m_dt + 365.0 };

或使用COleDateTimeSpan

datEnd = datStart + COleDateTimeSpan{ 365.0 };
// or
datEnd = datStart + COleDateTimeSpan{ 365, 0, 0, 0 };

此操作始终定义良好,并且无论闰年如何都会产生有效的时间点。在引擎盖下,它只是添加浮点值,这些值没有日历属性的概念。以下代码

COleDateTime datStart{ 2020, 2, 29, 0, 0, 0 };
COleDateTime datEnd{ datStart + COleDateTimeSpan{ 365.0 } };

将生成一个表示2021年2月28日的时间点(请注意,如果添加366.0天,则将返回2021年3月1日(。


试图通过对单个日期组件进行运算来构建COleDateTime的初始解决方案在构建过程中失败。构造函数验证其输入。当通过(2021, 2, 29, 0, 0, 0)时,它确定一个无效日期,并将m_status设置为invalid


1这并不完全正确。范围(-1 .. 0]中的值映射到与其绝对值相同的时间点。注意,例如COleDateTime{-0.25} == COleDateTime{0.25}评估为false,即使它们表示相同的时间点

最新更新