現在の時間をUTCで取得し、ナノ秒単位で入力しています。その後、ナノ秒を取得して現地時間の日付に戻す必要があります。私は時間をナノ秒まで取得してから日付文字列に戻すことができますが、文字列から日付に行くと時間が複雑になります。
//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 ) )!
}
}
//タイムスタンプは正しいが、返される日付は正しくない
なぜあなたが文字列で何かをしているのか分かりません...
extension Date {
var millisecondsSince1970:Int64 {
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
}
init(milliseconds:Int64) {
self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
}
}
Date().millisecondsSince1970 // 1476889390939
Date(milliseconds: 0) // "Dec 31, 1969, 4:00 PM" (PDT variant of 1970 UTC)
@Travis Solutionは機能しますが、場合によっては
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と同じサイズです。
通常、32ビット環境で実行されるiPhone 5
でこの問題が発生します。新しいデバイスは64ビット環境を実行します。 Int
はInt64
になります。
同じ問題を抱えている人にも役立つことを願っています
@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 ))
}
}
//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)
}
}
文字列およびそれらすべてのランダム!
を介して、一見役に立たない変換を削除しました。
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)
@Prashant Tukadiyaの回答は動作します。ただし、UserDefaultsに値を保存してから他の日付と比較したい場合は、int64が切り捨てられて問題が発生する可能性があります。私は解決策を見つけました。
スウィフト4:
UserDefaultsに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
}
これが同じ問題を抱えている人を助けることを願っています
変換後の日付を比較する場合は注意してください!
たとえば、TimeInterval(366144731.91.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でアセットを取得しようとしましたが、アセットが見つからないため、数字が同じではないことがわかります。
Round(interval * 1000)/ 1000などのdoubleの小数精度を下げるために複数のソリューションを試しましたが、NSDecimalNumberなどを使用しましたが、成功しませんでした。
CreationDate == Intervalではなく、interval -1 <creationDate <interval + 1でフェッチしました。
より良い解決策があるかもしれません!?