【问题标题】:Conversion of NSString to NSDate conversion - incorrect resultNSString 到 NSDate 转换的转换 - 结果不正确
【发布时间】:2013-12-07 20:52:15
【问题描述】:

简而言之,我计划通过将 +0800 应用于时区来更改时间并使其成为马来西亚时间的本地时间。

结果出乎意料:

-(NSDate *)departureDateTime
{
    NSDate *date = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
    NSDateComponents *components = [gregorian components: NSUIntegerMax fromDate: date];
    [components setHour: 7];
    [components setMinute: 59];
    [components setSecond: 17];

    NSDate *newDate = [gregorian dateFromComponents: components];

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-mm-dd HH:mm:ss Z"];
    [dateFormat setLocale:[NSLocale currentLocale]];


    NSString *newDateString = [NSString stringWithFormat:@"%@",newDate];
    NSString *maskString = [NSString stringWithFormat:@"%@", [newDateString substringToIndex:20]];
    NSString *append = [maskString stringByAppendingString:@"+0800"];
    NSLog(@"%@",append);


    NSDate *finalLocalDate = [dateFormat dateFromString:append];

    return finalLocalDate;
}

结果:

对于 NSLog 附加:2013-12-07 23:59:17 +0800

但 finalLocalDate :2013-01-07 15:59:17 +0000

【问题讨论】:

  • 您似乎没有在任何地方设置时区,因此所有日期转换都将根据当地时区。 NSDate 将始终以格林威治标准时间打印。
  • 顺便说一句,要格式化月份,请使用“MM”,而不是“mm”。

标签: ios objective-c cocoa-touch nsdate nsdateformatter


【解决方案1】:

用更短的解决方案找到了答案,所以我在这里发布以防将来对任何人有所帮助。

对于返回,问题是不同的时区,所以通过添加这一行

[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:(+0*3600) ] ];

我们将时区设置为系统时区,然后我们删除不必要的代码:

-(NSDate *)departureDateTime
{
    NSDate *date = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
    NSDateComponents *components = [gregorian components: NSUIntegerMax fromDate: date];

    [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:(+0*3600) ] ];
    [components setHour: 7];
    [components setMinute: 59];
    [components setSecond: 17];

    NSDate *newDate = [gregorian dateFromComponents: components];
    NSLog(@"%@",newDate);

    return newDate;
}

正确结果:2013-12-08 07:59:17 +0000

【讨论】:

  • 不清楚你在做什么,但如果 NSDate 是在当地时间打印,那么你做错了。 NSDate 应包含 GMT。
  • 事实上,您似乎将时区设置为 GMT --(+0*3600) 为零 -- 因此您没有得到任何时区校正。 (这几乎肯定不是你想要的。)
  • @HotLicks 每次我得到 NSDate 的结果时,它与我的系统时间(马来西亚)不同 -8 小时。这是什么原因?
  • 因为 NSDate(几乎)总是在 GMT 中。这就是它的意图。当您使用 NSDateFormatter 和 NSCalendar 设置/显示时区时,您会更改时区。但是使用这些不会(或者至少不应该,如果做得正确的话)会影响您在 NSLog 一个 NSDate 对象时看到的内容——它始终是格林威治标准时间。
【解决方案2】:

试试这个:

NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSDate *malaysianTime = [NSDate dateWithTimeIntervalSince1970:now+(8*60*60)]; //8h in seconds

【讨论】:

    【解决方案3】:

    如果您的计算机在正确的时区运行,请不要设置时区。

    创建您的 newDate 值,然后 --

    NSDateFormatter* fmt = [[NSDateFormatter alloc] init];
    [fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSString* printableDate = [fmt stringFromDate:newDate];
    
    NSLog(@"The date is %@", printableDate);
    

    仅当所需的时区不是您的计算机/手机当前使用的时区时才设置时区(在 NSCalendar 和 NSDateFormatter 中)。

    请注意,如果您直接使用 NSLog newDate,它将在 GMT 时区打印。这就是它应该的方式——你总是使用 NSDateFormatter 作为可打印的日期。当您直接 NSLog 一个 NSDate 时,您会根据设计获得 GMT。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 2012-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多