保存到plist时的NSDate行为

时间:2014-07-09 09:50:49

标签: ios nsdate plist nsdatecomponents nstimezone

我正在从[NSdate date]创建一个日期并将其保存到plist,以下是我创建日期的方式

- (void)applicationWillResignActive:(UIApplication *)application
{
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
   // [gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];


    NSDateComponents *weekdayComponents = [gregorian components:(NSDayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit  | NSMinuteCalendarUnit)fromDate:[NSDate date]];
    NSInteger day    = [weekdayComponents day];
    NSInteger month  = [weekdayComponents month]; 
    NSInteger year   = [weekdayComponents year];

    NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init];
    [timeZoneComps setDay:day];
    [timeZoneComps setMonth:month];
    [timeZoneComps setYear:year];
    [timeZoneComps setHour:00];
    [timeZoneComps setMinute:00];
    [timeZoneComps setSecond:01];    


    NSDate *date = [gregorian dateFromComponents:timeZoneComps];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"file.plist"];

    NSMutableDictionary *d = [NSMutableDictionary new];
    [d setObject:date forKey:@"my-date"];

    [d writeToFile:filePath atomically:YES];
}

我测试了几个案例

案例1:没有将时区设置为上面的NSCalendar对象格里高利(默认情况下它将占用本地时区)并将设备中的时区设置为印度,我将日期保存到plist,这就是我得到的

日期的NSLog显示 CurrentDate:2014-07-08 18:30:01 +0000

enter image description here

案例2:现在将设备时区设置为san jose USA

日期的NSLog显示 2014-07-09 07:00:01 +0000

enter image description here

案例3:将NSCalendar对象的时区,上面的格里高利设置为“UTC”,并将设备中的时区设置为印度,这是我在plist中得到的

日期的NSLog显示 2014-07-09 00:00:01 +0000

enter image description here

案例4:将设备时间设置为san jose USA

日期的NSLog显示 2014-07-09 00:00:01 +0000

enter image description here

任何人都可以向我解释在所有这些案件中发生的事情。

此致 兰吉特。

2 个答案:

答案 0 :(得分:3)

这是因为您处理NSDate的方式。将某些内容转换为NSDate后,您将丢失所有时区信息,当您将其写入plist时,它将写入您当前的时区,因为它将转换回串。因此,让我们一个接一个地浏览这些场景。

所有方案都遵循此流程 NSDate - > NSDateComponents - > NSDate - >串

1) NSDate:2014-07-09 XX:XX:XX IST - > NSDateComponents 2014-07-09 00:00:01 IST - > NSDate 2014-07-09 00:00:01 IST - > 09-Jul-2014 12:00:01 am

2) NSDate:2014-07-09 XX:XX:XX PST - > NSDateComponents 2014-07-09 00:00:01 PST - > NSDate 2014-07-09 12:30:01 IST - > 2014年7月9日12:30:01

3) NSDate:2014-07-09 XX:XX:XX UTC - > NSDateComponents:2014-07-09 00:00:01 UTC - > NSDate:2014-07-09 05:30:01 IST - > 09-Jul-2014 5:30:01 am

4) 与手动指定时区

时的3相同

请记住NSDate 不关心时区。这只是一个时间点。 2014-07-09 00:00:01 UTC 和2014-07-09 05:30:01 IST 同时完全条款NSDate(格林威治标准时间2001-01-01 00:00:00之前426556801秒)。它们在plist中不同的原因是因为您(隐式)选择NSDate的本地时间表示。如果您需要更多控制权,请使用NSDateFormatter

编辑来想一想你可以说结果应该是不同的,但是NSDate输出到plist的方式是专有的,所以它看起来像某些原因它保持使用印度标准时间。猜测可能包括您在设置时区之间没有杀死您的应用程序。

第二次编辑实际上,我对原始的plist持有什么感兴趣。您正在使用编辑器进行查看,并且在显示时可能会将其转换为 Mac 当地时间。

答案 1 :(得分:1)

NSDate表示绝对时间点,与时区无关。你所看到和记录的是NSDate 描述,这在不同情况下是相当随意的,并且根据Apple Docs <有用进行调试/ p>

  

该表示仅对调试有用。

     

有许多选项可以获取日期的格式化字符串   包括:日期格式化程序(请参阅NSDateFormatter和数据格式   指南)和NSDate方法descriptionWithLocale:,   dateWithCalendarFormat:timeZone:,和   descriptionWithCalendarFormat:时区:区域设置:

因此,您可以将NSDate存储为已存储,因为它与任何时区信息无关,并使用NSCalendarNSDateFormatter进行应用所需的所有转换。

相关问题