简体   繁体   English

Swift - 获取本地日期和时间

[英]Swift - Get local date and time

How can I get local date and time in Swift?如何在 Swift 中获取本地日期和时间?

let last_login = String(NSDate.date())

update: Xcode 8.2.1 • Swift 3.0.2更新: Xcode 8.2.1 • Swift 3.0.2

You can also use the Date method description(with locale: Locale?) to get user's localized time description:您还可以使用 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”).日期的字符串表示形式,使用给定的语言环境,或者如果语言环境参数为 nil,则采用国际格式 YYYY-MM-DD HH:MM:SS ±HHMM,其中 ±HHMM 表示时区偏移量,以小时和分钟为单位UTC(例如,“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"

The method above it is not meant to use when displaying date and time to the user.上面的方法不适用于向用户显示日期和时间。 It is for debugging purposes only.它仅用于调试目的。

When displaying local date and time (current timezone) to the user you should respect the users locale and device settings.在向用户显示本地日期和时间(当前时区)时,您应该尊重用户的区域设置和设备设置。 The only thing you can control is the date and time style (short, medium, long or full).您唯一可以控制的是日期和时间样式(短、中、长或完整)。 Fore more info on that you can check this post shortDateTime .有关这方面的更多信息,您可以查看这篇文章shortDateTime

If your intent is to create a time stamp UTC for encoding purposes (iso8601) you can check this post iso8601如果您的意图是为编码目的创建时间戳 UTC (iso8601),您可以查看这篇文章iso8601

In case you want to get a Date object and not a string representation you can use the following snippet:如果您想要获取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
    }
}

Use it like this:像这样使用它:

let now = Date().localDate()

Leo's answer great.狮子座的回答很好。 I just wanted to add a way to use it as a computed property.我只是想添加一种将其用作计算属性的方法。

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

Use it like so:像这样使用它:

print(currentTime)

Or you can encapsulate it:或者你可以封装它:

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

And then you can use it anywhere you use a string:然后你可以在任何你使用字符串的地方使用它:

var time: String = .currentTime

use NSDateFormatter, either by setting the format使用 NSDateFormatter,或者通过设置格式

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

or styles或样式

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

I already found the answer.我已经找到了答案。

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)

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

To get back the most common string formats (when dealing with queries and databases):要取回最常见的字符串格式(在处理查询和数据库时):

Swift 4, 5斯威夫特 4, 5

2019-01-09T01:07:04Z (RFC3339 in GMT/Zulu time) 2019-01-09T01:07:04Z (格林威治标准时间/祖鲁时间的 RFC3339)

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

2019-01-08T17:04:16-08:00 (RFC3339 accounting for local time zone) 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 (standard date stamp in GMT/Zulu time) 2019-01-09 (格林威治标准时间/祖鲁时间的标准日期戳)

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

2019-01-08 (standard date stamp accounting for local time zone) 2019-01-08 (本地时区的标准日期戳记帐)

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

All four strings represent the exact same point in time.所有四个字符串都代表完全相同的时间点。 And remember that sorting these strings in alphabetical order also sorts them into chronological order, which makes this data database agnostic (which I always aim for).请记住,按字母顺序对这些字符串进行排序也会按时间顺序对它们进行排序,这使得这个数据数据库不可知(我一直致力于)。

You have to use NSDateFormatter你必须使用 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)

Swift 4斯威夫特 4

To get current date and time获取当前日期和时间

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

but that will be in date type to convert date into string但这将是日期类型,以将日期转换为字符串

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

My understanding ofSwift Date is that Date is a time point without any calendar or timezone information.我对Swift Date的理解是Date是一个没有任何日历或时区信息的时间点。 I think it is GMT time.我想现在是格林威治标准时间。 If you want to show a date in a specified timezone, you have to use DateFormat API to format the date to a string.如果要在指定时区显示日期,则必须使用DateFormat API 将日期格式化为字符串。

I have an iOS app TapToCount-3W to make notes with date and GPS location information.我有一个 iOS 应用TapToCount-3W来记录日期和 GPS 位置信息。 When I travel, I use it to record/tap a note with date and GPS.当我旅行时,我用它来记录/点击带有日期和 GPS 的笔记。 The dates are local date when I am in travel countries.日期是我在旅行国家时的当地日期。 However, the problem I found is that when I come back home, the travel dates displayed are in my home country dates instead of those travel country timezones.但是,我发现的问题是,当我回到家时,显示的旅行日期是我本国的日期,而不是那些旅行国家的时区。

I am working on updates with my app now.我现在正在使用我的应用程序进行更新。 The solution is to add timezone information when a tap is made.解决方案是在点击时添加时区信息。 With date and timezone information, the localized dates will be correctly displayed.使用日期和时区信息,将正确显示本地化日期。

The method as recommended in this QA to extend Date is actually to create date from Date() from second offset from GMT time.此 QA 中推荐的扩展 Date 的方法实际上是从Date()中从 GMT 时间的第二个偏移量创建日期。 It is a GMT time and different date from Date() .它是 GMT 时间,与Date()不同的日期。

The following codes are from my updates(I also included @lajosdeme method as comparison):以下代码来自我的更新(我还包括@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)")

Here are the test result from SwiftFiddle playground :以下是SwiftFiddle 游乐场的测试结果:

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

Refactor the answer with swift 5 base on @lajosdeme.基于@lajosdeme,使用 swift 5 重构答案。 My location is in China.我的位置在中国。

import Foundation

let date = Date() // It is not the local time, less than 8 hours
print(date)  // 2022-08-05 08:04:20 +0000

extension Date {
    static 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 nowUTC
        }
        return localDate
    }
}
// It is the local time
print(Date.localDate()) // 2022-08-05 16:04:20 +0000

Swift 5斯威夫特 5
If you want to do it manually,如果你想手动完成,
Date() will always return current UTC time Date() 将始终返回当前的 UTC 时间

let today = Date()  

If you live, let's say in Malaysia.如果你住在马来西亚,让我们说。 It is UTC+8 (meaning 8 hours faster)它是 UTC+8(意味着快 8 小时)
You can get your local date time by using Calendar您可以使用日历获取本地日期时间

let localDateTime = Calendar.current.date(byAdding: .hour, value: 8, today)!   

other method you can use is您可以使用的其他方法是

let localDateTime = Date().addingTimeInterval(8 * 60 * 60) //because the param in seconds

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

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