NSTimeZone isDaylightSavingTime giving wrong value - ios

Currently GMT-0700(US/pacific) is already in day-light-saving
But I am getting "NO" from NSTimeZone
NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:secondsFromGMT]; //Getting timezone as GMT-0700
BOOL isDaylightSavingTime = [timeZone isDaylightSavingTime]; //getting boolean value as NO
How to fix this issue?
REQUIREMENT :I want to know ,my receiver is using dayLightSavingTime or not.i will get only receiver offset value.I have to support different timezones()..What is the best approach to do this

timeZoneForSecondsFromGMT is not specific enough.
The most accurate way is to create the time zone with the (full) region name:
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:#"America/Los_Angeles"];

This is not a wrong value. You get timezone GMT-0700 but this is not a Pacific timezone. To create pacific timezone you need:
timeZone = [NSTimeZone timeZoneWithName:#"PST"];
This is short description from apple documentation:
+ (instancetype)timeZoneForSecondsFromGMT:(NSInteger)seconds;
Description Returns a time zone object offset from Greenwich Mean
Time by a given number of seconds. The name of the new time zone is
GMT +/– the offset, in hours and minutes. Time zones created with this
method never have daylight savings, and the offset is constant no
matter the date.

Other answers mentioning timeZoneWithName are correct but there's one more detail I don't think has been mentioned. The reason that timeZoneForSecondsFromGMT doesn't work is that GMT does not have daylight savings time (or summer time, as it's more sensibly called in some other countries). GMT doesn't jump forward or back; it always moves ahead by one second per second. Since you ask for a fixed number of seconds from GMT, the result also does not have GMT. If it gave you a time zone that observed daylight saving time, the number of seconds from GMT would have to change twice a year. But since you asked for a fixed number of seconds, you get a result that doesn't do that, and never reports daylight saving time in effect.

Related

secondsFromGMT returns different values on device and simulator

I am working on a time app which display time of different time zones. For this i am using a standard time haDate (UTC tz).
For displayDate i am using system time zone api. Time Zone is America/Santiago (UTC-3:00).
NSTimeZone *tz=[NSTimeZone timeZoneWithName:_timeZone];
_displayDate=[_haDate dateByAddingTimeInterval:tz.secondsFromGMT];
"haDate" code -
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
formatter.timeZone=[NSTimeZone timeZoneWithName:#"UTC"];
NSString *utcTimeCurrent=[dict objectForKey:#"utctime"];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
_haDate=[formatter dateFromString:utcTimeCurrent];
The issue is when i run this code on simulator tz.secondsFromGMT returns -10800 but on device it returns -14400, which is 1 hour less.
Device and Simulator using same timeZone Asia/Kolkata (UTC+5:30). I know America/Santiago uses DST but why it is giving me different seconds even both (simulator and device) are on same timeZone.
What is wrong and how can i fix it?
NOTE
To fix DST issue i am using this code. But it always go to the else part on both devices. (BTW below code is not required because tz.secondsFromGMT always return seconds after DST adjustments.)
NSTimeZone *tz=[NSTimeZone timeZoneWithName:_timeZone];
if (tz.isDaylightSavingTime)
{
_displayDate=[_haDate dateByAddingTimeInterval:tz.secondsFromGMT+tz.daylightSavingTimeOffset];
}
else
{
_displayDate=[_haDate dateByAddingTimeInterval:tz.secondsFromGMT];
}
When i log the tz -
On Simulator
tz America/Santiago (GMT-3) offset -10800
On Device
tz America/Santiago (GMT-4) offset -14400
So it is not using DST.
NOTE 2
This problem only occurs in iPad 2. Other devices working fine.
NOTE 3
My iPad 2 using iOS 8.4 . Both time zones (Chile Standard Time -America/Santiago and Easter Island Standard Time - Pacific/Easter) are giving me wrong seconds
Chile changed the TZ at the beginning of 2015. Probably your iPad 2 has an iOS Version using an outdated time zone database. Update it.
Time in Chile is divided into two time zones. Continental Chile uses the time offset UTC−03:00. Additionally, Easter Island uses the time offset UTC−05:00.[1]
Until 2015, Continental Chile used the time offset UTC−04:00 and Easter Island used UTC−06:00 for standard time, with daylight saving time roughly between October and March every year. However, in January 2015 it was announced that all the country will keep the time offset used during daylight saving time.
https://en.wikipedia.org/wiki/Time_in_Chile

NSDate fixing timezones

I know that NSDate doesn't have timezone information.
However, I'm trying to understand how to manipulate them properly.
At the moment I'm passing a date into an object. That date is the user selected date at time 00:00:00.
i.e. if the user hits October 21st then the NSDate passed in should be. 21/10/2013 00:00:00.
However, it isn't it's 20/10/2013 23:00:00. (One hour before).
Now, this is nothing about formatting them or displaying them. I'm just using the NSDates.
I'm creating the date using NSDateComponents and NSCalendar.
I guess my question is...
How can I tell what date an NSDate is actually referring to in my local time zone?
I need to send a UNIX time stamp for 00:00:00 and 23:59:59 for a given date. However, at the moment when I set the hour, minute and second to 0, 0 and 0 then I'm not getting midnight in the current time zone I'm getting midnight in GMT.
This isn't what I want.
Fixed?
OK, I've fixed it... I think. At least, it's doing what I want it to do.
The trick is...
NSTimeZone *timeZone = [NSTimeZone localTimeZone];
[dateComponents setSecond:timeZone.secondsFromGMT];
I've been confused by this many times. When you NSLog an NSDate, you'll always get the output in GMT. So the 20/10/2013 23:00:00 (GMT) you're seeing is the same as your expected 21/10/2013 00:00:00 (BST). The UNIX timestamp for both of these dates would be the same because it doesn't take into account timezone - it's always UTC.
If you want to output in a user-readable format, an NSDateFormatter will format the date using your current timezone and locale.

Find DST (Daylight Savings Time) timestamp using Objective-C/C?

Is there a way to get the specific date (way) when daylight davings begins and ends for each country using C or Objective-C?
In the Mexico, summer time begins on the first Sunday in April at 2:00am, and ends on the last Sunday in October at 2:00am. In many POSIX systems this is written as
M4.1.0/2,M10.5.0/2
(Begins: Month 4, 1st Sunday at 02:00AM, Ends: Month 10, last Sunday at 02:00AM)
I know it is possible to know if daylight savings is currently active using
NSTimeZone* systemTimeZone = [NSTimeZone systemTimeZone];
BOOL dstIsOn = [systemTimeZone isDaylightSavingTime];
and that it is possible to get the time until the next Daylight Savings begins
NSTimeZone* systemTimeZone = [NSTimeZone systemTimeZone];
NSTimeInterval delta = [systemTimeZone daylightSavingTimeOffset];
BUT: How would I go about finding the specific day that the daylight savings begins/ends?
Is there some killer table out there that I have not been able to find?
Any help would be greatly appreciated!
Yes, there is - you can use [NSTimeZone nextDaylightSavingTimeTransitionAfterDate:] method. This returns an NSDate, which you can use with daylightSavingTimeOffsetForDate to establish what the offset is.
Normally you'd use this to find the next offset, but you can obviously run it more than once with different dates to get a series of upcoming daylight saving changes. There is also a convenience method nextDaylightSavingTimeTransition which will always return the next transition.

System timezone vs selected timezone

What's the best way to compare two time zones?
I'm facing an issue while comparing two NSTimeZone instances using - (BOOL)isEqualToTimeZone:(NSTimeZone *)aTimeZone method.
NSString *timeZoneName = ...
NSTimeZone *sytemTimeZone = [NSTimeZone systemTimeZone];
NSTimeZone *selectedTimeZone = [NSTimeZone timeZoneWithName:timeZoneName];
if ([sytemTimeZone isEqualToTimeZone:selectedTimeZone])
isEqual = YES;
else
isEqual = NO;
Step 1: Go to Settings (Application) > General > Date & Time > Time Zone and search for "Austin". The entry that you'll get will be "Austin, U.S.A". Select this Time Zone. This SHOULD be your new system time zone now!
Step 2: Create a small iPhone/iPad application. Use [NSTimeZone knownTimeZoneNames] to get a list of time zone names. Then try to find "Austin". It's not there! So, i guess we can use "America/Chicago" as the timezone?
Why is the Setting's timezone list different from ours?
Step 3: Now compare the system timezone with time zone for "America/Chicago". They don't match.
I've posted a bug for this - The bug is that Austin isn't in the known time zone list yet is offered by the settings app.
As per an Apple Engineer:
For two NSTimeZones to compare equal, both the names and the data (as
returns by -data) must be equal. You have to be careful when
comparing time zones, because two zones can have the same offset from
GMT but not be the same time zone for historical reasons. Remember
that time zones are used for all sorts of calendrical calculations,
meaning that they are only equal if, throughout history, they've
always had the same GMT offset, the same daylight savings transitions,
and so on.

NSDate dateWithTimeIntervalSince1970 NOT returning GMT/UTC time

I tried an experiment because I need to be able to generate a unix timestamp (since 1970) in the app I am working on.
NSLog(#"Getting timeIntervalSince1970");
double theLoggedInTokenTimestampDateEpochSeconds = [[NSDate date] timeIntervalSince1970];
This should've returned epoch seconds (since 1970) in GMT (Seconds since Jan 1, 1970). However, when conducting the experiment at at Mon Aug 15 09:54:30 2011, it returned 1313427270.504315
Testing this with a simple perl one-liner on my Mac OS Terminal, I get:
perl -e 'print scalar(localtime(1313427270))' which returns Mon Aug 15 09:54:30 2011 ...
This is obviously not GMT time when I am in the SF Bay Area and my local timezone is set to "Cupertino". What is going on and how do I fix it please? I need to have my app send UTC time to the server when it communicates so wherever the user is time timestamp would be sent in one equal, valid time zone.
In another part of my app, when the user requests data from the server, it gets it sent in UTC -- converting it to be displayed as follows:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setTimeZone:nil];
[dateFormatter setDateFormat:#"yyyyMMdd"];
NSDate *conversationDate = [NSDate dateWithTimeIntervalSince1970:[theConversationTimeStampString intValue]];
NSString *conversationDateString = [dateFormatter stringFromDate:conversationDate];
[dateFormatter release];
and this works beautifully -- displaying the corrected time in the user's timezone and locale... so I know it is being done for incoming timestamps. So, what am I doing wrong with the first function (timeIntervalSince190) that stops it from being in GMT?
Thx
I don't think the first function is actually wrong, although it may look like it on the surface. The time interval you are receiving from timeIntervalSince1970 is NOT returning the time interval in GMT. Rather, it is returning the time interval between now and January 1, 1970 00:00:00 GMT. That might seem like a nitpick, but it is important: The interval values are nothing more than a scalar number of seconds since a fixed point in time. The interval itself is not in GMT, only its fixed reference point is.
I don't know perl, but I did a quick search for documentation on local time and it appears to take any time and print convert a standard date type into local time. That means that your time interval describing a fixed point in time is converted back into your local time at that point. When you display it from your command line, you are getting the local time again. So seeing that absolute time translated to your local time is what I would expect to see.
Depending on how exactly your service expects to receive UTC time, your time interval value is likely to be working just fine. Do you have evidence that it is not based on something other than your terminal check?

Resources