NSDate calculation missing 1 hour when date set manually from settings - iphone

I have a strange query...
If the date/time is set automatically in my iPhone than the time is correctly displayed as seen below...
And if the date/time is set manually with a different time zone than I am actually in (I am in India and set it to London. Works fine if set to India),it shows wrong results only for two dates calculated by using the method [self.surveyModel.creationDate dateByAddingTimeInterval:60*60*24*30] and similarly for 20 days .. see image below..
I am not setting the default time zone or local time zone for the application, and I am suing the following method to show the result...
- (NSString *)stringWithFormat:(NSString *)format {
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[outputFormatter setDateFormat:format];
NSString *timestamp_str = [outputFormatter stringFromDate:self];
[outputFormatter release];
return timestamp_str;
}
what am I doing wrong here...?

NOTE: This answer is in reply to the Comment on the Question
It seem the error is caused by regions with Daylight Savings, in this case London, England.
When the date/time is calculated automatically, the iOS DateTime library takes the DayLight Saving into account.
When dealing with the DateTime manually, which you are doing through this code [self.surveyModel.creationDate dateByAddingTimeInterval:60*60*24*30]
You are setting the DateTime without listing the DayLight option enabled. So when you take the NSTimeZone look for the DayLight savings options.

Related

Keep Date format to be fix IPhone SDK

How do I keep the date format fix getting from UIDatePickerView, It should not affected from country(Region Format). Presently In my application if I set the region format as "China" it is displaying UIDatePickerView in local china format. I want to as it is but I want to access the date from this in my fixed standard format. It should not be affect by country whether it is Australia or China or UK. Please Suggest with example.
I do not want to change the date format in Picker View just want to change date format access from it. Here is the code that I am using:
NSDateFormatter *datef = [[NSDateFormatter alloc]init];
NSCalendar *usersCalendar =
[[NSLocale currentLocale] objectForKey:NSLocaleCalendar];
[datef setLocale:[NSLocale currentLocale]];
[datef setTimeZone:[NSTimeZone localTimeZone]];
[datef setCalendar:usersCalendar];
tempFDate = [datef dateFromString:[NSString stringWithFormat:#"%# %#",txtDate.text,txtTime.text]];
NSLog(#"%#",tempFDate);
I am continuously getting null in console. I need such a date format that can work for all the region formats. Please Suggest its urgent for me.
NSDateformatter is the best option.
See, the timezone if not specified it will use the timezone of which device is set and display the content accordingly
there are options to get the device setted timezone also to work with it
+ localTimeZone
+ defaultTimeZone
+ setDefaultTimeZone:
+ resetSystemTimeZone
+ systemTimeZone
check this class
Here you need the reponse to a certain timezone for eg GMT 0000
then
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
will do the job for you
using NSDateFormatter.
you can use NSDateFormatter to convert any date format like dd/MM/yyyy etc.

Struggling with NSDate, formats and timezones

The deal is I want a NSDate representation of the date 18th of June 1978.
I have tried to init NSDate like
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
self.dateFormatter.timeStyle = NSDateFormatterNoStyle;
self.startDate = [dateFormatter dateFromString:#"19/06/78"];
NSLog(#"%#", self.startDate);
This produces the right date when the iPhone is set to Danish in the International settings.
It does not work with a iPhone set to i.e. english/american settings.
Notice the extra day (19) because denmark is in GMT +1 and i think the NSDate defaults to time 23:00:00. That indicates that something i not working as intended.
I want the above date (18/06/1978) represented a an NSDate object regardless of the timezone, locale and International settings on the device.
How to achieve that?
Edit:
So Ole Begemann's answer seemed to resolve my issue. His solution did create the correct date both on a device in USA International settings and en European international settings.
But when Apple should review the app the date created was 17th of June 1978. This makes sence since I'm setting timezone to GMT +0000. And Cupertino is like GMT -0007 or so.
So this would give a day earlier.
So to correct my question: I want the 18-06-1978 no matter what locale, timezone the device is physically or settings wise in.
What I'm trying to do is setting a start date 18. june 1978 and later in my app render the date as a string formatted like "780618" (yyMMdd) regardless of the timezone or place of the device. It allways has to be "780618" as this is a key start date for my app.
So I might be attending the problem wrong. Instead of trying to force same date everywhere I maybe should accept the timezone stuff and try to configure the NSDateFormatter to output the right date.
So basically: What I want is THE NSDate instance that formats to "780618" everywhere - in any timezone with any international device settings.
How to achieve this?
I want the above date (18/06/1978) represented a an NSDate object regardless of the timezone, locale and International settings on the device.
This makes no sense to NSDate. An NSDate always represents a single point in time, so by definition it includes a time and the time zone this time is in (or to be more exact, it stores the time in GMT; the time is only converted to another time zone for display purposes). If you just want the date, you have to make your own definition regarding the time, e.g. to store these dates with a time of midnight GMT.
When setting a date programmatically, you must always set a time zone and, if you use a date formatter, set the formatter's locale and calendar. This ensures that your code is independent of the user's/device's locale settings.
I would do it like this:
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateComponents setYear:1978];
[dateComponents setMonth:6];
[dateComponents setDay:18];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [calendar dateFromComponents:dateComponents];
NSLog(#"%#", date);
You can do like this:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// Set the locale to en_US_POSIX. This makes the date formatter respect
// the format string regardless of the user's locale.
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[formatter setLocale:locale];
[locale release];
// We want the date in the user's current time zone.
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setDateFormat:#"dd/MM/yy"];
NSDate *date = [formatter dateFromString:#"18/06/78"];
[formatter release];
NSLog(#"%#", date);
That the date is shown like this 1978-06-17 23:00:00 +0000 is because NSDate's description returns the date in GMT. 17th of June 1978 at 23:00 is 18th of June 1978 00:00 in GMT+1.

NSDate and different timezones?

Alright. Our application sends an NSString made out of the current user's username and todays date formatted in yyyyMMddHH. Our server, that is located in sweden, makes the exact same String and compares the two when it gets the call.
Now. We have realized, that if one of our users goes abroad, the timezone will change, resulting in complications.
if the iPhone user were to be in lets say, Seoul, South-korea. His NSString that is sent would be something like:
2011061718
Meanwhile, when our server gets the call, it will recreate its own datestring in this format because it's located in sweden.
2011061711
And therefore deny the user access to the functions on the server side.
To summarize:
How do i programmatically set a default static timezone in my application?
Atm we do this:
NSDate *aDate = [aDateFormatter stringFromDate:[NSDate date]];
And somehow we need the timezone and compare the difference between the user's actual timezone and change it to a swedish-timezone.
Any ideas?
EDIT: Ok. This application is only meant to be released in sweden. And we are using a combination of the user's username and the current date in the format of yyyyMMddHH to make a secure key, the key is meant to update itself whenever a new hour starts. The server, which is located in sweden in the timezone of GMT+1 makes a verification that the user is on an actual device using the application and not someone who has made a client of his own making soap-calls to our service.
Therefore, if one of our users goes outside the timezone, it will reject the user since the strings wont match.
This is why we want to set the default timezone for that function GMT+1 at all times. And this is what we're really looking for.
Thanks. Again.
If you need to make the client format the date, this is how to do it:
NSDate *now = [NSDate date];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"Europe/Stockholm"]; // Sets the right time.
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]; // Forces the date formatter to accept any format string.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setCalendar:gregorianCalendar];
[formatter setTimeZone:timeZone];
[formatter setDateFormat:#"yyyyMMddHH"];
[formatter setLocale:locale];
NSString *dateString = [formatter stringFromDate:now];
NSLog(#"Date: %#", dateString);
[locale release];
[gregorianCalendar release];
[formatter release];
The date formatter will do all the work for you, you just need to configure it.
By setting the gregorian calendar, you're using the same calendar as in Sweden.
By setting the timezone, you'll get the time as it would be in Sweden.
By setting the locale to "en_US_POSIX" you make the formatter use the exact format you specify, and not append any AM/PM stuff.
Don't mess about with that. Send complete date time as a string and let the server figure out the times.
NSString *dtString = [[NSDate date] description];
This will create a string with the format
YYYY-MM-DD HH:MM:SS ±HHMM
Use -[NSDateFormatter setTimeZone:]. NSDate has nothing to do with it as it does not care about time zones.
Btw, your code will also fail if the user uses a different calendar.
Also a heads up, if you turn the AM/PM function on the dateformatter will pring out 'AM/PM' even if you dont place it in the format string.
To fix this also add an NSLocale to the DateFormatter.

Date and timezone

In our app, we always need to pick the current Eastern time (EST or EDT).
We set the application timezone as below in the app delegate:
NSTimeZone *ESTTimeZone = [NSTimeZone timeZoneWithName:#"US/Eastern"];
[NSTimeZone setDefaultTimeZone:ESTTimeZone];
Also, for the NSDateFormatter, we set the locale as follows:
NSDateFormatter *formatForFileName = [[NSDateFormatter alloc] init];
[formatForFileName setDateFormat:#"yyyyMMdd"];
NSLocale *uslocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[formatForFileName setLocale:uslocale];
[uslocale release];
If my iPad is set to correct EST date and time, there is no issue. If I were to log the current date as follows:
NSLog(#"current date : %#",[formatForFileName stringFromDate:[NSDate date]]);
it will display today's date correctly.
However, if I change my iPad date to be the next day's date and log the current date, I would want the current EST date and time to be returned.
However, [NSDate date] returns me the current iPad date (the next day's date) and time and not the EST date and time.
Is there any way I can get the correct EST date and time using [NSDate date] irrespective of what the user has set on his iPad.
Thanks.
I'm not sure if I understand your question. [NSDate date] always creates a date with the date/time the OS thinks is valid at the moment, i.e. the time the device's clock is set to. If you have doubts whether this is indeed the current time, you would need to contact a trustworthy time server on the Internet and get the time from there.
[NSDate date] returns a date set to the current system date and time. So when the user changes to the next day's date on the system, [NSDate date] will return next day's date. NSDate assumes (rightfully so) that the system date is the correct date.
To display the actual EST date, you will need to query a source (a remote source) other than the system for the date that you want.

In Cocoa, how do I use NSTimeZone to get the system time zone offset as a string?

For PDT, I would want "-0700".
I'm getting a date in the past to determine how long ago something happened.
NSDate *then = [NSDate dateWithString:#"1976-04-01 12:34:56 -0700"]; // Note the hard-coded time zone at the end
I'll be constructing the date string elsewhere but I don't know how to access the local time zone.
I read the Apple Dates and Times Programming Topics for Cocoa as well as the NSTimeZone and NSDate Class References but it's just too hard for me to put the information together. I could really use a few lines of code just to show how it's used.
Update: While struggling with this, I was writing code using a Command Line template so I could try things quickly. I just tried my previous code on iPhone and I'm getting NSDate may not respond to '+dateWithString:' Sorry if that added to the confusion, who knew Apple would change up such a basic class.
Use NSDateFormatter to build NSDate from a string:
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
NSDate *formatterDate;
formatterDate = [inputFormatter dateFromString:#"1976-04-01 12:34:56 -0700"];
NSString *dateString = [inputFormatter stringFromDate:formatterDate];
NSLog(#"date:%#", dateString);
This way you get the local time from string, for example the date specified by the string:
"1976-04-01 12:34:56 -0700"
is in time zone -0700, (I'm in time zone GMT +1000) so I get:
2009-11-17 22:13:46.480
cmdline[10593:903] date:1976-04-02
05:34:56 +1000
The time zone offset is dependent on the date in much of the world—those parts of it that use Daylight-Saving Time/Summer Time.
The only correct way is to generate the entire string from date and time-zone together. Use NSDateFormatter for this.
The best way is to probably use a simple calendar formatter
NSCalendarDate * date = [NSCalendarDate calendarDate];
[date setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"PDT"]];
NSLog([date descriptionWithCalendarFormat:#"%z"]);
which will output '-0700'
or leave out the second line if you want the current time zone of the system (not sure which you were asking for)