I get time in EDT from my server in format yyyy-MM-ddTHH:mm:ss for instance 2014-05-21T09:30:00. I convert these to NSDate and save in sqlite on iphone using code below
NSString *strDate = #"2014-05-21T09:30:00";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeZone:[NSTimeZone timeZoneWithName:#"EDT"]];
[df setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss"];
NSDate *date = [df dateFromString:strDate];
It works fine until I change the timezone on the device. If I change time on device time gets messed up. Any idea what am I doing wrong here?
Device's timezone is Eastern and I save 8:00AM
I change device's timezone to Pacific and time changes to 5:00AM
I have an update process that updates all datetime values again and it goes back to 8AM
I now change device's timezone to Eastern and time goes to 11AM
I run the update process again and time goes back to 8AM
How can I save these times so no matter which timezone users is in, they always see eastern time.
Thanks,
D.
NSDate itself doesn't know about timezone; it's just a simple wrapper around a double value, which represents the number of seconds since some fixed time (I think Jan 1 2001 or something) UTC.
What you need is a NSDateFormatter, similar to the one you use to parse the date, to transform the NSDate into an NSString using the EDT timezone.
Related
I am playing about with some timezone calculations and I have noticed quite an annoying error which is causing me problems.
If I create a date, use NSDateformatter to convert it to a certain time zone, retrieve that string, and then use dateformatter to convert the string back into a date object, it keeps reverting to my local GMT time.
Example
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss zzz"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"COT"]];
NSString *str = [dateFormatter stringFromDate:date];
NSLog(#"%#", str);
//prints 2015-02-04 10:33:45 GMT-5
NSDate *newDate = [dateFormatter dateFromString:str];
NSLog(#"%#", newDate);
//Prints 2015-02-04 15:33:45 +0000
Why does it keep reverting back to GMT? I need that date object to accurately reflect the time zone I have set the dateformatter to for some testing purposes, so this is quite a frustrating issue.
Any help would be much appreciated
I believe that the problem is that NSDate itself (i.e. the value you're logging at the end) doesn't have a time zone - it's just a moment in time. You're specifying the time zone *when formatting the value using stringFromDate*, and you're still using that when you *parse* the value back to anNSDate... but theNSDate` value itself doesn't remember the time zone.
To give a different example, imagine you had an IntegerFormatter for NSInteger, which let you say whether you wanted to format and parse in hex or decimal. You could format the decimal value 16 to 0x10, and then parse that value back... but the NSInteger wouldn't "remember" that it was parsed from hex. It's exactly the same here - the time zone plays a part in the parsing (at least when the value itself doesn't specify the time zone) but it isn't part of the result in itself.
I need that date object to accurately reflect the time zone
Then you need to keep the time zone separately alongside the NSDate, basically... (Looking at the documentation, it sounds like NSCalendarDate did what you want, but that's deprecated.)
I am converting an NSString with a date format of 2012-06-30 into an NSDate using the following code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [dateFormatter dateFromString:dateString];
When omitting [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]] the value in NSString is 2012-06-29 23:00:00 plus some automatically added time zone information, which indicates that the the system has some assumptions about the current time zone.
The conversion works fine when I set the time zone with the method above.
However, what would happen if the user is in a different time zone?
How can I make sure that iOS parses just the date as it is and does not add any time information?
The data will not change, timezones dont affect that date itself, it just affect the date presentation, so a date that says 13:00 GMT will have the same presentation of a date that is 14:00 GMT +1
You shouldnt care about the timezones, instead for date conversion to the current time zone of the device use
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
This will set the time zone of the device
I am trying to format a date object and I am noticing on the string I am passing in; 6 hours is being added to my time. This seems to be associating my date time object to GMT.
My code:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd h:mm:ss a"];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *date = [formatter dateFromString:#"2012-02-01 03:38:12 AM"];
NSLog(#"%#", date);
The result is:
2012-02-01 09:38:12 +0000
I have tried this with and without the setTimeZone and it does not matter. Any ideas on why this is displaying as GMT time?
Thanks,
Flea
The date that your formatter creates is not associated with any timezone, but the description method of NSDate (which is what NSLog uses for the output) converts any date to UTC. You would have to use another (or the same) date formatter's stringFromDate: method to print it with a different time zone.
All NSDates are absolute times, meaning that 3:00 AM central time in the United States is 9 AM UTC. I suspect that your systemTimeZone is central time in the United States.
NSLog always shows times in UTC.
If you want to see, as a string, what the time is in your time zone, then you can use the same date formatter stringFromDate: method, and make the you set the time zone of the date formatter to that time zone.
NSLog date formatting is an annoyance because it leads to the kind of confusion you are experiencing.
I have a NSString (date) retrieved from my MySQL database which is in GMT +000 (London) and its format is like this: 12/05/2011 5:21:29 PM.
I would like to know how I could convert it to the user's time zone so that if the user was in china for example, it would be that date in the chinese time zone.
Use setTimeZone: on your input NSDateFormatter. (Internally, NSDates are time zone agnostic.)
E.g.:
// The default time zone for a formatter is the time zone of the user's locale
NSDateFormatter *localFormatter = [[NSDateFormatter alloc] init];
[localFormatter setDateStyle:NSDateFormatterShortStyle];
[localFormatter setTimeStyle:NSDateFormatterMediumStyle];
NSDateFormatter *gmtFormatter = [[NSDateFormatter alloc] init];
[gmtFormatter setDateFormat:#"MM/dd/yyyy h:mm:ss a"];
[gmtFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [gmtFormatter dateFromString:gmtDateString];
NSString *locallyFormattedDate = [localFormatter stringFromDate:date];
[localFormatter release];
[gmtFormatter release];
Although…I don't think this takes DST into account if the DST setting during the specified time is different than the current setting.
Use initWithTimeInterval:sinceDate: to make a date object that adds/subtracts hours. It will be in seconds, so 3 hours ahead would be initWithTimeInterval:10800 sinceDate:(originalDate). The format that would be given if you called -description on that object would be given as (from Apple Documentation)
A string representation of the
receiver in the international format
YYYY-MM-DD HH:MM:SS ±HHMM, where ±HHMM
represents the time zone offset in
hours and minutes from GMT (for
example, “2001-03-24 10:45:32 +0600”).
So it would include the time interval.
EDIT:
Sorry I was using the wrong init method, that is the one you are looking for, initWithTimeInterval:sinceDate:. You make a new NSDate that adds or subtracts the number of seconds that the timezone is ahead/behind.
I have strings like 2011-01-19T20:30:00-5:00 and I'd like to parse them into an NSDate but I want to keep the original time zone.
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat: #"yyyy-MM-dd'T'HH:mm:ssZ"];
NSLog(#"%#", [dateFormatter dateFromString: dateString]);
[dateFormatter release];
That snippet gives me 2011-01-20 02:30:00 +0100 which is also correct but I wish to keep the original time zone -0500 instead of my local time zone +0100 in the NSDate.
First of all, you should be aware that NSDate objects don't store anything related to their locales or timezones, and internally they're essentially represented as a number of seconds since the first instant of 1 January 2001, GMT.
If you are able to the timezone for the string in an NSTimezone object, just do the following before doing dateFromString:
[dateFormatter setTimeZone:timezoneForString];
and you'll be set.
If you're unable to get an NSTimezone and all you have is a string "2011-01-19T20:30:00-5:00", there isn't a very good way to get to an NSTimezone from the -5:00, since there isn't always an unambiguous way to get a timezone ID (e.g., "America/Los_Angeles") or timezone name (e.g., "Pacific Daylight Time") from an UTC offset. So you'd have to write your own code to manually extract the offset, store it, and add it to the time before displaying it.