NSCalendar 组件不考虑时间

发布于 2024-10-28 02:32:35 字数 879 浏览 2 评论 0原文

我们知道 NSDate 是 UTC/GMT。换句话说,没有与之关联的时区信息。

有一些高级类,例如 NSCalendar、NSTimeZone 和 NSDateComponents,它们确实考虑了时区。

基于此,我使用以下代码来计算两个日期之间的天数差异。然而,我得到的结果似乎是在完全忽略时间的情况下完成计算的。我想知道我是否做错了什么,或者这是出于某种原因设计的。

以下是代码和数据:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comp = [calendar components:NSDayCalendarUnit fromDate:startDate toDate:stopDate options:0];
NSInteger day = [comp day];

调试输出:

(gdb) po startDate
2011-04-01 03:52:13 +0000
(gdb) po stopDate
2011-04-03 15:52:13 +0000
(gdb) p (int) day
$1 = 2

时区是太平洋标准时间,上面转换为 PST 的日期是:

startDate = 2011-03-31 8:52:13 -7
stopDate  = 2011-04-03 8:52:13 -7

因此我预计它们之间有 4 天,而不是 2 天。(第 31 日、第 1 日、第 2 日和第 3 日)

我的原因认为忽略时间是因为如果将时间添加到计算中,我们将得到 2 天和 12 小时。

我做错了什么还是这就是设计的工作原理?

谢谢你, 万斯

We know that NSDate is UTC/GMT. In order words, no time zone info is associated with it.

There are high level classes such as NSCalendar and NSTimeZone and NSDateComponents which do take timezone into account.

Based on that, I am using the following code to calculate the difference in days between 2 dates. However the result I am getting seems as the calculation is done ignoring the time altogether. I am wondering if I am doing something wrong or if this is by design for some reason.

Here is the code and data:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comp = [calendar components:NSDayCalendarUnit fromDate:startDate toDate:stopDate options:0];
NSInteger day = [comp day];

Debug output:

(gdb) po startDate
2011-04-01 03:52:13 +0000
(gdb) po stopDate
2011-04-03 15:52:13 +0000
(gdb) p (int) day
$1 = 2

The timezone is Pacific Standard Time and the dates above converted to PST are:

startDate = 2011-03-31 8:52:13 -7
stopDate  = 2011-04-03 8:52:13 -7

Therefore I would expect 4 days between them, not 2. (31st, 1st, 2nd, and 3rd)

The reason I think the hours are ignored is because if hours are added to the calculations we get 2 days and 12 hours.

Am I doing something wrong or is this how this is designed to work?

Thank you,
Vance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨与橙与城 2024-11-04 02:32:35

不完全是。当您以太平洋时区格式化日期时,您会得到:

Calendars[38041:707] start: 2011-03-31 20:52:13 -0700
Calendars[38041:707] stop : 2011-04-03 08:52:13 -0700

这与您发布的内容有点不同。你的似乎显示上午 8 点,而不是晚上 8 点。

此外,components:fromDate:toDate:options: 将计算整个 单位。因此,如果您询问天数,它会说它们之间有整整 2 天,确实有。

也许执行您正在寻找的操作的更好方法是:

NSUInteger startOrdinal = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:startDate];
NSUInteger stopOrdinal = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:stopDate];

那么它们之间的天数将是(stopOrdinal - startOrdinal)。对于您的日期,这会产生 3(格林威治标准时间 4 月 1 日 - 格林威治标准时间 4 月 3 日)。如果您确实想忽略时间部分,则必须弄清楚如何删除目标时区内日期的时间部分。这将涉及将日期转换为 NSDateComponent 对象,然后设置 -小时-分钟-秒部分变为 0。完成此操作后,您可以将它们更改回 NSDates,然后继续进行差异计算。

Not quite. When you format the dates in the Pacific time zone, you get:

Calendars[38041:707] start: 2011-03-31 20:52:13 -0700
Calendars[38041:707] stop : 2011-04-03 08:52:13 -0700

This is a bit different from what you posted. Yours seems to indicate 8 AM, not 8 PM.

Also, the components:fromDate:toDate:options: is going to count whole units. Thus, if you're asking for the number of days, it's going to say there are 2 whole days in between them, which there are.

Perhaps a better way to do what you're looking for is this:

NSUInteger startOrdinal = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:startDate];
NSUInteger stopOrdinal = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:stopDate];

Then the number of days between them will be (stopOrdinal - startOrdinal). In the case of your dates, this yields 3 (April 1 GMT - April 3 GMT). If you really really want to ignore the time portion, you're going to have to figure out how to chop off the time portion of the dates within the target timezone. This will involve converting the dates into NSDateComponent objects, then setting the -hour, -minute, and -second portions to 0. Once you've done that, you can change them back into NSDates, and then go on with your difference calculations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文