Compare iOS Time Zone Rules - ios

If the user is in Eastern time, I don't want to display "EST" or "EDT" but if they are not, I do want to display it.
Is there an easy way to compare TimeZone rules in iOS?
[NSTimeZone localTimeZone] returns America/Indianapolis, but I just want to know if it is eastern.
Comparing data does not work, do I just compare secondsFromGMT?
EDIT
Comparing offsets does seem to work, but I don't know if it is going to cause problems later?

You can use [[NSTimeZone localTimeZone] abbreviation]; to get the abbreviation of whatever time zone the user is in.
This gives the abbreviation of the current date (EDT if not daylight savings and EST if daylight savings, in your case). If you want the abbreviation of a specific date, you can use abbreviationForDate: and insert any date.
Here is some more information about NSTimeZone
Edit:
If you want to actually compare multiple time zones (as in to check if it is the current time zone or not), you can use isEqualToTimeZone:. If that does not fit your needs, look at some of the other NSTimeZone methods in that link.

I've had lots of pain from dealing with time zone issues on our tools app, that includes event scheduling across time zones. The time zone names have not been friendly to use. Also, Daylight savings time is a great big pain.
What has worked consistently for me is calls like this using timeZoneForSecondsFromGMT
I also convert my stored dates to GMT, then I can set them to the local time on display.
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger timeZoneOffset = [zone secondsFromGMT];
[self.dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:timeZoneOffset]];

Related

Save date in 'GMT' timezone in sqlite database

I am using Core-Datato store date-time object.
Eg. 2015-07-28T07:16:52+0000 this is date in ISO format in GMT timezone.
But when I save this date in database
NSString* dateString=#"2015-07-28T07:16:52+0000";
NSDateFormatter* dateTimeformatter=[[NSDateFormatter alloc] init];
[dateTimeformatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
[dateTimeformatter dateFromString:dateString];
the resulting date which I see in database is 2015-07-28 12:46:52
which is in IST according to my device's timezone
I tried to set timezone as well in dateFormatter but again the same response
NSString* dateString=#"2015-07-28T07:16:52+0000";
NSDateFormatter* dateTimeformatter=[[NSDateFormatter alloc] init];
[dateTimeformatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
[dateTimeformatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
[dateTimeformatter dateFromString:dateString];
Even when I save the [NSDate date] directly in database , it saves the converted date according to device's timezone.
Why Core-data is not taking the timezone of NSDateFormatter into account?
Can anyone tell me how can I save the date in GMT in database irrespective of my device's timezone?
I think the behavior you're seeing is the 3rd party software converting it to your timezone for display. Timezones don't really matter except for display purposes (or if you need to convert between them for calculations, maybe). And, NSDates on their own don't really correspond to any particular timezone, though internally they're represented as though they were GMT. The doc says:
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.
If you look at how the value is actually stored (which you can do with the sqlite3 command-line tool), you can see Core Data is storing it as the number of seconds since 1/1/01; there's no timezone involved. I have an app which does a ton of date manipulation and stores dates in a Core Data store. It looks something like:
zach$ sqlite3 TaskLog.sqlite
sqlite> select ZSTARTTIME from ZTASK;
459924925.598104
459925327.3355
459925356.467429
...
I managed to solve problem I was facing by doing some research and using zpasternack's answer .I mentioned some findings for anyone who may face such problems related to timezone.
Findings:
The date which is saved in database (originally in any timezone) will be saved in 'GMT/UTC' timezone.
The date which is seen in local timezone in database directly is because of third party tool which is used to see the data in database.
When date is taken out of database , then also it is in 'GMT/UTC' timezone.
To see the date in specific timezone , the NSDateFormatter is used with the specific timezone specified.
The most important is NSDate object is always irrespective of any timezone and is always in 'GMT/UTC'

iOS - Does setDefaultTimeZone handle daylight saving and timezone offset automatically?

Server currently store date in UTC and in the app user has option to select any timezone.
[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithName:selectedTimeZone]]
This will override the local timezone. Do I still need to handle anything in NSDateFormatter ?
setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss"
I think I don't need to call setTimeZone in NSDateFormatter if I override defaulttimezone.
And [NSDate date] will then return proper current date or it will be absolute time ?
There are a few related questions here.
This will override the local timezone. Do I still need to handle anything in NSDateFormatter?
You don't need to set the time zone, because if you don't, it uses the default value when the date formatter was created.
I think I don't need to call setTimeZone in NSDateFormatter if I override defaulttimezone.
True, but if you ever change the default time zone, you need to create a new NSDateFormatter, because it doesn't notice that the default has changed. Or you could just change the date formatter's time zone any time you would change the default.
And [NSDate date] will then return proper current date or it will be absolute time ?
The results of [NSDate date] are completely unaffected by the default time zone. NSDate has no time zone, so you get the same results even if you change the default.
Does setDefaultTimeZone handle daylight saving and timezone offset automatically?
If the time zone uses daylight saving time, then yes. Otherwise no. That seems obvious but keep in mind that zones like GMT-0500 don't have daylight saving time even though zones like America/New_York do.

NSDate Daylight time saving

I need to know if we can determine that a particular date had Daylighttime saving ON or OFF.
For eg. In Germany , Daylighttime saving was not there from 1950-1979. Can I determine this programmatically in iOS if these days did not have Daylighttime saving?
You can pick a date and test it. The NSDate accounts for daylight savings.
isDaylightSavingTimeForDate: returns YES if daylight savings time was in effect at that moment in time. If you want to check whether it was in effect in a certain country in a certain year, create an NSDate on 1st of July of that year, and an NSDate on 1st of January of that year, and if neither date had daylight savings time on, then the country didn't have it at all.
(You need to check a date in January as well because Australia, New Zealand etc. have daylight savings time in Summer = January).
iOS is quite good with that kind of historical knowledge. Actually, there are quite a few posts from time to time where iOS has some bizarre but correct information about a timezone and people think it's a bug.

Timezone in the future

I'm working on an app that can book services in later dates in many timezones.
My problem is that when i'm getting timezone for one country, i got this timezone for now.
But this week-end we will change our timezone, and Paris (Actually +1) we'll become +2.
How can I get this timezone for a date like tuesday programmatically ?
You can use various methods.
One would be to use
- (NSInteger)secondsFromGMTForDate:(NSDate *)aDate
of NSTimeZone and get the GMT offset for a certain date and a certain timezone.
Or you can use
– daylightSavingTimeOffsetForDate:
to check wether there needs a DST offset to be accounted for.

change date of NSDate while keeping the time same

I get current time or time stamp of some image. I have to change only date while the time should not be changed. For example I use [NSdate date] to get current date and time and store in an NSdate object that is "2014-01-10 09:58:47 +0000". Now change only the date part, keeping the time same as it is "2013-11-09 09:58:47 +0000"
How can I achieve that?
Convert the date into it's date components (which includes the time part), change the date part of the components to be for the new day, and create a new date based on these components.
dateByAddingDateComponents is also another way to do it.
It's all described in the Calendrical Calculations documentation.

Resources