4

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

一位同事评论说“添加 86,400 的倍数永远不是答案”。为什么会这样?

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

- (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 秒)

4

2 回答 2

7

你不能假设天的长度是一样的。由于夏令时,它们可以是 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 一起使用。视频中也有解释。

于 2013-11-07T03:10:56.513 回答
4

由于多种因素(闰秒、夏令时等),您无法预测一天中有多少秒。相反,您应该让系统在 NSCalendar 上使用此方法为您处理此问题:

- (NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts

通过将日期设置为正数或负数,您可以从给定日期准确地增加或减少天数。

于 2013-11-07T02:45:00.247 回答