【问题标题】:How can I completely ignore time zones in entire app?如何完全忽略整个应用程序中的时区?
【发布时间】:2016-04-25 14:49:33
【问题描述】:

我在某个特定应用中遇到了日期/时间问题。这是一个活动预订应用程序,我什至不想知道有时区之类的东西。无论用户当前位于何处,我都想要一次且只有一次。我不希望将时间转换为任何其他语言环境/时区。此应用程序中没有“本地”时间之类的东西,因为一切都基于您预订活动地点的时间。它需要始终在那个时间表达,而不是你现在所处的时间。因此,我真的不需要任何时区功能。

例如,您在纽约,并在 3 月 15 日晚上 10:30 在伦敦预订了活动/约会。现在,无论您是在纽约、伦敦还是世界上任何其他城市,那个事件仍然在 3 月 15 日晚上 10 点 30 分在伦敦举行。如果您正在洛斯卡沃斯度假,您不想知道您的活动是在洛斯卡沃斯时间下午 3:30。

在有人向我解释 NSDate 不包含时区数据之前,我已经完全意识到了这一点,而且这些信息对我来说毫无用处。 NSDate 可能没有时区信息,但日期会被转换数千次,每次转换都会考虑时区,这让我非常痛苦。我在 NSDate 上有大约 30 个扩展,试图确保它永远不会返回本地时间(尝试将所有内容保持在 UTC)。以为我已经成功了,但显然 DatePicker 有它自己的日期格式化程序,所以现在所有的日期选择器都搞砸了。

必须有一种相对简单的方式来处理这个问题。我尝试将所有内容都处理为 UTC 日期,从远程数据库到 Web 服务再到 iOS 应用程序中的所有内容,确保所有转换为/从字符串等转换为 UTC 格式。仍然没有太多的运气。我可以在几分钟内制作出精美的动画,但我已经与这些愚蠢的日期作斗争了好几个星期。

解决这个问题的最佳方法是什么?

  1. 一个时区中的所有内容(例如 UTC)
  2. 强制应用本地时区对所有人都相同?
  3. 在事件地点的时区存储时间,然后总是尝试根据该时区显示它?这听起来很复杂,但我担心这是我应该采取的方向,即使它有点矫枉过正。
  4. 每次触摸日期时创建日期格式化程序并重置区域设置?
  5. 其他?

【问题讨论】:

  • 看起来你只需要时区:-)
  • 你的问题正是你想要做的。忘记时区。如果您需要特定位置的日期,则只需在从字符串中提取日期时将该时区传递给日期格式化程序
  • 那么,日期选择器之类的东西呢?他们会自动将时间转换为您当前的时区。不涉及字符串或手动转换。我给它一个 NSDate 并且它总是显示错误的时间(我的时区的时间,而不是事件的时区)。
  • 我在日期选择器中更改了语言环境,但我仍然总是得到当地时间。

标签: ios swift datepicker timezone nsdateformatter


【解决方案1】:

事情就是这样。忽略应用中的两个操作以外的时区:

  1. 向用户显示日期/时间时。
  2. 从用户那里获取日期/时间时。

拥有NSDate 后,忘记时区的存在。按原样坚持NSDate。按原样使用NSDate 进行计算。从某种意义上说,这意味着一切都在 UTC 时间完成。这一切都是一致的。一切都很简单。

您只需在向用户显示这些日期或从用户那里获取这些日期时担心时区。就是这样。

如果您想要用户的区域时间,只需使用NSDateFormatter 及其默认时区即可显示或获取当地时间。

如果您想显示或获取特定事件的时间,请使用NSDateFormatter,并将其时区设置为事件的时区。

没有比这更复杂的了。

我认为这似乎总是更复杂,因为人们开始记录 NSDate 并看到看起来像是错误的时间,因为他们没有意识到 NSLog 的输出是 UTC 时间,而不是本地时间。

例如,您有一个UIDatePicker 用于伦敦的一个活动。将日期选择器的时区设置为伦敦时间。存储生成的NSDate。当您想向用户显示事件的时间时,请将NSDateFormatter 的时区设置为伦敦时间。然后,无论用户在哪里,它都会显示正确的伦敦时间。

【讨论】:

  • 谢谢。很好的解释。
  • 那么我该如何实现呢?将时区与每个日期一起存储在数据库中,将其检索回来并将时区与日期一起传递到实体类中?大多数人以什么格式存储时区? SecondsFromGMT 作为 Int?我是否需要担心夏令时的变化?您如何将日期存储在数据库中?在 UTC 中,或在日期的时区(您使用它存储的时区)中,还是您只是使用标准 ISO 格式以日期格式正确处理它?
  • 按原样存储所有日期(本质上是 GMT)。具体取决于您存储NSDate 的位置/方式。仅当您需要向用户显示 NSDate 时才考虑时区。
  • 这是最简单的部分。存储和 NSDates 不是问题。问题区域是“唯一担心”的部分。我有一个当地时间的日历,其中包含数百个事件,每个事件(理论上)都可能位于不同的时区。由于我必须在某个时候显示它们中的每一个,因此要使用所描述的方法完成此操作,对于每个日期值,我需要:a)找出事件位置的时区 b)通过网络传递时区服务 c) 在 mySQL 数据库中存储时区,在 Web 服务中检索时区,
  • “SecondsFromGMT”的存储存在一个问题 - 由于 DST 开始或关闭,这些秒数在未来日期或事件日期可能突然不同。除非您在事件的“那个日期”存储 SecondsFromGMT,否则您会发现人们哭着说他们的事件正在显示一个小时。通常最好存储“时区 ID”,并在该日期的运行时获取该时区的“SecondsFromGMT”,以防 SecondsFromGMT 发生变化(国家经常更改其 DST 规则 - 我知道。)
猜你喜欢
  • 1970-01-01
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 2016-02-09
  • 2015-02-10
  • 2019-11-06
  • 1970-01-01
相关资源
最近更新 更多