【问题标题】:Why does stringFromDate NSString still have GMT time even though I set timezone on the NSDateFormatter?即使我在 NSDateFormatter 上设置了时区,为什么 stringFromDate NSString 仍然有 GMT 时间?
【发布时间】:2014-05-07 21:48:41
【问题描述】:

实际 NSDate 对象 (firstTime) 的输出是我想要的(iOS 设备的时间)。即使我设置了日期格式化程序(df ) 到本地时区。为什么它不起作用?

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"HH:mm:ss"];
[df setTimeZone:[NSTimeZone localTimeZone]];

NSDate *firstTime = [NSDate dateWithTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT] sinceDate:[NSDate date]];
NSLog(@"%@", firstTime);
NSString *secondTime = [df stringFromDate:firstTime];
NSLog(@"%@", secondTime);

输出:

第一次:2014-05-07 17:41:29 +0000,第二次:13:41:29

【问题讨论】:

  • 那些可能是同一时间...第一次输出时区第二次不输出
  • 好吧,你破坏了 NSDate 对象中的时间。由于您从 NSDate 对象派生日期字符串,它也会被损坏。
  • (提示:不要试图“更正” NSDate 的时区。它会自动在 GMT 中。)
  • [dateTime description]NSLog,始终将时间报告为 GMT。在我看来,一切都按预期工作(假设您的时区是 GMT-4,EDT)
  • 你好。我以什么方式“破坏”了 NSDate 对象?我正在尝试获取在第一次之后显示的同一日期的 NSString:。如果我在创建 firstTime 时不更改 NSTimeZone,它将出现在 GMT 时间。我要做的就是将我从 NSLogging firstTime 获得的确切输出转换为 NSString,因此当我输出该 NSString 时,它将是相同的。另外,我看到有人发布说 NSDateFormatter 默认情况下将时区设置为本地时区,并且明确设置它是多余的。真的吗?我再也看不到他的帖子了。

标签: ios objective-c


【解决方案1】:

应该让NSDate 捕获真正的日期/时间,而不尝试执行任何时区调整,然后让NSDateFormatter 格式化字符串,以便它在所需的时区中表示。

所以,看看你的代码:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"HH:mm:ss"];
[df setTimeZone:[NSTimeZone localTimeZone]];

没关系,虽然不需要将时区设置为本地时区。日期格式化程序默认为当前时区。

但随后您继续尝试获取当前时间并进行调整:

NSDate *firstTime = [NSDate dateWithTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT] sinceDate:[NSDate date]];
NSLog(@"%@", firstTime);

虽然我理解您为何尝试这样做,但这是不正确的。不应执行时区调整。所以,firstTime 的赋值应该是:

NSDate *firstTime = [NSDate date];
NSLog(@"%@", firstTime);

因此,如果您在下午 5:41(东部时间)执行此操作,则此 NSLog 现在将报告 2014-05-07 21:41:29 +0000,但这是正确的(因为 +0000 表示它向您显示 UTC/GMT/Zulu 的时间)。

然后,如果您想在本地时区显示它,您可以使用这个未经调整的 [NSDate date] 并将其与您的格式化程序一起使用,就像您在问题中所做的那样:

NSString *secondTime = [df stringFromDate:firstTime];
NSLog(@"%@", secondTime);

然后会像您预期的那样报告17:41:29

【讨论】:

    【解决方案2】:

    NSDate 没有时区。读五遍,直到你理解为止。

    这个:

    [NSDate date]
    

    返回表示现在的日期。它没有时区。它不在格林威治标准时间或任何其他时区。它没有一个。你的代码:

    [NSDate dateWithTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT] sinceDate:[NSDate date]];
    

    表示现在不适用于 GMT 以外的任何用户的时间。我再说一遍:你的NSDate 现在没有描述。这就像坐在旧金山,看着设置在正确当地时间的手表,它显示 12:00,然后告诉所有人“这意味着现在是凌晨 4 点,因为我们比格林威治标准时间晚 8 小时”。

    结果:

    [df stringFromDate:firstTime]
    

    将构建一个字符串来显示一个不是现在的时间。

    不要再认为自己比在 Apple 工作过的所有人都聪明,试试这个:

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    [df setDateFormat:@"HH:mm:ss"];
    [df setTimeZone:[NSTimeZone localTimeZone]];
    
    NSString *secondTime = [df stringFromDate:[NSDate date]];
    NSLog(@"%@", secondTime);
    

    也就是说“给我一个本地时区的‘现在’字符串”。告诉我:它输出正确的东西吗?

    【讨论】:

    • 可能发生在第 100 万篇有人不理解 NSDate 的帖子之后。
    • Unicode 和日历计算。如果计算机科学学校在这些上花更多的时间……我能感觉到你的痛苦。人们对这些主题做出假设是因为他们不知道自己需要了解多少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    相关资源
    最近更新 更多