iOS Swift - 获取当前本地时间和日期时间戳
Posted
技术标签:
【中文标题】iOS Swift - 获取当前本地时间和日期时间戳【英文标题】:iOS Swift - Get the Current Local Time and Date Timestamp 【发布时间】:2018-03-04 17:56:45 【问题描述】:我正在尝试制作一个考勤应用程序,但我对 ios 和 Firebase 中的日期和时间感到非常困惑。
我使用日期作为 Key,这是我的 Firebase 数据库的结构。
--Employees
--Unique_ID
--Details
Name: John
--Attendance
--dateToday
Timein: 8:00 AM
Timeout: 5:00 PM
BreakStart: 12:00 PM
BreakFinish: 1:00 PM
这是获取我用作密钥的日期时间戳的代码
override func viewDidLoad()
super.viewDidLoad()
let now = NSDate()
let nowTimeStamp = self.getCurrentTimeStampWOMiliseconds(dateToConvert: now)
// I save this dateToday as Key in Firebase
dateToday = nowTimeStamp
func getCurrentTimeStampWOMiliseconds(dateToConvert: NSDate) -> String
let objDateformat: DateFormatter = DateFormatter()
objDateformat.dateFormat = "yyyy-MM-dd"
let strTime: String = objDateformat.string(from: dateToConvert as Date)
let objUTCDate: NSDate = objDateformat.date(from: strTime)! as NSDate
let milliseconds: Int64 = Int64(objUTCDate.timeIntervalSince1970)
let strTimeStamp: String = "\(milliseconds)"
return strTimeStamp
但是当我将其转换回日期时,我得到 2017-09-22 16:00:00 +0000,这是错误的,因为在我的位置是 9 月 23 日。
使用什么代码才能获得正确的日期时间戳和时间时间戳?
【问题讨论】:
你的时区是UTC+0800是正确的。print
始终以 UTC 显示 Date
s。而2017-09-22 16:00:00 +0000
和2017-09-23 00:00:00 +0800
是完全相同的时间点。顺便说一句:不要在 Swift 3 中使用 NSDate
。
DateFormatter 是要创建的重对象,因此如果您经常调用该函数,请将其导出到函数范围之外
【参考方案1】:
关于扩展@MacacoAzul 的答案是我目前的工作示例:
import SwiftUI
struct TimestampDemo: View
var body: some View
Text(getActualTimeStamp(1))
.padding(10)
Text(getActualTimeStamp(2))
.padding(10)
Text(getActualTimeStamp(3))
.padding(10)
Text(getActualTimeStamp(4))
.padding(10)
func getActualTimeStamp(_ tipo:Int) -> String
let date = Date()
let formatter = DateFormatter()
if tipo == 1
formatter.dateFormat = "dd/MM/yyyy"
else if tipo == 2
formatter.dateFormat = "yyyy-MM-dd HH:mm"
else if tipo == 3
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
else if tipo == 4
formatter.dateFormat = "dd-MM-yyyy"
return formatter.string(from: date)
struct TimestampDemo_Previews: PreviewProvider
static var previews: some View
TimestampDemo()
Swift 语言版本: 5
【讨论】:
【参考方案2】:您甚至可以根据需要创建一个函数来返回不同的时间戳:
func dataatual(_ tipo:Int) -> String
let date = Date()
let formatter = DateFormatter()
if tipo == 1
formatter.dateFormat = "dd/MM/yyyy"
else if tipo == 2
formatter.dateFormat = "yyyy-MM-dd HH:mm"
else
formatter.dateFormat = "dd-MM-yyyy"
return formatter.string(from: date)
【讨论】:
【参考方案3】:当我们将 UTC 时间戳 (2017-11-06 20:15:33 -08:00
) 转换为 Date
对象时,时区将归零为 GMT。对于计算时间间隔,这不是问题,但它可以用于在 UI 中呈现时间。
我喜欢 RFC3339 格式 (2017-11-06T20:15:33-08:00
) 的通用性。 Swift 中的日期格式是 yyyy-MM-dd'T'HH:mm:ssXXXXX
,但 RFC3339 允许我们利用 ISO8601DateFormatter
:
func getDateFromUTC(RFC3339: String) -> Date?
let formatter = ISO8601DateFormatter()
return formatter.date(from: RFC3339)
RFC3339 还使时区提取变得简单:
func getTimeZoneFromUTC(RFC3339: String) -> TimeZone?
switch RFC3339.suffix(6)
case "+05:30":
return TimeZone(identifier: "Asia/Kolkata")
case "+05:45":
return TimeZone(identifier: "Asia/Kathmandu")
default:
return nil
我们需要考虑大约 37 个其他时区,您可以决定哪些时区,因为没有明确的列表。有些标准计算的时区更少,有些标准更多。大多数时区在整点休息,有些在半小时,有些在0:45
,有些在0:15
。
我们可以将上面的两种方法组合成这样:
func getFormattedDateFromUTC(RFC3339: String) -> String?
guard let date = getDateFromUTC(RFC3339: RFC3339),
let timeZone = getTimeZoneFromUTC(RFC3339: RFC3339) else
return nil
let formatter = DateFormatter()
formatter.dateFormat = "h:mma EEE, MMM d yyyy"
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
formatter.timeZone = timeZone // preserve local time zone
return formatter.string(from: date)
所以字符串"2018-11-06T17:00:00+05:45"
,表示加德满都某处下午5:00,将打印5:00PM Tue, Nov 6 2018
,显示当地时间,无论机器在哪里。
顺便说一句,我建议将日期存储为远程字符串(包括具有本机日期对象的 Firestore),因为我认为远程数据应该不可知,以尽可能减少服务器和客户端之间的摩擦。
【讨论】:
【参考方案4】:如果您为 iOS 13.0 或更高版本编写代码并需要时间戳,则可以使用:
let currentDate = NSDate.now
【讨论】:
这不是 10 位时间戳【参考方案5】:在 Swift 5
中extension Date
static var currentTimeStamp: Int64
return Int64(Date().timeIntervalSince1970 * 1000)
这样调用:
let timeStamp = Date.currentTimeStamp
print(timeStamp)
谢谢@lenooh
【讨论】:
【参考方案6】:如果您只想要 unix 时间戳,请创建一个扩展:
extension Date
func currentTimeMillis() -> Int64
return Int64(self.timeIntervalSince1970 * 1000)
然后你就可以像在其他编程语言中一样使用它了:
let timestamp = Date().currentTimeMillis()
【讨论】:
迄今为止最好的答案。【参考方案7】:创建当前时间戳的简单方法。如下图,
func generateCurrentTimeStamp () -> String
let formatter = DateFormatter()
formatter.dateFormat = "yyyy_MM_dd_hh_mm_ss"
return (formatter.string(from: Date()) as NSString) as String
【讨论】:
【参考方案8】:为了将当前时间保存到 firebase 数据库,我使用 Unic Epoch Conversation:
let timestamp = NSDate().timeIntervalSince1970
用于将 Unix 纪元时间解码为 Date()。
let myTimeInterval = TimeInterval(timestamp)
let time = NSDate(timeIntervalSince1970: TimeInterval(myTimeInterval))
【讨论】:
NSDate().timeIntervalSince1970 是否会计算时区,或者有什么方法可以针对不同的时区进行计算? 纪元时间,根据定义,是 UTC。它是 UTC 时区自 1970 年 1 月 1 日午夜以来经过的秒数/毫秒数。时区信息仅用于以特定的人类语言显示,而不用于存储或计算任何内容。【参考方案9】:首先,我建议您将时间戳作为 NSNumber
存储在 Firebase 数据库中,而不是将其存储为 String
。
这里值得一提的是,如果您想使用 Swift 操作日期,最好使用 Date
而不是 NSDate
,除非您在应用程序中与一些 Obj-C 代码进行交互。
您当然可以同时使用两者,但文档说明:
日期桥接到 NSDate 类。您可以在 与 Objective-C API 交互的代码。
现在回答你的问题,我认为这里的问题是因为时区。
例如,如果你print(Date())
,就目前而言,你会得到:
2017-09-23 06:59:34 +0000
这是格林威治标准时间 (GMT)。
因此,根据您所在的位置(或您的用户所在的位置),您需要在存储 Date
之前(或之后,例如当您尝试访问数据时)调整时区:
let now = Date()
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let dateString = formatter.string(from: now)
然后,您的String
格式正确,反映了您所在位置的当前时间,您可以随意使用它:) (将其转换为Date
/ NSNumber
,或存储它直接作为数据库中的String
..)
【讨论】:
dateString 最终是正确的。但是,如果我在末尾添加formatter.date(from: dateString)
,我会再次获得格林威治标准时间。以上是关于iOS Swift - 获取当前本地时间和日期时间戳的主要内容,如果未能解决你的问题,请参考以下文章