AEDT not recognized by NSTimeZone - objective-c

AEDT and AEST are real timezones. NSTimeZone however thinks otherwise. [NSTimeZone timeZoneWithAbbreviation:#"AEDT"] returns nil.
I've tried [NSTimeZone timeZoneWithName:#"AEDT"] as well, but no luck. How do I get this to work without handling this manually (with fixed timezone offsets)?

Related

objective-c create and compare time - running from different countries

I have an app that is used in different countries. In my app I am performing a simple calculation that states if the current time is later than 3pm, do something.
This is how I am creating the 3pm.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *dateAttempt = [[NSDateComponents alloc] init];
[dateAttempt setYear:2016];
[dateAttempt setMonth:05];
[dateAttempt setDay:18];
[dateAttempt setHour:15];
[dateAttempt setMinute:00];
NSDate *threePm = [calendar dateFromComponents:dateAttempt];
NSLog(#"%#", dateAttempt);
NSLog(#"%#", threePm);
I am creating the app in NewYork. When I run the above code I get...
2016-05-18 11:17:53.815 x[1312:37272] 2016-05-18 19:00:00 +0000
I guess that makes sense because NewYork is 4 hours behind UTC. (it's 11am at the time of me writing this)
So the threePm is giving me the UTC equivalent of 3pm in NY, and its working as expected. The problem is when I change the time on the laptop simulator to simulate being in another country. For example Greece.
If I switch the time on the pc to greece, the same code above gives a different result due to a different time adjustment to UTC.
How can I say... no matter where in the world the app is running, if time is later than 3pm (EST)... do something?
NSDate stores absolute time - actually the time offset from a fixed point in UTC time.
NSDateComponents has a timeZone property which is used as the basis for the conversion to NSDate, and this will default to the current timezone - as your results show.
If you always want 3pm in New York set this property. New York is one of the standard time zones: America/New_York; so you can set this property using:
dateAttempt.timeZone = [NSTimeZone timeZoneWithName:#"America/New_York"];
An NSTimeZone understands daylight savings and dependent on the date you set the conversion will translate from EST or EDT as appropriate.
HTH

NSDateformatter Converting date to string

I am having the following date and time 2013-04-25 10:42:44 +0000. When i convert the above date to string, i am getting the output as 2013-04-25 16:12:44. Following is the code i am using to convert the date to string
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.timeZone = [NSTimeZone systemTimeZone];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *dateStr= [dateFormatter stringFromDate:date]];
NSLog(#"dateStr--%#",dateStr);
This gets asked over and over (but is difficult to find via search).
When you log an NSDate object, you will always get the date in UTC format. This is how the description method of NSDate is currently implemented.
As long as the difference you are seeing can be accounted for based on your local timezone relative to UTC, then what you are seeing it correct and expected behavior.
BTW - there is no reason to set the date formatter's timezone to the "system" timezone. This is already done by default. Same for the locale. Only set the timezone or locale if you want something different from the current values.
I guess it's a timezone issue. Set your formatters time zone to GMT:
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
I assume the variable date gets initialized via [NSDate date].
Maybe the quite extensive answer in the follwing topic is helpful here, too.
Does [NSDate date] return the local date and time?

NSDate is 5 hours off

I run the following code:
NSDate *now = [NSDate date];
NSLog(#"now: %#", now);
and get :
2011-09-16 16:14:16.434 iSavemore[1229:7907] now: 2011-09-16 21:14:16 +0000
As you can see i'm running this at 16:14:16 (4:14 pm) but NSDate is returning 21:16:16 (9:14 pm!). Is this an Xcode4 issue or NSDate issue?
NSDate defaults to the Universal timezone (aka GMT).
I'm guessing you're somewhere on the East Coast, 5 hours behind UTC.
Try adding this to your date formatter...
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:[NSLocale currentLocale]];
...and you should see your local time.
If you want to use a specified locale, rather than 'currentLocale', create a NSLocale for the relevant locale.
NSLocale *usLoc = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setLocale:usLoc];
...actually that's US (so possibly not Central).
More specific timezone help can be found here...
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html
However, if you want to show expiry time, wouldn't you still want it in the user's currentLocale?
If you look at the output you'll see that the log includes the timezone:
2011-09-16 16:14:16.434 iSavemore[1229:7907] now: 2011-09-16 21:14:16 +0000
^^^^^^
The time stamp of your log is local time. I assume you're in a timezone that is 5 hours ahead of UTC.
A NSDate refers to a particular point in time. It's up to you to display this however you want; usually with an NSDateFormatter.
This is the reason why you'll see plenty of recommendations against storing a time, or a date as anything other than an NSDate. If you try and store it as a string you'll run into a lot of trouble later on when trying to handle the display in different timezones.
Try setting the time-zone of your NSDate to one that is fitting your need, for example [NSTimeZone localTimeZone]
Just a wild guess here, but maybe it has something to do with time zones?

iPhone - Differences among time zone convenience methods

I see that NSTimeZone has these methods :
defaultTimeZone
localTimeZone
systemTimeZone
Can someone explain to me, in simple terms, what the differences are beetween those calls, and when one should be used instead of the other? I don't understand anything inside the Apple docs about this.
The language in the docs is a bit on the dry side, to be sure, and the similarity of the names is potentially confusing. I'll quote the NSTimeZone docs here and try to explain them:
systemTimeZone
The time zone currently used by the system. If the current time zone cannot be determined, returns the GMT time zone.
This is the time zone which the device believes it is in; it is often set automatically, and would then correspond to the device's physical location, but if the user has explicitly set a particular time zone in the Settings App, that's what you'll get.
defaultTimeZone
The default time zone for the current application. If no default time zone has been set, this method invokes systemTimeZone and returns the system time zone.
Your application is allowed to set its own time zone, so that you can perform actions as if the device were in another zone, but without affecting the system time zone (and thereby other apps). The setting is performed with a call to setDefaultTimeZone:. If you haven't done that, this call is identical to calling systemTimeZone.
localTimeZone
An object that forwards all messages to the default time zone for the current application. The local time zone represents the current state of the default time zone at all times.
This is where it gets a little bit tricky. localTimeZone gives you nearly the same result as defaultTimeZone. The difference is that the specific NSTimeZone instance you get from localTimeZone will always reflect the setting you've made to the time zone within your app. You can call it once, save the result, and always get the current simulated time zone through that object, no matter the changes made. It is as if, when you use this NSTimeZone instance, the framework is calling defaultTimeZone for you, to be sure that you always get the current value.
Here's a couple of brief illustrations of the above. The NSTimeZone object that you get back from systemTimeZone represents the system time zone at the time you make the call. If you call systemTimeZone again, even if the user has since changed the time zone, you will get the same one. Your app caches that value, and you have to ask the system to clear it with resetSystemTimeZone to get the update.
// Say that device is in GMT originally
NSLog(#"%#", [NSTimeZone systemTimeZone]); // GMT
// User flies into Rome and iPhone changes the zone automatically
NSLog(#"%#", [NSTimeZone systemTimeZone]); // Still GMT
[NSTimeZone resetSystemTimeZone]; // Clear app's cache
NSLog(#"%#", [NSTimeZone systemTimeZone]); // Now GMT+2
A similar thing happens with defaultTimeZone. When you call that method, you get an object that will always represent the same time zone, even if you later call setDefaultTimeZone:. However, if you use the object you get from localTimeZone, it will follow the change you make to the default time zone*.
// Say that defaultTimeZone is originally GMT
NSTimeZone * myDefaultTZ = [NSTimeZone defaultTimeZone];
NSTimeZone * myLocalTZ = [NSTimeZone localTimeZone];
[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithName:#"Etc/GMT-4"]];
NSLog(#"%#", myDefaultTZ); // Still gives GMT
NSLog(#"%#", [NSTimeZone defaultTimeZone]); // GMT-4, the new value
NSLog(#"%#", myLocalTZ); // Also the new value!
Apple seems to recommend using localTimeZone:
with the localTimeZone class method, you can get a relative time zone object that decodes itself to become the default time zone on any computer on which it finds itself.
*Note that localTimeZone is still subject to the app-level cache of the system time zone. It only changes to follow your setting of the default time zone.

Keep original time zone with NSDateFormatter

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.