objective-c - 从 Core Data 检索 NSDate 时的时区问题

标签 objective-c ios ios5 nsdate nsdatecomponents

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

+ (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吗?

我在这里写错了什么?

谢谢!!

最佳答案

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

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

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“溢出”(或在本例中为“下溢”)和 dateFromComponents:自动计算。

关于objective-c - 从 Core Data 检索 NSDate 时的时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11416659/

相关文章:

objective-c - 将十六进制颜色代码转换为 NSColor

objective-c - Objective-C 类可以符合 swift 协议(protocol)吗?

ios - 使用 NSURLConnection 获取 302 HTTP 重定向的响应主体

苹果手机 : using Background location services is stopped after a little time

ios5 - 如何在iOS 5应用中更改亮度?

iphone - 从 ACAccountStore 打开 Twitter 设置 (iOS 5.1 TWITTER)

objective-c - Retina "@2x"图形在标准清晰度显示器上错误使用(使用 Snow Leopard/Xcode 4.2 )

iphone - 选择 UITableViewCell 导航到新的 DetailViewController

iOS:在两个动画 View 之间画线

iphone - EKEventStore removeEvent EKErrorDomain 代码=11 EKErrorObjectBelongsToDifferentStore