Objective c 从核心数据检索NSDate时出现时区问题
我使用这种方法将一个月和一年转换为一个日期,该日期等于给定月份的最后一天Objective c 从核心数据检索NSDate时出现时区问题,objective-c,ios,ios5,nsdate,nsdatecomponents,Objective C,Ios,Ios5,Nsdate,Nsdatecomponents,我使用这种方法将一个月和一年转换为一个日期,该日期等于给定月份的最后一天 + (NSDate*)endOfMonthDateForMonth:(int)month year:(int)year { NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *comps = [[NSDateComponents alloc]
+ (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的时间成分
以下是我将日期保存到核心数据的方式:
NSDate *endDate = [IBEstPeriod endOfMonthDateForMonth:endMonth year:endCalYear];
[annualPeriod setEndDate:endDate];
在检索数据并将其记录到调试器控制台之后,我得到了日期,比如带有时间组件的2008-12-30 23:00:00+0000
0.
为什么现在组件发生了变化?
它不应该停留在00:00吗
我这里的代码错了什么
谢谢 要看两件事:
comps
设置时区。我还没有测试过,但可能是在设置时区时,NSDateComponents会调整小时以保持与GMT相同的时间comps
设置时区。我还没有测试过,但可能是在设置时区时,NSDateComponents会调整小时以保持与GMT相同的时间创建日历后,只需设置日历时区 将此添加为函数的第二行:
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”天来实现的,该天与本月的最后一天相同。(这与从下个月的第一天减去一天是一样的。)请注意,这是有效的,因为comp允许“溢出”(或者在本例中是“下溢”)和
dateFromComponents:
自动进行计算。创建日历后,只需设置日历时区
将此添加为函数的第二行:
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”天来实现的,该天与本月的最后一天相同。(这与从下个月的第一天减去一天是一样的。)注意,这是有效的,因为comp允许“溢出”(或者在本例中是“下溢”)和
dateFromComponents:
自动进行计算。谢谢你的帮助,Caleb!!我尝试了你的建议,可惜没有成功。关于2:我只记录日期,根本没有转换。在读取时,核心数据中存储的日期似乎正在我当前的时区中转换(我基于GMT+2:00)。我怎样才能避免这种转换,它实际上改变了一天?我不关心时间成分,我只需要日期,它必须在所有时区保持不变。NSDate存储日期信息,不受时区的影响。要理解NSDate,您应该使用日期格式化程序来显示日期,以便自己指定时区。我怀疑当您记录日期时,NSDate的-description
方法可能使用当前时区,但日期本身不会更改(日期是不可变的)。因此,如果您想以GMT显示日期,请再次使用日期格式化程序。我不确定NSDate的-description方法是否真的使用了当前时区,因为我使用类似的代码生成NSDate:NSDateFormatter*dateFormatter=[[NSDateFormatter alloc]init];[dateFormatter setLocale:[NSLocale alloc]initWithLocaleIdentifier:@“en_US_POSIX”];[日期格式化程序setDateFormat:@“yyy MM dd”];[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];NSDate*date=[dateFormatter dateFromString:[csvLineItems对象索引:0]]代码>从字符串中解析。。。。在这种情况下,我总是得到正确的值,如2002-04-03 00:00:00+0000。我尝试了相同的方法(字符串解析)而不是上面显示的代码,但仍然存在相同的问题。正如Caleb所说,NSDate始终存储在GMT中,但日历/日期格式化程序操作将在创建或格式化它们时转换为/转换为它们设置的时区。感谢您的帮助,Caleb!!我尝试了你的建议,可惜没有成功。关于2:我只记录日期,根本没有转换。在读取时,核心数据中存储的日期似乎正在我当前的时区中转换(我基于GMT+2:00)。我怎样才能避免这种转换,它实际上改变了一天?我不关心时间成分,我只需要日期,它必须在所有时区保持不变。NSDate存储日期信息,不受时区的影响。要理解NSDate,您应该使用日期格式化程序来显示日期,以便自己指定时区。我怀疑当您记录日期时,NSDate的-description
方法可能使用当前时区,但日期本身不会更改(日期是不可变的)。因此,如果您想以GMT显示日期,请再次使用日期格式化程序。我不确定NSDate的-description方法是否真的使用了当前时区,因为我使用类似的代码生成NSDate:NSDateFormatter*dateFormatter=[[NSDateFormatter alloc]init];[dateFormatter setLocale:[NSLocale alloc]initWithLocaleIdentifier:@“en_US_POSIX”];[日期格式化程序setDateFormat:@“yyy MM dd”];[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];NSDate*date=[dateFormatter dateFromString:[csvLineItems对象索引:0]]代码>从字符串中解析。。。。在这种情况下,我总是得到正确的值,如2002-04-03 00:00:00+0000。我在instea中尝试了相同的方法(字符串解析)