Datetime 日期表在哪里有用?

Datetime 日期表在哪里有用?,datetime,d,phobos,Datetime,D,Phobos,我正在读火卫一的文件。有时我不理解某些方法的逻辑 将给定的年数或月数添加到此日期。负数将相减。滚动和添加的区别在于,滚动不会影响较大的单位 也许是火卫一考虑不好,也许我不明白它在哪里会有帮助 例如,如果我在2013-07-01中增加200天,我预计将在2014年,但不是2013年 有人能解释一下逻辑吗?roll也出现在Java中。。。。我记得我唯一一次在这两种语言中使用它是实现了一个小的日期选择器小部件。每件事都有单独的字段:月、日、年,您希望用户能够在不增加月的情况下旋转天数,因为它们是单独

我正在读火卫一的文件。有时我不理解某些方法的逻辑

将给定的年数或月数添加到此日期。负数将相减。滚动和添加的区别在于,滚动不会影响较大的单位

也许是火卫一考虑不好,也许我不明白它在哪里会有帮助

例如,如果我在2013-07-01中增加200天,我预计将在2014年,但不是2013年


有人能解释一下逻辑吗?

roll
也出现在Java中。。。。我记得我唯一一次在这两种语言中使用它是实现了一个小的日期选择器小部件。每件事都有单独的字段:月、日、年,您希望用户能够在不增加月的情况下旋转天数,因为它们是单独的字段。(假设设置为30,他们想选择第一个。最快的方法可能是点击向上箭头,让它滚动。)

可能还有其他用途,我只是现在不记得了。即使在我不久前实现ical支持时(遗憾的是,是专有的),我也从未使用过roll方法,但在那里可能有使用它的潜力。ical是日历上重复事件的标准,其中有一些棘手的事情,以及一些不同的实现方式

在评论中,您还会问为什么不能添加天数。原因是添加天数非常简单,并且包含了
opBinary

datetime += 5.days; // works
但这在几个月内不起作用,因为几个月的持续时间是可变的。这就是
add
方法的作用:假设是1月30日,你加了一个月。你可以加上31天,因为一月份有31天。这将使你在3月2日登陆(我想,在我的头脑中这样做)。。。但1月30日+1个月也可能需要2月28日。或者可能是2月29日。假设您正在支付月底到期的月度账单,这些到期日之间的天数将发生变化

add
方法处理这个问题,并为您提供在最后一天跌倒或溢出到下个月的选项


尽管如此,我还是有点争辩说,白天也没有固定的长度。。。。考虑DST转换。(或闰秒,但处理它们将是愚蠢的)。也许我们可以问JMD。

那么,简单的回答是,
roll
专门用于处理日期选择器和类似用例,
add
专门用于处理月份和年份,因为
Duration
不能(因为在不知道起点的情况下,数月和数年不会转换为百分之几纳秒)。但我将尝试一个更深入的答案,以防澄清问题

DateTime
Date
TimeOfDay
是为基于日历的操作而设计的。它们与系统时钟无关,没有时区概念,它们将日期/时间的各个部分作为单独的单位(年、月、日、小时等)保存在内部。因此,当您在
日期时间
上设置
小时
字段时,您实际上只是在调整
日期时间
的一个成员变量。当您向它们添加
持续时间
时,必须将其拆分以分别添加到每个单元,从而执行类似于添加7小时的
持续时间
的操作uld增量不仅仅是
小时
字段。例如

auto dt = DateTime(2015, 8, 2, 20, 0, 0);
dt += hours(7);
assert(dt == DateTime(2015, 8, 3, 3, 0, 0));
由于
Duration
在内部以百纳秒为单位保存其值,因此您不一定要添加到特定的单位。也就是说,它不像
+=hours(7)
专门添加到
hour
字段中。它向整个
DateTime
中添加了一定数量的百分之几纳秒,并且必须弄清楚这是如何影响每个单位的,而不是影响特定单位的。例如

auto dt = DateTime(2015, 8, 2, 20, 0, 0);
dt += hours(7) + minutes(5) + seconds(22);
assert(dt == DateTime(2015, 8, 3, 3, 5, 22));
另一方面,
roll
专门用于在不影响任何其他单位的情况下添加到特定单位。正如Adam正确确定的那样,它的主要使用情形是用于日期选择器对话框中的旋转控件等,在该对话框中,您最终会将特定时间单位调整一定量,而您不想影响其他单位,只要你正在调整的那一个。所以,如果你加上7个小时,你不会以一天的增加而结束,只有小时

auto dt = DateTime(2015, 8, 2, 20, 0, 0);
dt.roll!"hours"(7);
assert(dt == DateTime(2015, 8, 2, 3, 0, 0));
现在,随着月份和年份的增加,事情变得更有趣了,因为它们没有固定的长度。这就是为什么
持续时间
不支持它们。你不能说
x
hecto纳秒等于
y
月或
z
年。但是
持续时间
对于月来说没有意义或者年,我们仍然希望能够在
日期
日期时间
中添加月和年。因此,我们有
添加!“年”
添加!“月”
来处理这个问题,它允许您控制一些奇怪的事情,比如在1月31日添加一个月是否应该在2月底或3月初结束(因为没有2月31日)

所有这些都没有考虑任何类型的时区。它纯粹是处理日历时间。
添加
滚动
是纯粹基于日历的操作,而
+=
日期时间
日期
时间日期
上实现的是基于日历的操作。它需要年、月、日,等等。在进行计算时,将其考虑在内(在他们的情况下,不能进行其他操作,因为单位在其成员变量中被拆分)

然后我们有了
SysTime
。它旨在表示系统的时间(这意味着要考虑时区)。但是,避免DST相关问题和类似问题的唯一方法是始终将时间保持在UTC。因此,
SysTime
始终将其内部时间保持在UTC(以百分之一纳秒为单位)并使用
时区
对象
auto year = st.year;
auto month = st.month;
auto day = st.day;