【问题标题】:Can't format time right无法正确格式化时间
【发布时间】:2019-05-15 14:47:10
【问题描述】:

我有以下方法,它将给定时间(以 UTC 为单位)作为参数,并以“更友好的格式”将其转换为当前时间。

有效/正常的输入可能是:'11:30' 或 '1:30' 我的问题是虽然我的设备中设置的时区是纽约(-4 GMT),甚至这个例子中的硬编码!此函数不断将时间转换为 -5 GMT(分别为上午 6:30 和晚上 8:30)

-(NSString*) convertServerTimeToAppTimeFormat:(NSString*) input {
NSDateFormatter *dateFormatInput = [[NSDateFormatter alloc] init];
[dateFormatInput setDateFormat:@"HH:mm"];
[dateFormatInput setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [dateFormatInput dateFromString:input];

NSDateFormatter *dateFormatInputOutput = [[NSDateFormatter alloc] init];
[dateFormatInputOutput setDateFormat:@"h:mm a"];
[dateFormatInputOutput setTimeZone: [NSTimeZone localTimeZone]];
[dateFormatInputOutput setTimeZone:[NSTimeZone timeZoneWithName:@"America/New_York"]];
return  [dateFormatInputOutput stringFromDate:date];
}

肯定有一些我没有看到的非常明显的东西。我通常会使用:

[NSTimeZone localTimeZone]

要获取我的用户所在的当前时区,而不是像我在这里所做的那样对其进行硬编码,但我认为硬编码版本应该有助于使错误更加明显。

【问题讨论】:

    标签: objective-c time nsdateformatter datetime-conversion


    【解决方案1】:

    问题在于,纽约是比 GMT/UTC 晚 4 小时还是 5 小时取决于您当前是否处于夏令时。我们目前处于“夏令时”时间,但在没有相反信息的情况下,日期格式化程序将假定日期为 2000 年 1 月 1 日,这不是夏令时。因此断开连接。

    但您可以将格式化程序的defaultDate 设置为今天:

    NSDate *today = [[NSCalendar currentCalendar] startOfDayForDate:[NSDate date]];
    [dateFormatInput setDefaultDate:today];
    

    以上将格式化程序默认为今天的日期。显然,如果您的输入有一个单独的字段来标识此时间与哪一天相关,那么就使用它。

    但是通过设置defaultDate,这将使仅时间字符串知道它是否应该应用夏令时,从而产生所需的时区转换。


    顺便说一句,我建议不要使用dateFormat 作为输出字符串。指定timeStyle,它将根据用户设备的设置对其进行适当的格式化:

    NSDateFormatter *dateFormatInputOutput = [[NSDateFormatter alloc] init];
    [dateFormatInputOutput setTimeStyle:NSDateFormatterShortStyle];
    return [dateFormatInputOutput stringFromDate:date];
    

    具体来说,如果用户将其设备配置为 24 小时制,则上述内容将尊重用户所指示的内容,而不是强制采用可能不符合他们喜好的格式。

    另外请注意,您不必强制使用时区或区域设置(除非您真的打算将其强制设置为 NY,即使用户在 CA 也是如此),因为它也将默认为用户设备的设置。这仅取决于您是否真的想将其强制到东部时区。


    如果您从 Web 服务中读取日期/时间字符串,您可能还需要根据 Technical Note 1480 指定一致的区域设置。从技术上讲,它是一个时间字符串,可能不需要,但这是一个很好的做法:

    [dateFormatInput setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
    

    【讨论】:

      【解决方案2】:

      当您只解析没有日期的时间时,重新调整的日期将为Jan 1, 2000。由于夏令时,今天您与 GMT 之间的偏移量可能与 1 月 1 日不同。您需要在代码中间添加一些额外的步骤以使其正确执行。

      我对 Objective-C 真的很生疏,所以我将总结一下您需要执行的步骤。我也可以快速发布解决方案,您认为这会有所帮助,因为它基本相同,只是语法不同。

      1. 保留从字符串创建date 的代码
      2. 创建一个Calendar,并将其时区设置为GMT
      3. 创建一个DateComponents,其中包含当前日期的年、月、日
      4. 创建一个DateComponents,它的小时,分​​钟从date
      5. 将两个DateComponents 组合在一起,编辑其中一个或新建一个
      6. 使用日历从组件中获取日期
      7. 使用您的 dateFormatInputOutput 格式化程序从该日期创建一个字符串

      【讨论】:

      • 谢谢你,你成功了!但我必须选择其他评论,因为他给了我所需的 sn-p。但你肯定完全搞定了,我在黑暗中度过了难关,txs!!
      • 是的,我不知道defaultDate,这样容易多了。
      猜你喜欢
      • 1970-01-01
      • 2022-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 2017-04-10
      • 1970-01-01
      相关资源
      最近更新 更多