简体   繁体   English

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

[英]Swift Date function do not work as Expected

I am trying to find out the difference between two date in seconds using Swift 4.1. 我正在尝试使用Swift 4.1以秒为单位找出两个日期之间的差异。 This is the code I use, 这是我使用的代码

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

Function to generate date1 from 2018-10-09T18:19:00Z 从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
    }

The Date is always returning back an hour less than my current device time, so the calculation is not working as expected. 日期总是比我当前的设备时间少返回一个小时,因此计算无法按预期进行。 If my current device time is 16:34 the Date() function returns it back as 15:34. 如果我当前的设备时间是16:34,则Date()函数将其返回为15:34。

I have seen that Date() is returning back the time in UTC not based on my timezone. 我已经看到Date()返回的时间不是我的时区,而是UTC时间。

At the moment if I pass in a Date 09/10/2018 14:25:00 and the current device time is 09/10/2018 14:20:00 . 目前,如果我传递日期09/10/2018 14:25:00并且当前设备时间是09/10/2018 14:20:00 I am expecting this function to return a value 300 which is 60 * 5 minute difference between two dates . 我期望此函数返回的值300是两个日期之间相差60 * 5分钟

But I am getting back a value of 3900 which is because the date function returns the date as 但是我返回的值为3900 ,这是因为date函数将日期返回为

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

. So the duration will be 1 hour + the 300 second difference. 因此,持续时间将为1小时+ 300秒差。

Including a sample output from Xcode console, my device time when I executed this code was 2018-10-09 17:56:28.565423 包括来自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)

But I cant find a proper way to find the correct duration between two times based on my current time zone. 但是我找不到根据当前时区在两次之间找到正确持续时间的正确方法。 How can I do it? 我该怎么做?

The issue is not with the Date() returning wrong time. 问题不在于Date()返回错误的时间。 Date() always returns the current time, which is not really based on your (any other) local timezone. Date()始终返回当前时间,它并不是真正基于您(任何其他)本地时区的时间。

The problem seems to be with the dateFormatter that you are using to generate the Date object from the date string. 问题似乎与您用来从日期字符串生成Date对象的dateFormatter有关。

Please try using the following lines of code: 请尝试使用以下代码行:

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   

instead of: 代替:

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

The problem with the latter is that, you are specifying ' Z ' to be the zero-offset time zone (UTC). 后者的问题在于,您将“ Z ”指定为零偏移时区(UTC)。 So, the difference of 1 hour from UTC in your device is causing this offset. 因此,与设备中的UTC的1小时差异导致了这种偏移。

And, while passing in the date string, please make sure that you skip the 'Z' at the end (For example, it should be like 2018-10-09T18:19:00 ). 并且,在传递日期字符串时,请确保您在末尾跳过“ Z”(例如,应类似于2018-10-09T18:19:00 )。

The updated code should work good for you, and return the expected difference in seconds. 更新的代码应该对您有用,并以秒为单位返回预期的差异。

Since you are using a string that represents the current time in your time zone, try this instead: 由于您使用的是表示时区中当前时间的字符串,因此请尝试以下操作:

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

It uses this property and this method. 它使用属性和方法。

Or if you'd like to account for the time zone difference from UTC in dateFromString(stringDate:) : 或者,如果您想在dateFromString(stringDate:)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
}

Test 测试

I am in a UTC + 1h timezone: 我处于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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM