【问题标题】:Why isn't my time zone being saved into my NSDate?为什么我的时区没有保存到我的 NSDate 中?
【发布时间】:2023-03-16 07:04:01
【问题描述】:

我必须在objective-c 中从NSString 初始化一个NSDate 对象。我是这样做的:

NSString *dateString = [[webSentence child:@"DateTime"].text stringByReplacingOccurrencesOfString:@"T" withString:@" "];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-mm-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Budapest"]];

NSDate *date = [[NSDate alloc] init];
date = [dateFormatter dateFromString:dateString];

例如:当我尝试使用字符串值 @"2011-01-02 17:49:54" 时,我得到一个 NSDate 2011-01-02 16:49:54 +0000。如您所见,这两个值之间存在一小时的差异。 NSDate 的值错误,它应该与我在 dateFormatter 中设置的时区中的字符串中定义的完全相同。即使我将其时区设置为“欧洲/布达佩斯”,它似乎也使用我将其定义为 UTC 的日期字符串。我该如何解决这个问题?

谢谢!

【问题讨论】:

    标签: objective-c timezone nsdate nsdateformatter


    【解决方案1】:

    NSDate 存储相对于标准参考日期的日期。来自类文档:

    “NSDate 的唯一原始方法 timeIntervalSinceReferenceDate 为 NSDate 接口中的所有其他方法提供了基础。此方法返回相对于绝对参考日期的时间值 - 格林威治标准时间 2001 年 1 月 1 日的第一个瞬间。”

    NSDate 本身没有任何时区概念。所以 NSDateFormatter 做了正确的事:它转换了一个你告诉它有 GMT 偏移量的日期(通过指定一个时区),并给你一个“标准化”的 NSDate 日期。

    如果您想查看以欧洲/布达佩斯时区表示的日期,请使用现有的日期格式化程序 (-stringFromDate:) 或适当的 NSDate 描述方法(例如 -descriptionWithCalendarFormat:timeZone:locale:)。

    P.S.- 你的代码中根本不需要 alloc/init 。在非 ARC 中,这将是一个泄漏。

    P.P.S.- 您的日期格式不正确并给出无意义的结果。我已经按照以下方式清理了您的代码(在 ARC 下测试):

    NSString *dateString = @"2011-09-02 17:49:54";
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSTimeZone *tz = [NSTimeZone timeZoneWithName:@"Europe/Budapest"];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dateFormatter setTimeZone:tz];
    
    NSDate *date = [dateFormatter dateFromString:dateString];
    NSLog(@"%@", [dateFormatter stringFromDate:date]);
    NSLog(@"%@", [date descriptionWithCalendarFormat:nil timeZone:tz locale:nil]);
    

    【讨论】:

    • 所以 NSdate 没有时区的概念。但它有GMT的概念吗?我不能将时区转换为 GMT 小时并将其添加到 NSDate 对象中吗?
    【解决方案2】:

    两件事:

    1) 您的日期格式字符串有错误。您应该使用 MM 表示月份,而不是 mm(小写 mm 表示分钟)

    2) 创建 NSDate 对象后,您需要使用 NSDateFormatter 方法stringFromDate: 生成本地化到特定时区的日期字符串。如果您只是在 NSDate 对象上直接执行 NSLog(),它将默认将日期显示为 GMT(GMT 比布达佩斯时间晚一小时)

    【讨论】:

    • 这意味着如果我有一个时区,我不能将日期存储到具有该时区的 NSDate 对象中?我必须将时区存储在其他地方并在显示时使用它?
    猜你喜欢
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多