Get UTC time and local time from NSDate object

Get UTC time and local time from NSDate object



In objective-c, the following code results in the UTC date time information using the date API.


date


NSDate *currentUTCDate = [NSDate date]



In Swift however,


let date = NSDate.date()



results in local date and time.



I have two questions:


date


NSDate


NSDate



EDIT 1: Thanks for all the inputs but I am not looking for NSDateFormatter objects or string values. I am simply looking for NSDate objects (however we cook them up but that's the requirement).
See point 1.


NSDateFormatter





NSDate gives sub-second precision.
– Stonz2
Jul 23 '14 at 17:54


NSDate





A NSDate is a moment in time. There is no such thing as a UTC date or a local date. Its just a question of how you display it.
– carloabelli
Jul 23 '14 at 17:59


NSDate





NSDate instances are based on the time interval since the first instant of 1 January 2001, GMT. Thus the time zone that a date is created in does not make any difference and does not affect the NSDate value.
– zaph
Jul 23 '14 at 18:12



NSDate





From the Apple Docs: "The sole primitive method of NSDate, timeIntervalSinceReferenceDate, provides the basis for all the other methods in the NSDate interface. This method returns a time value relative to an absolute reference date—the first instant of 1 January 2001, GMT."
– zaph
Jul 23 '14 at 18:22




9 Answers
9



The documentation says that the date method returns a new date set to the current date and time regardless of the language used.


date



The issue probably sits somewhere where you present the date using NSDateFormatter. NSDate is just a point on a time line. There is no time zones when talking about NSDate. I made a test.


NSDateFormatter


NSDate


NSDate


print(NSDate())



Output: 2014-07-23 17:56:45 +0000


2014-07-23 17:56:45 +0000


NSLog(@"%@", [NSDate date]);



Output: 2014-07-23 17:58:15 +0000


2014-07-23 17:58:15 +0000



Result - No difference.





Thanks for that. Apparently, playground shows me local time for some reason. Maybe it's just a bug (IDK). I am simply querying let x = NSDate.date().
– p0lAris
Jul 23 '14 at 18:17


let x = NSDate.date()





Not a bug; just the way it is. You haven't specified the time zone or format, so you get whatever. My guess is that it's current time zone, US medium date format, and US short time format.
– Steven Fisher
Jul 23 '14 at 18:34





Yes, not a bug. The description of the NSDate object will show local time zone on your current device in the log, but all dates are GMT or UTC in reality. You settings will then show the log of the date set to the timezone you are in. Which is correct. If I was not at GMT lets say (GMT +1 hour), then the date would show 2014-07-23 16:56:45 +0000 (GMT or UTC) in the log after I created it. In reality, this is 2014-07-23 17:56:45 +0000 (my local timezone). Just imagine they are stored in GTM or UTC and change depending on your timezone.
– skymook
Jan 6 '15 at 12:11



description


NSDate


2014-07-23 16:56:45 +0000


2014-07-23 17:56:45 +0000





@skymook if the UTC date is 2014-07-23 16:56:45 +0000, the local date is actually 2014-07-23 17:56:45 +0100, the +0100 represents the offset from the UTC time.
– Jake T.
Jun 15 '17 at 18:42



2014-07-23 16:56:45 +0000


2014-07-23 17:56:45 +0100


+0100



NSDate is a specific point in time without a time zone. Think of it as the number of seconds that have passed since a reference date. How many seconds have passed in one time zone vs. another since a particular reference date? The answer is the same.


NSDate



Depending on how you output that date (including looking at the debugger), you may get an answer in a different time zone.



If they ran at the same moment, the values of these are the same. They're both the number of seconds since the reference date, which may be formatted on output to UTC or local time. Within the date variable, they're both UTC.



Objective-C:


NSDate *UTCDate = [NSDate date]



Swift:


let UTCDate = NSDate.date()



To explain this, we can use a NSDateFormatter in a playground:


import UIKit

let date = NSDate.date()
// "Jul 23, 2014, 11:01 AM" <-- looks local without seconds. But:

var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZoneStr = formatter.stringFromDate(date)
// "2014-07-23 11:01:35 -0700" <-- same date, local, but with seconds
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.stringFromDate(date)
// "2014-07-23 18:01:41 +0000" <-- same date, now in UTC



The date output varies, but the date is constant. This is exactly what you're saying. There's no such thing as a local NSDate.



As for how to get microseconds out, you can use this (put it at the bottom of the same playground):


let seconds = date.timeIntervalSince1970
let microseconds = Int(seconds * 1000) % 1000 // chops off seconds



To compare two dates, you can use date.compare(otherDate).


date.compare(otherDate)





One thing to note is that if you examine a date value using the debugger it's apt to be shown in local time, while if you use po to display it while debugging (or simply use NSLog) it will always be shown in UTC.
– Hot Licks
Jul 23 '14 at 18:11



po





Actually the time is based on GMT.
– zaph
Jul 23 '14 at 18:16





Thanks. Also, as I mentioned, I want to compare dates, etc. So I want to have these two time values typed using the NSDate type. Is there a way to do that. NSFormatter doesn't solve any purpose.
– p0lAris
Jul 23 '14 at 18:18


NSDate


NSFormatter





dateA.compare(dateB);
– Steven Fisher
Jul 23 '14 at 18:22


dateA.compare(dateB);





Comparing dates is easy, I've added that. But as your question was regarding the different date you saw, explaining why you saw different dates was important. And NSDateFormatter is the best way to do that. :)
– Steven Fisher
Jul 23 '14 at 18:24



Xcode 9 • Swift 4 (also works Swift 3.x)


extension Formatter
// create static date formatters for your date representations
static let preciseLocalTime: DateFormatter =
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "HH:mm:ss.SSS"
return formatter
()
static let preciseGMTTime: DateFormatter =
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "HH:mm:ss.SSS"
return formatter
()


extension Date
// you can create a read-only computed property to return just the nanoseconds from your date time
var nanosecond: Int return Calendar.current.component(.nanosecond, from: self)
// the same for your local time
var preciseLocalTime: String
return Formatter.preciseLocalTime.string(for: self) ?? ""

// or GMT time
var preciseGMTTime: String
return Formatter.preciseGMTTime.string(for: self) ?? ""




Playground testing


Date().preciseLocalTime // "09:13:17.385" GMT-3
Date().preciseGMTTime // "12:13:17.386" GMT
Date().nanosecond // 386268973



This might help you also formatting your dates:



enter image description here



a date is independant of any timezone, so use a Dateformatter and attach a timezone for display:



swift:


let date = NSDate()
let dateFormatter = NSDateFormatter()
let timeZone = NSTimeZone(name: "UTC")

dateFormatter.timeZone = timeZone

println(dateFormatter.stringFromDate(date))



objC:


NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];

[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:timeZone];
NSLog(@"%@", [dateFormatter stringFromDate:date]);





Actually the date is based on GMT. If it was not based on a specific time zone it could not be displayed as another time zone.
– zaph
Jul 23 '14 at 18:17






it is not GMT based I am afraid. If anything you can call it UTC based but for me UTC = zulu time = no timezone. In short the difference UTC vs .GMT is that with GMT, some DaylightSavings time is connected
– Daij-Djan
Jul 23 '14 at 18:34






NSDate basically wraps a unix timestamp
– Daij-Djan
Jul 23 '14 at 18:34






Where did you get information "GMT, some DaylightSavings time is connected". Perhaps you are thinking of BST?
– zaph
Jul 23 '14 at 19:00






From the Apple docs: "the first instant of 1 January 2001, GMT." That is not a unix timestamp which has an epoch of 1 January 1970. UTC did replace GMT and for most purposes, UTC is used interchangeably with GMT.
– zaph
Jul 23 '14 at 19:03



Xcode 9 • Swift 4 or Swift 3:


let date = Date() // default is UTC.



This code gives date in UTC. If you need the local time, you should call the following extension with timezone as Timezone.current


Timezone.current


extension Date

var currentUTCTimeZoneDate: String
let formatter = DateFormatter()
formatter.timeZone = TimeZone(identifier: "UTC")
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

return formatter.string(from: self)




For UTC time, use it like: Date().currentUTCTimeZoneDate


Date().currentUTCTimeZoneDate



At the moment (with the latest changes to Swift), NSDate.date() is not longer available.


NSDate.date()



Instead you just need to initialize NSDate and it gets the current date and time.

To try it, in a playground:


NSDate


var d = NSDate()
d



and you will get:


Oct 22, 2014, 12:20 PM"





That string is what YOU get. By chance :) no formatter and The Output is based on The Locale of The debugger.
– Daij-Djan
Mar 25 '15 at 6:11





It's not about the string , it's about getting current date time , and by just instantiating the NSDate as I said YOU will get the current datetime too.
– Ali
Mar 25 '15 at 9:36





your string is your local time and that what ticket is about is: "in objective-c, the following code [X} results in the UTC date time information, in swift it results in local date and time. X" ==> the debuggers date formatter
– Daij-Djan
Mar 25 '15 at 9:38






This in no way answers the question (or, for that matter, shows the fundamental assumptions behind the question are invalid).
– Steven Fisher
Jul 23 '15 at 16:20



Swift 3



You can get Date based on your current timezone from UTC


extension Date
func currentTimeZoneDate() -> String
let dtf = DateFormatter()
dtf.timeZone = TimeZone.current
dtf.dateFormat = "yyyy-MM-dd HH:mm:ss"

return dtf.string(from: self)




Call like this:


Date().currentTimeZoneDate()





This will give the current timeZone date.Not UTC.
– abhi1992
Jun 22 '17 at 6:56



My Xcode Version 6.1.1 (6A2008a)



In playground, test like this:


// I'm in East Timezone 8
let x = NSDate() //Output:"Dec 29, 2014, 11:37 AM"
let y = NSDate.init() //Output:"Dec 29, 2014, 11:37 AM"
println(x) //Output:"2014-12-29 03:37:24 +0000"


// seconds since 2001
x.hash //Output:441,517,044
x.hashValue //Output:441,517,044
x.timeIntervalSinceReferenceDate //Output:441,517,044.875367

// seconds since 1970
x.timeIntervalSince1970 //Output:1,419,824,244.87537



I found an easier way to get UTC in Swift4. Put this code in playground



let date = Date()
//"Mar 15, 2018 at 4:01 PM"



let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)



let newDate = dateFormatter.string(from: date)
//"2018-03-15 21:05:04 +0000"






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)