Date to milliseconds and back to date in Swift
Solution 1
I don't understand why you're doing anything with strings...
extension Date {
var millisecondsSince1970:Int64 {
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)
Solution 2
As @Travis Solution works but in some cases
var millisecondsSince1970:Int
WILL CAUSE CRASH APPLICATION ,
with error
Double value cannot be converted to Int because the result would be greater than Int.max if it occurs Please update your answer with Int64
Here is Updated Answer
extension Date {
var millisecondsSince1970:Int64 {
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
//RESOLVED CRASH HERE
}
init(milliseconds:Int) {
self = Date(timeIntervalSince1970: TimeInterval(milliseconds / 1000))
}
}
On 32-bit platforms, Int is the same size as Int32, and on 64-bit platforms, Int is the same size as Int64.
Generally, I encounter this problem in iPhone 5
, which runs in 32-bit env. New devices run 64-bit env now. Their Int
will be Int64
.
Hope it is helpful to someone who also has same problem
Solution 3
@Travis solution is right, but it loses milliseconds when a Date is generated. I have added a line to include the milliseconds into the date:
If you don't need this precision, use the Travis solution because it will be faster.
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 ))
}
}
Solution 4
//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)
}
}
I removed seemingly useless conversion via string and all those random !
.
Solution 5
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)
Related videos on Youtube
user1079052
Updated on November 12, 2021Comments
-
user1079052 over 2 years
I am taking the current time, in UTC, and putting it in nanaoseconds and then I need to take the nanoseconds and go back to a date in local time. I am able to do get the time to nanoseconds and then back to a date string but the time gets convoluted when I go from a string to date.
//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 ) )! } }
//The timestamp is correct but the date returned isn't
-
vadian over 7 yearsWhat is the purpose of converting a date to string and right back to date (in
currentTimeInMiliseconds()
)? -
user1079052 over 7 yearsThe company I work for stores all dates in milliseconds
-
vadian over 7 yearsBut what the is double conversion date -> string -> date for and what is the given
format
which is missing in the code? -
user1079052 over 7 yearsI don't understand what you are trying to say. I use currentTimeToMilliseconds to send UTC dates to the server. Then I use dateFromMilliseconds to go back to a current date when the server sends times.
-
vadian over 7 yearsYou are converting a date to a string and right back to the same date which seems to be useless. Once again, what is the used date format
format
? ActuallyInt(Date().timeIntervalSince1970 * 1000)
can replace the entire function.NSDate
is just a double value without considering a time zone -
Caleb over 5 yearsYou seem to use nanoseconds in your question when you appear to mean milliseconds. There are 1 million nanoseconds in a millisecond, so it's not an inconsequential mistake.
-
-
user1079052 over 7 yearsThis would be great but I need currentTimeInMilliseconds to convert the local time to UTC and I need dateFromMilliseconds to convert from UTC to local time
-
user28434'mstep over 7 yearsTimestamp is in UTC already.. >
The number of seconds from the reference date (00:00:00 **UTC** on 1 January 1970)
-
user1079052 over 7 yearsI am doing the string because i need millisecondsSince1970 to be in UTC and init(milliseconds:Int) to be put back in local time.
-
Travis Griggs over 7 yearsDate objects are always in UTC. Those values in my example are UTC (note how the description method then renders the UTC epoch beginning in PDT).
-
dickyj about 7 yearsBetter to do init(milliseconds:Double) instead of Int or else you will lose the milliseconds when you convert back.
-
davis almost 7 yearsdoesn't this solution lose the millisecond precision?
-
DoesData over 6 yearsWhy would that error happen? Time interval since 1970 is a 32 bit number. At least until we get to this: en.wikipedia.org/wiki/Year_2038_problem
-
Prashant Tukadiya over 6 years@DoesData If you see we are multiplying number with 1000. this causes out of the range of Int32
-
Nicolas Guillaume about 6 yearsdavis: If I understand correctly, the
timeIntervalSince1970
is a double and therefore has millisecond precision in it. The multiplier and cast are there to convert this into a int. -
AechoLiu over 5 yearsSome old iOS device run in 32-bit env. It's
Int
isInt32
. But new iOS device, ex: iPhone 6, it'sInt
isInt64
. So, 32-bit problem may cause crash in old iOS devices. -
Prashant Tukadiya over 5 years@AechoLiu Thanks for pointing it what should be solution for this case ? Can you help me to update my answer
-
doogilasovich over 5 yearsI ran into this issue on 32-bit systems (iPad 2) as well. This should be the correct answer.
-
WestCoastProjects almost 4 years
Date().millisecondsSince1970
is showing as unresolved -
famfamfam almost 4 yearswhy should * 1000, i think we lost the milisecond
-
Jase almost 4 years@javadba try
Date().timeIntervalSince1970
. The return value is aDouble
that represents the number of seconds since 1970 – it is precise to 'sub-millisecond precision'. See here: developer.apple.com/documentation/foundation/timeinterval -
WestCoastProjects almost 4 years@Jase Thx yes I did finally run into that soon after and it works.
-
Peter Schorn over 3 years@javadba
Date().millisecondsSince1970
is a custom extension in the posts for this question. It's not in Foundation. -
Peter Schorn over 3 years@davis It doesn't loose the millisecond precision, but it does loose sub-millisecond precision. Unless you absolutely need to convert the date to an integer, consider using my answer.
-
Peter Schorn over 3 yearsYou will not lose millisecond precision, but you will lose sub-millisecond precision. Unless the time interval absolutely needs to be represented as an integer, consider my answer below instead.
-
user28434'mstep over 3 years@PeterSchorn, yep, this code in the answer was just a cleaned up version of the code from the question. The question had
Int
, therefore the answer hasInt
too. -
Peter Schorn over 3 years@user28434 Ok, got it. Hopefully other people will find my answer userful though.