从NSDate对象获取UTC时间和本地时间

时间:2014-07-23 17:51:11

标签: ios objective-c swift nsdate

在objective-c中,以下代码使用date API生成UTC日期时间信息。

NSDate *currentUTCDate = [NSDate date]

然而,在斯威夫特,

let date = NSDate.date()

导致当地日期和时间。

我有两个问题:

  1. 如何在date个对象中获取UTC时间和当地时间(NSDate给出当地时间)。
  2. 如何从NSDate对象获得精确秒数。
  3. 编辑1:感谢所有输入,但我不是在寻找NSDateFormatter个对象或字符串值。我只是在寻找NSDate对象(但是我们会对它们进行烹饪,但这是要求)。
    见第1点。

10 个答案:

答案 0 :(得分:60)

NSDate没有时区的特定时间点。将其视为自参考日期以来经过的秒数。自特定参考日期以来,一个时区与另一个时区相比过了多少秒? 答案是一样的。

根据您输出该日期的方式(包括查看调试器),您可能会在不同的时区获得答案。

如果它们在同一时刻运行,它们的值是相同的。它们既是参考日期以来的秒数,也可以是输出格式化为UTC或本地时间。在日期变量中,它们都是UTC。

目标-C:

NSDate *UTCDate = [NSDate date]

夫特:

let UTCDate = NSDate.date()

为了解释这一点,我们可以在游乐场中使用NSDateFormatter:

import UIKit

let date = NSDate.date()
    // "Jul 23, 2014, 11:01 AM" <-- looks local without seconds. But:

var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZoneStr = formatter.stringFromDate(date)
    // "2014-07-23 11:01:35 -0700" <-- same date, local, but with seconds
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.stringFromDate(date)
    // "2014-07-23 18:01:41 +0000" <-- same date, now in UTC

日期输出各不相同,但日期不变。这正是你所说的。没有本地NSDate这样的东西。

至于如何获得微秒,你可以使用它(把它放在同一个游乐场的底部):

let seconds = date.timeIntervalSince1970
let microseconds = Int(seconds * 1000) % 1000 // chops off seconds

要比较两个日期,您可以使用date.compare(otherDate)

答案 1 :(得分:40)

Xcode 9•Swift 4 (也适用于Swift 3.x)

extension Formatter {
    // create static date formatters for your date representations
    static let preciseLocalTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "HH:mm:ss.SSS"
        return formatter
    }()
    static let preciseGMTTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = "HH:mm:ss.SSS"
        return formatter
    }()
}

extension Date {
    // you can create a read-only computed property to return just the nanoseconds from your date time
    var nanosecond: Int { return Calendar.current.component(.nanosecond,  from: self)   }
    // the same for your local time
    var preciseLocalTime: String {
        return Formatter.preciseLocalTime.string(for: self) ?? ""
    }
    // or GMT time
    var preciseGMTTime: String {
        return Formatter.preciseGMTTime.string(for: self) ?? ""
    }
}

游乐场测试

Date().preciseLocalTime // "09:13:17.385"  GMT-3
Date().preciseGMTTime   // "12:13:17.386"  GMT
Date().nanosecond       // 386268973

这可能有助于您格式化日期:

enter image description here

答案 2 :(得分:27)

文档说明date方法会将新日期设置为当前日期和时间,无论使用何种语言。

问题可能出在您使用NSDateFormatter呈现日期的地方。 NSDate只是时间轴上的一点。在谈论NSDate时没有时区。我做了一个测试。

夫特

print(NSDate())

输出:2014-07-23 17:56:45 +0000

目标C

NSLog(@"%@", [NSDate date]);

输出:2014-07-23 17:58:15 +0000

结果 - 没有区别。

答案 3 :(得分:22)

日期独立于任何时区,使用Dateformatter并附加时区进行显示:

迅速:

let date = NSDate()
let dateFormatter = NSDateFormatter()
let timeZone = NSTimeZone(name: "UTC")

dateFormatter.timeZone = timeZone

println(dateFormatter.stringFromDate(date))

objC:

NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];

[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:timeZone];       
NSLog(@"%@", [dateFormatter stringFromDate:date]);

答案 4 :(得分:17)

let date = Date() 
print(date) // printed date is UTC 
  

如果您使用 playground ,请使用print语句检查时间。游乐场显示当地时间,直到您打印它。不要依赖操场的右侧面板。   enter image description here

此代码以UTC格式提供日期。如果您需要当地时间,则应将以下时区扩展为Timezone.current

 extension Date {

   var currentUTCTimeZoneDate: String {
        let formatter = DateFormatter()
        formatter.timeZone = TimeZone(identifier: "UTC")
        formatter.amSymbol = "AM"
        formatter.pmSymbol = "PM"
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

        return formatter.string(from: self)
    }
}

对于UTC时间,请使用它:Date().currentUTCTimeZoneDate

答案 5 :(得分:12)

目前(对Swift进行了最新更改),NSDate.date()不再可用。

相反,您只需初始化NSDate即可获得当前日期和时间 试一试,在操场上:

var d = NSDate()
d

你会得到:

Oct 22, 2014, 12:20 PM"  

答案 6 :(得分:7)

Swift 3

您可以根据UTC当前时区获取日期

extension Date {
    func currentTimeZoneDate() -> String {
        let dtf = DateFormatter()
        dtf.timeZone = TimeZone.current
        dtf.dateFormat = "yyyy-MM-dd HH:mm:ss"

        return dtf.string(from: self)
    }
}

这样打电话:

Date().currentTimeZoneDate()

答案 7 :(得分:4)

我的Xcode版本6.1.1(6A2008a)

在游乐场,测试如下:

// I'm in East Timezone 8
let x = NSDate() //Output:"Dec 29, 2014, 11:37 AM"
let y = NSDate.init() //Output:"Dec 29, 2014, 11:37 AM"
println(x) //Output:"2014-12-29 03:37:24 +0000"


// seconds since 2001
x.hash //Output:441,517,044
x.hashValue //Output:441,517,044
x.timeIntervalSinceReferenceDate //Output:441,517,044.875367

// seconds since 1970
x.timeIntervalSince1970 //Output:1,419,824,244.87537

答案 8 :(得分:1)

我找到了一种在Swift4中获取UTC的简便方法。将此代码放在游乐场

let date = Date() 
*//"Mar 15, 2018 at 4:01 PM"*

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let newDate = dateFormatter.string(from: date) 
*//"2018-03-15 21:05:04 +0000"*

答案 9 :(得分:0)

除了其他答案外,您还可以编写Date类的扩展名,以获取特定TimeZone中的格式化数据,使其成为实用程序功能,以备将来使用。喜欢

 extension Date {

 func dateInTimeZone(timeZoneIdentifier: String, dateFormat: String) -> String  {
 let dtf = DateFormatter()
 dtf.timeZone = TimeZone(identifier: timeZoneIdentifier)
 dtf.dateFormat = dateFormat

 return dtf.string(from: self)
 }
}

现在您可以这样称呼

 Date().dateInTimeZone(timeZoneIdentifier: "UTC", dateFormat: "yyyy-MM-dd HH:mm:ss");