Swift - 获取本地日期和时间

Swift - Get local date and time

如何获取 Swift 中的本地日期和时间?

let last_login = String(NSDate.date())

使用 NSDateFormatter,或者通过设置格式

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "hh:mm"
println(dateFormatter.stringFromDate(NSDate()))

或样式

dateFormatter.dateStyle = .NoStyle
dateFormatter.timeStyle = .MediumStyle

你必须使用 NSDateFormatter

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMMM dd, yyyy HH:mm"
dateFormatter.locale = "en" // Change "en" to change the default locale if you want  
let stringDate = dateFormatter.stringFromDate(date)

更新:Xcode 8.2.1 • Swift 3.0.2

您还可以使用 Date 方法 description(with locale: Locale?) 获取用户的本地化时间描述:

A string representation of the Date, using the given locale, or if the locale argument is nil, in the international format YYYY-MM-DD HH:MM:SS ±HHMM, where ±HHMM represents the time zone offset in hours and minutes from UTC (for example, “2001-03-24 10:45:32 +0600”).

description(with locale: Locale?)

Date().description(with: .current)   // "Monday, February 9, 2015 at 05:47:51 Brasilia Summer Time"

上面的方法不适合在向用户显示日期和时间时使用。它仅用于调试目的。

向用户显示本地日期和时间(当前时区)时,您应该尊重用户的区域设置和设备设置。您唯一可以控制的是日期和时间样式(短、中、长或完整)。有关更多信息,您可以查看此 post shortDateTime.

如果您打算为编码目的创建一个时间戳 UTC (iso8601),您可以检查这个 post

我已经找到答案了。

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy HH:mm"
let dateInFormat = dateFormatter.stringFromDate(NSDate())
let expiryDate: Date = ...
let localizedDateString = DateFormatter.localizedString(from: expiryDate, dateStyle: .medium, timeStyle: .short)

“2017 年 9 月 10 日,14:37”

Leo 的回答很棒。我只是想添加一种方法将其用作计算 属性.

 var currentTime: String { 
     Date().description(with: .current) 
 }

像这样使用它:

print(currentTime)

或者封装起来:

extension String { 
    static var currentTime: String { 
        Date().description(with: .current) 
    }
}

然后你可以在任何你使用字符串的地方使用它:

var time: String = .currentTime

Swift 4

获取当前日期和时间

let currentDate = Date()
print(currentDate) //this will return current date and time 

但是将日期类型转换为字符串

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm" //give the formate according to your need
let dateStr =  dateFormatter.string(from: currentDate) //which will give the string of current date and time in required dateformate

获取最常见的字符串格式(在处理查询和数据库时):

Swift 4, 5

2019-01-09T01:07:04Z(GMT/Zulu 时间的 RFC3339)

let f = ISO8601DateFormatter()
f.formatOptions = [.withInternetDateTime]
let s = f.string(from: Date())

2019-01-08T17:04:16-08:00(RFC3339占本地时区)

let f = ISO8601DateFormatter()
f.formatOptions = [.withInternetDateTime]
f.timeZone = TimeZone.current
let s = f.string(from: Date())

2019-01-09(GMT/Zulu 时间的标准日期戳)

let f = ISO8601DateFormatter()
f.formatOptions = [.withFullDate, .withDashSeparatorInDate]
let s = f.string(from: Date())

2019-01-08(当地时区的标准日期戳)

let f = ISO8601DateFormatter()
f.formatOptions = [.withFullDate, .withDashSeparatorInDate]
f.timeZone = TimeZone.current
let s = f.string(from: Date())

所有四个字符串表示完全相同的时间点。请记住,按字母顺序对这些字符串进行排序也会将它们按时间顺序排序,这使得该数据数据库不可知(我一直以此为目标)。

如果您想获得 日期对象 而不是字符串表示,您可以使用以下代码段:

extension Date {
    func localDate() -> Date {
        let nowUTC = Date()
        let timeZoneOffset = Double(TimeZone.current.secondsFromGMT(for: nowUTC))
        guard let localDate = Calendar.current.date(byAdding: .second, value: Int(timeZoneOffset), to: nowUTC) else {return Date()}

        return localDate
    }
}

这样使用:

let now = Date().localDate()

我对Swift Date的理解是Date是一个没有任何日历或时区信息的时间点。我认为现在是 GMT 时间。如果要显示指定时区的日期,则必须使用 DateFormat API 将日期格式化为字符串。

我有一个 iOS 应用程序 TapToCount-3W 可以用日期和 GPS 位置信息做笔记。当我旅行时,我用它来 record/tap 带有日期和 GPS 的便条。当我在旅行国家时,日期是当地日期。但是,我发现的问题是,当我回到家时,显示的旅行日期是我本国的日期,而不是那些旅行国家的时区。

我现在正在更新我的应用程序。解决方案是在点击时添加时区信息。使用日期和时区信息,将正确显示本地化日期。

此 QA 中推荐的扩展日期的方法实际上是从 Date() 从 GMT 时间的第二个偏移量创建日期。这是格林威治标准时间和不同于 Date() 的日期。

以下代码来自我的更新(我还包括@lajosdeme 方法作为比较):

extension Date {
  private func getLocalByID(_ identifier: String?) -> Locale
  {
    let local: Locale
    if let id = identifier, !id.isEmpty {
      local = Locale(identifier: id)
    } else {
      local = Locale.current
    }
    return local
  }

  func localizedString(
    timezone: String?,
    dateStyle: DateFormatter.Style = .short,
    timeStyle: DateFormatter.Style = .long
  ) -> String
  {
    let dtFormater = DateFormatter()
    let tz: String = timezone ?? ""
    dtFormater.locale = getLocalByID(tz)
    dtFormater.dateStyle = dateStyle
    dtFormater.timeStyle = timeStyle
    if let timeZone = TimeZone(identifier: tz) {
      dtFormater.timeZone = timeZone
    }
    return dtFormater.string(from: self)
  }

  func dateForTimezone(_ timezone: String?) -> Date {
    let nowUTC = Date()
    let tz: TimeZone
    if let timezone = timezone, 
      let v = TimeZone(identifier: timezone)
    {
      tz = v
    } else {
      tz = TimeZone.current
    }
    let timeZoneOffset = 
      Double(tz.secondsFromGMT(for: nowUTC))
    if let dt = 
      Calendar.current.date(byAdding: .second, value: Int(timeZoneOffset), to: nowUTC) 
    {
      return dt
    }
    else {
      return Date()
    }
  }
}

// Test above extension in Playground
// [SwiftFiddle][3]
let dt1 = Date()
let tz = "America/Edmonton"
let dt2 = dt1.description(with: .current)
let dt3 = dt1.localizedString(timezone: tz)
let dt4 = dt1.dateForTimezone(tz)
print("Timezone: \(tz)\nDate: \(dt1)\ndescription: \(dt2)\nlocalized string: \(dt3)\ndateForTimezone: \(dt4)")

以下是 SwiftFiddle playground 的测试结果:

Timezone: America/Edmonton
Date: 2022-06-03 15:41:23 +0000
description: Friday, June 3, 2022 at 3:41:23 PM Coordinated Universal Time
localized string: 6/3/22, 9:41:23 AM GMT-6
dateForTimezone: 2022-06-03 09:41:23 +0000