【问题标题】:iOS: Add timezone without changing/converting the time valueiOS:添加时区而不更改/转换时间值
【发布时间】:2019-06-19 22:01:21
【问题描述】:

您好,需要时区方面的帮助,我需要在不更改时间戳的情况下更改它,如下所示: “2019-01-25T11:55:00+00:00”->“2019-01-25T11:55:00-08:00”

这是我得到的: “2019-01-25T11:55:00+00:00”时间戳,00:00 不正确,我需要将其更改为特定时区,例如 -08:00 以获取“2019-01-25T11: 55:00-08:00"

我正在使用具有以下日期格式的 dateFormatter:“yyyy-MM-dd'T'HH:mm:ssZ” 尝试通过 dateComponents 解耦整个时间戳并在添加 tz 之后再次重建它,但时间也发生了变化(

提前致谢。

【问题讨论】:

  • 您是否可能误解了它的工作原理? "2019-01-25T11:55:00+00:00" 之类的时间戳特别表示它发生在 UTC 时区的 11:55:00。 -08:00 时区的同一时刻是 3:55:00,而不是 11:50:00。为什么要更改时区但保持相同的时间?这似乎是错误的。
  • 我得到 timestamp: "2019-01-25T11:55:00+00:00" 和 timeZone 分别为 "America/Los_Angeles",所以这个 11:55 已经在那个时区了,我只是需要将时间戳中的 +00:00 替换为正确的
  • 您将时区标​​识符作为一个字符串与明确说明它位于 UTC 时区的时间戳分开,这真的很奇怪。因此,您的目标是忽略时间戳中指定的时区,并使用单独提供给您的其他时区,对吗?
  • @rmaddy,如果我不得不猜测,我会说它就像一个写得很糟糕的 JSON API,我必须使用一次,其中 API 返回的时间戳没有服务器本地时间的时区,并且然后在解析时,接收方将缺少时区解析为 UTC,现在他试图告诉 Swift 实际上时区不是 UTC,而是 America/Los_Angeles。
  • @Kirill 如果我在最后一个陈述中完全正确,我会说尽你最大的努力让你的 API 被更改以返回带有明确指示时区的 UTC 时间戳。

标签: ios date nsdate


【解决方案1】:

鉴于您需要忽略时间戳字符串中提供的时区并将其替换为时区标识符,您可以使用如下代码:

let timezone = "America/Los_Angeles"
let timestamp = "2019-01-25T11:55:00+00:00"

let df = DateFormatter()
df.timeZone = TimeZone(identifier: timezone)
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

let date = df.date(from: String(timestamp.dropLast(6)))

这会使用附加时区设置日期格式化程序,同时解析没有任何时区的时间戳(使用 dropLast(6) 删除)。

此代码为您提供 Date,代表 2019 年 1 月 25 日洛杉矶时区的 11:55:00。请记住,如果您只是打印date,它将以UTC 显示日期。这只是打印Date 的输出。

请注意,实际正确的解决方案是从 API 获取具有正确时区的时间戳字符串。您不必像这样跳过箍来获得正确的时间戳。

【讨论】:

  • 可靠的解决方法。 +1 表示 API 一开始就应该做好。
  • @rmaddy 谢谢你,是的,我同意 API 应该纠正的观点。
【解决方案2】:

所以在这里我结束了

日期:

extension Date {
  public func dateWithAdjusted(timeZone: String, date: String) -> String {
    let timeZoneIdentifier = TimeZone(identifier: timeZone)?.identifier

    guard let timezoneId = timeZoneIdentifier else { return "" }
    let timeZoneOffset = TimeZone.getOffset(from: timezoneId)

    let regex = try! NSRegularExpression(pattern: "([+-])([0-9]{2}[:]{1}[0-9]{2})", options: .caseInsensitive)
    let range = NSMakeRange(0,date.count)
    let newTimeStamp = regex.stringByReplacingMatches(in: date, options: [], range: range, withTemplate: timeZoneOffset)

    return newTimeStamp
  }

和时区:

extension TimeZone {
  public static func getOffset(from identifier: String) -> String {
    let timeZone = TimeZone(identifier: identifier)

    guard let tz = timeZone else { return getOffset(from: TimeZone.current.identifier ) }

    let seconds = tz.secondsFromGMT()
    let hours = seconds/3600
    let minutes = abs(seconds/60) % 60

    let timeZoneOffset = String(format: "%+.2d:%.2d", hours, minutes)

    return timeZoneOffset
  }
let adjustedTimestamp = Date().dateWithAdjusted(timeZone:"America/New_York", date: "2019-01-26T02:55:00+00:00")

Output: "2019-01-26T02:55:00-05:00" 

【讨论】:

    猜你喜欢
    • 2021-02-10
    • 2013-05-24
    • 1970-01-01
    • 2020-12-14
    • 2011-02-21
    • 2013-09-21
    • 2022-11-01
    • 2016-01-30
    • 2019-08-06
    相关资源
    最近更新 更多