NSDateComponents - 结合日期和时间会损失 1 小时?

Posted

技术标签:

【中文标题】NSDateComponents - 结合日期和时间会损失 1 小时?【英文标题】:NSDateComponents - Combining a date and time loses 1 hour? 【发布时间】:2015-02-26 10:10:06 【问题描述】:

我正在尝试将 NSDate(日期)与 NSDate(时间)组合成一个新的 NSDate 对象,无论出于何种原因,我似乎都损失了 1 小时。

我有一组格式化的时间对象,每个对象间隔 15 分钟。 我有一个可选择的日期项,它引用一个 NSDate 对象。

用户选择一个格式化的时间对象(我在字典中引用了 NSDate),然后在保存时;我这样做;

if (self.selectedDate && self.selectedTimeObject)
    
        // Combine selected date and selected time into a new NSDate object
        NSCalendar *cal = [NSCalendar currentCalendar];

        unsigned unitFlagsDate = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
        unsigned unitFlagsTime = NSHourCalendarUnit | NSMinuteCalendarUnit |  NSSecondCalendarUnit;

        NSDateComponents *dateComponents = [cal components:unitFlagsDate fromDate:self.selectedDate];
        NSDateComponents *timeComponents = [cal components:unitFlagsTime fromDate:self.selectedTimeObject];

        [dateComponents setSecond:[timeComponents second]];
        [dateComponents setHour:[timeComponents hour]];
        [dateComponents setMinute:[timeComponents minute]];

        NSDate *combinedDate = [cal dateFromComponents:dateComponents];
        NSLog(@"targetDate = %@", combinedDate);
    

在我的示例中,我选择 01:00;但由于某种原因,我会根据日期损失 1 小时。

日志;

targetDate = 2015-03-31 00:00:00 +0000
targetDate = 2015-03-30 00:00:00 +0000
targetDate = 2015-03-29 01:00:00 +0000
targetDate = 2015-03-28 01:00:00 +0000
targetDate = 2015-03-27 01:00:00 +0000
targetDate = 2015-03-31 00:00:00 +0000
targetDate = 2015-04-01 00:00:00 +0000
targetDate = 2015-04-02 00:00:00 +0000

现在在我的日志中,我注意到 28 岁之前的任何事情都很好,但该日期之后的任何事情都会失去 1 小时而没有任何解释。

我检查了我的数组,我检查了我的索引,我检查了对象是有效的时间对象;但是我很困惑——为什么会失去 1 小时?

【问题讨论】:

我认为这里的 NSDateComponents 有问题,但无法识别 【参考方案1】:

问题很可能是您使用NSLog(@"%@", date); 记录您的日期。这将以 UTC 记录时间,即 +0000。如果您不住在使用 UTC 的国家/地区(例如英国、冰岛、加纳、葡萄牙……),这些日期似乎与您的预期不同。 (另见:https://***.com/a/4976950/457406)

如果您使用 NSDateComponents 创建日期,它会使用您当地的时区。根据您的本地时区,同一本地时间(例如 01:00)全年在 UTC 中具有不同的表示形式。也称为夏令时。

在您的实验中,您在 3 月底看到了这种变化。这是许多国家/地区开始夏令时的一年中的时间。例如在德国,它从 3 月 29 日星期日凌晨 2:00 开始。这将解释 3 月 30 日 1:00 日志中的更改。

长话短说,使用其他东西来记录您的日期。例如:

NSLog(@"%@", [NSDateFormatter localizedStringFromDate: combinedDate dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]);

【讨论】:

以上是关于NSDateComponents - 结合日期和时间会损失 1 小时?的主要内容,如果未能解决你的问题,请参考以下文章

NSDateComponents:如何将已弃用的 NSWeekCalendarUnit 替换为计算周开始日期?

NSDateComponents weekOfYear 返回错误的日期

使用 NSDateComponents 时无法返回目标日期

NSDateComponents : 查找超过 30 天

NSDateComponents 给出奇怪的结果

从 NSDateComponents 创建的 NSDate 不正确?