objective-c - 假设使用公历,为什么将 86,400(一天)的时间间隔添加到日期永远不是答案?

标签 objective-c cocoa

我创建了一种方法来计算一周的第一天和最后一天,方法是将一天的时间间隔 (86,400) 添加到日期,再乘以所需的天数。

一位同事评论了“adding multiples of 86,400 is never the answer”。为什么会这样?

这是我创建的类别方法,我该如何改进它?

- (NSDate*)firstDayOfWeek
{
    return [self dateWithDaysAddedGivenDayOfWeek:@{
        @1 : @-6,
        @2 : @0,
        @3 : @-1,
        @4 : @-2,
        @5 : @-3,
        @6 : @-4,
        @7 : @-5
    }];
}

- (NSDate*)lastDayOfWeek
{
    return [self dateWithDaysAddedGivenDayOfWeek:@{
        @1 : @0,
        @2 : @6,
        @3 : @5,
        @4 : @4,
        @5 : @3,
        @6 : @2,
        @7 : @1
    }];
}

- (NSDate*)dateWithDaysAddedGivenDayOfWeek:(NSDictionary*)daysToAddGivenDay
{
    NSDateComponents* components = [[NSCalendar currentCalendar]
        components:NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit fromDate:self];

    NSInteger daysToAdd = [[daysToAddGivenDay objectForKey:@([components weekday])] integerValue];
    return [self dateByAddingTimeInterval:daysToAdd * 60 * 60 * 24];
}

我需要在一天中使用不同的时间间隔吗? (例如 23 小时 56 分 4.1 秒)

最佳答案

您不能假设天的长度相同。由于夏令时,它们可以是 23、24 或 25 小时。很容易想象,如果我们假设一天恰好是 24*60*60 秒长,可能会造成什么麻烦。

您的代码也可能有问题,因为在不同的国家和文化中,一周的第一天可能不同(星期日与星期一)。所以时间和日期的计算必须与日历和用户区域相关。这不是简单地通过数秒来完成的。

我们甚至还没有提到更令人讨厌的事情,例如闰秒、政客改变国家时区(普京统治下的俄罗斯、佛朗哥统治下的西类牙),甚至是跨过国际日期变更线(指的是萨摩亚——他们做了两次).

所以你应该相信框架的工具,在 WWDC2011: Performing Calendar Calculations 中有很好的解释。 .

对于您在问题中发布的代码,我会建议类似

NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDate *startOfTheWeek;
NSDate *endOfWeek;
NSTimeInterval interval;
[cal rangeOfUnit:NSWeekCalendarUnit 
       startDate:&startOfTheWeek 
        interval:&interval //<-- interval will hold the length of the time unit, 
         forDate:now];     //    here week, taking DST et al into account
//startOfWeek holds now the first day of the week, according to locale (monday vs. sunday)

endOfWeek = [startOfTheWeek dateByAddingTimeInterval:interval-1];
// holds 23:59:59 of last day in week.

在您的情况下,另一种选择是跳过 NSDate,因为它们不代表一天,而是代表一个特定的时刻,并与 NSDateComponents 一起使用。视频中也有说明。

关于objective-c - 假设使用公历,为什么将 86,400(一天)的时间间隔添加到日期永远不是答案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19826952/

相关文章:

objective-c - 如何查找用户点击了 NSBrowser 中的任何行?

objective-c - 如何在应用程序本身内存储 cocoa 应用程序的键值数据?

ios - “名称”不可用 : not available on iOS - XCode11

iphone - 检查蓝牙是否已启用?

iphone - Interface Builder 中的占位符对象

iphone - 如何让 UIDatePicker 显示特定日期?

ios - UIViewController的initWithNibName : a reason behind this design?

ios - 如何更改具有透明区域的UIIMAGE的色调?

ios - 使用 Objective C 和 GLKit 存储模型信息的数据结构

objective-c - iOS 5 中 NSDate 的 earlierDate 问题