0

我正在使用这种方法将月份和年份转换为等于给定年份月份的最后一天的日期。

+ (NSDate*)endOfMonthDateForMonth:(int)month year:(int)year
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.year = year;
    comps.month = month;

    NSDate *monthYearDate = [calendar dateFromComponents:comps];

    // daysRange.length will contain the number of the last day of the endMonth:
    NSRange daysRange = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:monthYearDate];
    comps.day = daysRange.length;
    comps.hour = 0;
    comps.minute = 0;
    comps.second = 0;
    [comps setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    [calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    [calendar setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
    NSDate *endDate = [calendar dateFromComponents:comps];
    return endDate;
}

我希望日期的时间分量为 00:00:00,这就是为什么我将时区设置为 GMT 0 并将分钟、小时和秒的日期分量设置为 0。从该方法返回的日期是正确的并且具有从 00:00:00 开始的时间分量。

这就是我将日期保存到 Core Data 的方式:

NSDate *endDate = [IBEstPeriod endOfMonthDateForMonth:endMonth year:endCalYear];
[annualPeriod setEndDate:endDate];

在检索数据并将其 NSLogging 到调试器控制台后,我得到的日期类似于2008-12-30 23:00:00 +0000时间组件!= 0。

为什么现在组件发生了变化?它不应该停留在 00:00:00 吗?

我在这里写错了什么?

谢谢!!

4

2 回答 2

3

您只需要在创建日历后设置日历时区。

将此添加为函数的第二行:

calendar.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];

但是,更简单的方法是:

- (NSDate*)endOfMonthDateForMonth:(int)month year:(int)year
{
    NSCalendar *calendar    = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    calendar.timeZone       = [NSTimeZone timeZoneWithName:@"UTC"];

    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.year              = year;
    comps.month             = month+1;
    comps.day               = 0;

    NSDate *monthYearDate   = [calendar dateFromComponents:comps];
    return monthYearDate;
}

结果:

NSLog(@"%@",[self endOfMonthDateForMonth:12 year:2010]);
// Output: 2012-07-10 12:30:05.999 Testing App[16310:fb03] 2010-12-31 00:00:00 +0000

这通过将日期设置为下个月的“第 0”天来工作,这与本月的最后一天相同。(这与从下个月的第一天减去一天的作用相同。)请注意,这是因为允许comps“溢出”(或在本例中为“underflow”)并dateFromComponents:自动进行数学运算。

于 2012-07-10T16:07:17.473 回答
1

有两件事要看:

  1. comps在设置时间组件之前尝试设置时区。我还没有测试过,但是当你设置时区时,NSDateComponents 可能会调整小时以保持相对于 GMT 的相同时间。

  2. 看看当您从 Core Data 存储中读回日期时,您是如何解释日期的。

于 2012-07-10T15:37:12.497 回答