快速日期功能无法按预期工作

时间:2018-10-09 16:36:17

标签: swift swiftdate

我正在尝试使用Swift 4.1以秒为单位找出两个日期之间的差异。这是我使用的代码,

func getDurationInSeconds(date1 :Date) -> Int{
    guard let durationInSeconds = Calendar.current.dateComponents([.second], from: Date(), to: date1).second else {
            return 0
    }
    return durationInSeconds
}

从2018-10-09T18:19:00Z生成date1的函数

func dateFromString(stringDate:String) -> Date? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
        dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale?
        let date = dateFormatter.date(from: stringDate)
        return date
    }

日期总是比我当前的设备时间少一个小时返回,因此计算无法按预期进行。如果我当前的设备时间是16:34,则Date()函数将其返回为15:34。

我已经看到Date()返回的是UTC时间,而不是基于我的时区。

如果我输入日期 2018/10/9 14:25:00 ,当前设备时间为 2018/10/9 14:20:00 。我期望此函数返回值 300,这是两个日期之间的差值* 60 * 5分钟

但是我返回的值是 3900 ,这是因为date函数将日期返回为

  

09/10/2018 13:20:00而不是14:20

。因此,持续时间将为1小时+ 300秒差异。

包括来自Xcode控制台的示例输出,我执行此代码时的设备时间为 2018-10-09 17:56:28.565423

(lldb) po date1
▿ 2018-10-09 17:59:00 +0000
  - timeIntervalSinceReferenceDate : 560800740.0

(lldb) po durationInSeconds
3731

(lldb) po Date()
▿ 2018-10-09 16:57:04 +0000
  - timeIntervalSinceReferenceDate : 560797024.35021996

(lldb)

但是我找不到根据当前时区在两次之间找到正确持续时间的正确方法。我该怎么办?

2 个答案:

答案 0 :(得分:0)

问题不是 Date()返回错误的时间。 Date()始终返回当前时间,这并不是真正基于您(任何其他)本地时区的时间。

问题似乎出在您使用 dateFormatter 从日期字符串生成 Date 对象。

请尝试使用以下代码行:

dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

// Not necessary as the dateFormatter would take the device's timeZone to be the default.
dateFormatter.timeZone = Calendar.current.timeZone   

代替:

dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

后者的问题在于,您将“ Z ”指定为零偏移时区(UTC)。因此,您的设备与UTC的1小时之差造成了这种偏移。

此外,在传递日期字符串时,请确保您在末尾跳过“ Z”(例如,应类似于 2018-10-09T18:19:00

更新后的代码应该对您有用,并以秒为单位返回预期的差异。

答案 1 :(得分:-2)

由于您使用的字符串代表了您所在时区的当前时间,因此请尝试以下操作:

func getDurationInSeconds(date1: Date) -> Int {
    return Int(-date1.timeIntervalSinceNow + TimeZone.current.daylightSavingTimeOffset(for: date1))
}

它使用this属性和this方法。

或者,如果您想在dateFromString(stringDate:)中考虑与UTC的时区差异:

func getDurationInSeconds(date1: Date) -> Int {
    return Int(-date1.timeIntervalSinceNow)
}

func dateFromString(stringDate:String) -> Date? {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    let date = dateFormatter.date(from: stringDate)! //I am force-unwrapping for brevity
    let adjustedDate = date.addingTimeInterval(-TimeZone.current.daylightSavingTimeOffset(for: date))
    return adjustedDate
}

测试

我处于UTC + 1h时区:

let str = "2018-10-09T19:50:00Z"    //"2018-10-09T19:50:00Z"
let date1 = dateFromString(stringDate: str)! //"Oct 9, 2018 at 7:50 PM"
Date()         //At the time of testing this it is "Oct 9, 2018 at 7:53 PM"
getDurationInSeconds(date1: date1)  //213, which is 3 minutes and 33 seconds