我正在以UTC为单位拍摄当前时间,然后将其置于nanaoseconds,然后我需要花费纳秒并回到当地时间的某个日期。我能够把时间缩短到纳秒,然后回到日期字符串,但是当我从字符串到日期时,时间会变得复杂。
//Date to milliseconds
func currentTimeInMiliseconds() -> Int! {
let currentDate = NSDate()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
let date = dateFormatter.date(from: dateFormatter.string(from: currentDate as Date))
let nowDouble = date!.timeIntervalSince1970
return Int(nowDouble*1000)
}
//Milliseconds to date
extension Int {
func dateFromMilliseconds(format:String) -> Date {
let date : NSDate! = NSDate(timeIntervalSince1970:Double(self) / 1000.0)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
dateFormatter.timeZone = TimeZone.current
let timeStamp = dateFormatter.string(from: date as Date)
let formatter = DateFormatter()
formatter.dateFormat = format
return ( formatter.date( from: timeStamp ) )!
}
}
//时间戳是正确的,但返回的日期不是
答案 0 :(得分:110)
我不明白为什么你要用字符串做任何事情......
extension Date {
var millisecondsSince1970:Int {
return Int((self.timeIntervalSince1970 * 1000.0).rounded())
}
init(milliseconds:Int) {
self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
}
}
Date().millisecondsSince1970 // 1476889390939
Date(milliseconds: 0) // "Dec 31, 1969, 4:00 PM" (PDT variant of 1970 UTC)
答案 1 :(得分:33)
正如@Travis解决方案有效但在某些情况下
var millisecondsSince1970:Int
会导致崩溃申请,
有错误
Double值无法转换为Int,因为如果出现,结果将大于Int.max 请使用Int64更新您的答案
这是更新的答案
extension Date {
var millisecondsSince1970:Int64 {
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
//RESOLVED CRASH HERE
}
init(milliseconds:Int) {
self = Date(timeIntervalSince1970: TimeInterval(milliseconds / 1000))
}
}
希望对有同样问题的人有帮助
在32位平台上,Int与Int32的大小相同,在64位平台上,Int与Int64的大小相同。
通常,我在iPhone 5
中遇到此问题,该问题以32位环境运行。新设备现在运行64位环境。他们的Int
将为Int64
。
答案 2 :(得分:9)
@Travis解决方案是正确的,但是在生成Date时会丢失毫秒。我添加了一行以包含日期中的毫秒数:
如果您不需要这种精确度,请使用Travis解决方案,因为它会更快。
extension Date {
func toMillis() -> Int64! {
return Int64(self.timeIntervalSince1970 * 1000)
}
init(millis: Int64) {
self = Date(timeIntervalSince1970: TimeInterval(millis / 1000))
self.addTimeInterval(TimeInterval(Double(millis % 1000) / 1000 ))
}
}
答案 3 :(得分:8)
//Date to milliseconds
func currentTimeInMiliseconds() -> Int {
let currentDate = Date()
let since1970 = currentDate.timeIntervalSince1970
return Int(since1970 * 1000)
}
//Milliseconds to date
extension Int {
func dateFromMilliseconds() -> Date {
return Date(timeIntervalSince1970: TimeInterval(self)/1000)
}
}
我通过字符串和所有随机!
删除了看似无用的转换。
答案 4 :(得分:3)
let dateTimeStamp = NSDate(timeIntervalSince1970:Double(currentTimeInMiliseconds())/1000) //UTC time //YOUR currentTimeInMiliseconds METHOD
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone.localTimeZone()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.dateStyle = NSDateFormatterStyle.FullStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
let strDateSelect = dateFormatter.stringFromDate(dateTimeStamp)
print("Local Time", strDateSelect) //Local time
let dateFormatter2 = NSDateFormatter()
dateFormatter2.timeZone = NSTimeZone(name: "UTC") as NSTimeZone!
dateFormatter2.dateFormat = "yyyy-MM-dd"
let date3 = dateFormatter.dateFromString(strDateSelect)
print("DATE",date3)
答案 5 :(得分:1)
在Swift 5 / iOS 13中有一个简单的解决方案。
extension Date {
func toMilliseconds() -> Int64 {
Int64(self.timeIntervalSince1970 * 1000)
}
init(milliseconds:Int) {
self = Date().advanced(by: TimeInterval(integerLiteral: Int64(milliseconds / 1000)))
}
}
但是,这假设您已经计算了UTF时间与本地时间之间的时差,并以毫秒为单位进行了调整和说明。为此,请看日历
var cal = Calendar.current
cal.timeZone = TimeZone(abbreviation: "UTC")!
let difference = cal.compare(dateGiven, to: date, toGranularity: .nanosecond)
答案 6 :(得分:0)
当心您要在转换后比较日期!
例如,我使用
将日期为TimeInterval(366144731.9)的模拟器的资产转换为毫秒Int64(1344451931900),然后又转换回TimeInterval(366144731.9000001)func convertToMilli(timeIntervalSince1970: TimeInterval) -> Int64 {
return Int64(timeIntervalSince1970 * 1000)
}
func convertMilliToDate(milliseconds: Int64) -> Date {
return Date(timeIntervalSince1970: (TimeInterval(milliseconds) / 1000))
}
我试图通过creationDate来获取资产,但找不到资产,正如您所看到的那样,数字并不相同。
我尝试了多种解决方案来降低double的十进制精度,例如round(interval * 1000)/ 1000,使用NSDecimalNumber等,但没有成功。
我最终以间隔-1 可能有更好的解决方案!?
答案 7 :(得分:0)
@Prashant Tukadiya回答作品。但是,如果要将值保存在UserDefaults中,然后将其与其他日期进行比较,则会将int64截断,这样可能会引起问题。我找到了解决方法。
迅速4:
您可以在用户默认设置中将int64另存为字符串:
let value: String(Date().millisecondsSince1970)
let stringValue = String(value)
UserDefaults.standard.set(stringValue, forKey: "int64String")
就像避免Int截断一样。
然后您可以恢复原始值:
let int64String = UserDefaults.standard.string(forKey: "int64String")
let originalValue = Int64(int64String!)
这使您可以将其与其他日期值进行比较:
let currentTime = Date().millisecondsSince1970
let int64String = UserDefaults.standard.string(forKey: "int64String")
let originalValue = Int64(int64String!) ?? 0
if currentTime < originalValue {
return false
} else {
return true
}
希望这可以帮助遇到相同问题的人
答案 8 :(得分:0)
除非绝对必须将日期转换为整数,否则请考虑使用Double
来表示时间间隔。毕竟,这是timeIntervalSince1970
返回的类型。转换为整数的所有答案都失去了亚毫秒级的精度,但是这种解决方案更加精确(尽管由于浮点不精确度,您仍然会失去一些精度)。
public extension Date {
/// The interval, in milliseconds, between the date value and
/// 00:00:00 UTC on 1 January 1970.
/// Equivalent to `self.timeIntervalSince1970 * 1000`.
var millisecondsSince1970: Double {
return self.timeIntervalSince1970 * 1000
}
/**
Creates a date value initialized relative to 00:00:00 UTC
on 1 January 1970 by a given number of **milliseconds**.
equivalent to
```
self.init(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
```
- Parameter millisecondsSince1970: A time interval in milliseconds.
*/
init(millisecondsSince1970: Double) {
self.init(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
}
}
答案 9 :(得分:0)
UInt64 中获取时间令牌的简单一行代码
让时间 = UInt64(Date().timeIntervalSince1970 * 1000)
print(time) <----- 在 UInt64 中打印时间
额外提示:
对于自 1970 年以来 API 调用的 10 位毫秒的时间戳然后
让 timeStamp = Date().timeIntervalSince1970
print(timeStamp) <-- 打印当前时间戳