How to format the date to IST? - ios

I have to format the date as below:
19-JUL-2014 10:27:16 IST
How can I do that? Should I send "IST" as string object?
I tried -
NSDate* sourceDate = [NSDate date];
NSLog(#"Date is : %#", sourceDate);
NSTimeZone *currentTimeZone = [NSTimeZone localTimeZone];
NSLog(#"TimeZone is : %#", currentTimeZone);
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]init] ;
dateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm:ss Z"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSLog(#"%#",[dateFormatter stringFromDate:sourceDate]);

I've tried several of scenarios of timezone formatters according to the Apple's official docs and the Unicode date-formatter standards.
I inited the timezone like this:
NSTimeZone *_timezone = [NSTimeZone timeZoneWithName:#"IST"];
that presented the proper timezone to me with +0530 offset, so that was used for the instance of my NSDateFormatter.
NSDateFormatter *_dateFormatter = [[NSDateFormatter alloc]init];
[_dateFormatter setTimeZone:_timezone];
here is the list about I've experienced with different format-scpecifiers:
z = GMT+0530 IST
zz = GMT+0530 IST
zzz = GMT+0530 IST
zzzz = India Standard Time IST
zzzzz = India Standard Time IST
it seemed that none of the standard format-specifiers could provide the actual "IST" only as string, a match was the "India Standard Time IST" with format specifier zzzz and zzzzz – but you can see the "GMT+0530 IST" still contains it with the rest of the formatters.
NOTE: the other format specifiers like Z, v, V, x or X did not seem useful either.
I've read more about format specifiers, the docs says about using z:
The short specific non-location format (e.g. PDT). Where that is unavailable, falls back to the short localized GMT format.
that means to me, the actual short specific non-location format for India Standard Time is not available via NSDateFormatter directly – or for some reason is specified as "GMT+0530 IST" not as short "IST"†.
on the other hand, I'm not sure whether the long specific non-location format is accepted on your server side (aka "India Standard Time IST"), or the timezone must be marked by string "IST" only.
I'm afraid if that latest format is expected only you will need to add it manually and inelegantly, like:
[_dateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm:ss"];
NSString *_date = [[_dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:#" IST"];
NOTE: I've also spotted the months' names should be capitalised as well, I'm not sure that is another expectation or the generic capitalisation of months' names (like e.g. "Jul", "Sep" etc...) is good enough for your server side – I did not take care of capitalising them in my current answer.
† I have not found any standard which to be supposed to describe the actual short format, so based on the unicode standards I would assume the "IST" should be the shortened format against the "GMT+0530 IST" – but that is based on my personal speculation only.

NSDate* sourceDate = [NSDate date];
NSLog(#"Date is : %#", sourceDate);
NSTimeZone *currentTimeZone = [NSTimeZone localTimeZone];
NSLog(#"TimeZone is : %#", currentTimeZone);
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]init] ;
[dateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm:ss zzz"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSLog(#"%#",[dateFormatter stringFromDate:sourceDate]);
This may help you

Please try this,
NSDate *date= [NSDate date];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:#"dd-MMM-yyyy HH:mm:ss z"];
NSLog(#"%#",[dateFormatter1 stringFromDate:date]);

Related

NSDateFormatter dateFromString return wrong year

I have these following snippet.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat : #"yyyy/MM/dd"];
NSString *timeStr = #"2015/05/16";
NSDate *timeDate = [formatter dateFromString:timeStr];
But when I print timeDate in console,the output is werid.The year becomes 4003.
4003-05-16 16:00:00 +0000
I test it in iPad 8.3(12F69)(not simulator).System time zone is Beijing.
Any help is appreciated.
The issue is the locale of the formatter. If you want to use gregorian calendar regardless of the device settings, you generally should set locale to en_US_POSIX.
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
See Apple Technical Q&A #1480. This is geared towards RFC 3339/ISO 8601 dates, but it really applies anywhere you're trying to use standard calendar for converting date string for internal purposes (i.e. as opposed to those dates that are presented to the end user in the UI, which generally should use the device's locale).
Try this... Just need to add last line while printing output.
NSString *timeStr = #"2015/05/16";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd";
NSDate *Date = [formatter dateFromString:timeStr];
NSLog(#"Date =%#", [formatter stringFromDate:Date]);

NSDateFormatter formats wrong for timezone

I have a problem with Date Format
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"YYYY-MM-dd hh:mm:ssZZ"];
formatedDate =[format stringFromDate:datePicker.date];
Everything works fine, except one thing
when I set the YEAR less than or equal to 1924, DateFormatter returns
1924-04-21 03:00:07+050748
Whereas should be
1924-04-21 03:00:07+0500
What's wrong?
You can see the Apple Data Formatting Guide https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html
In the "Fixed Formats",
There are two things to note about this example:
It uses yyyy to specify the year component. A common mistake is to use YYYY. yyyy specifies the calendar year whereas YYYY specifies the year (of “Week of Year”), used in the ISO year-week calendar. In most cases, yyyy and YYYY yield the same number, however they may be different. Typically you should use the calendar year.
The representation of the time may be 13:00. In iOS, however, if the user has switched 24-Hour Time to Off, the time may be 1:00 pm.
So you should change "YYYY" to "yyyy".
User this method .......
-(NSString*) currentDateForServer
{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:UTC];
[dateFormat setTimeZone:timeZone];
[dateFormat setDateFormat:DATE_FORMATE];
NSDate *currentDate = [NSDate date];
NSString *finalString = [dateFormat stringFromDate:currentDate];
return finalString;
}
Define UTC and DATE_FORMATE as you need
You can set your Timezone, like with GMT,
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MM-dd hh:mm:ssZZ"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[format setTimeZone:gmt];
formatedDate =[format stringFromDate:datePicker.date];
This may change your time in output string formatedDate, but you can set NSTimeZone as per your requirement.

NSDateFormatter difference

What is the difference between these two Date Formats. First one give actual time but second on give time buy adding time zone offset value.
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSDate *dateConverted = [dateFormatter dateFromString:#"2013-12-02T12:15:43.182Z"];
NSLog(#"Date: %#",dateConverted); //
Date: 2013-12-02 12:15:43 +0000
NSDateFormatter * dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormatter1 setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"];
NSDate *dateConverted1 = [dateFormatter1 dateFromString:#"2013-12-02T12:15:43.182Z"];
NSLog(#"%#",dateConverted1);
Date: 2013-12-02 06:45:43 +0000
The problem with the 2nd format is all of the needless quotes, especially around the Z. By quoting the Z this means the Z is treated as a literal character and not the timezone format specifier.
Get rid of the quotes around the Z and both will give the same result.
The second date formatter is incorrect, the 'Z' should not be single quoted, that keeps it from being considered a format character.
Also the only single quotes that are needed are around the 'T' so that is is not considered a format character but rather a literal.
See ICU User Guide: Formatting Dates and Times

Difference between 'YYYY' and 'yyyy' in NSDateFormatter

What is exact difference between 'YYYY' and 'yyyy'. I read in this link, it states that
A common mistake is to use YYYY. yyyy specifies the calendar year
whereas YYYY specifies the year (of “Week of Year”), used in the ISO
year-week calendar. In most cases, yyyy and YYYY yield the same
number, however they may be different. Typically you should use the
calendar year.
But when I try to use
NSString *stringDate = #"Feb 28, 2013 05:30pm";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd, yyyy hh:mma"];
NSDate *date=[dateFormatter dateFromString:stringDate];
NSLog(#"Date 1 : %#",date); //2013-02-28 12:00:00 +0000
NSString *stringDatee = #"Feb 28, 2013 05:30pm";
NSDateFormatter *dateFormatterr = [[NSDateFormatter alloc] init];
[dateFormatterr setDateFormat:#"MMM dd, YYYY hh:mma"];
NSDate *datee=[dateFormatterr dateFromString:stringDatee];
NSLog(#"Date 2 : %#",datee); //2013-01-05 12:00:00 +0000
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM dd, YYYY hh:mma"];
NSString *dateString = [dateFormat stringFromDate:datee];
NSLog(#"date 3 : %#", dateString); //Jan 05, 2013 05:30PM
As here, result to date and datee different, which I understood, but why result of date 2 and date 3 are different? As I am creating date from string and reversing same to string again, but output mismatches?
Has anybody knows reason about same?. Though it specifies week of year, still I should get result same.
Thanks..
EDIT :-
If I code
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM dd, YYYY hh:mma"];
NSString *dateString = [dateFormatterr stringFromDate:[NSDate date]];
NSLog(#"date: %#", dateString); //Feb 28, 2013 04:37PM
If results me proper result, but same which I pass as string to date I get 2013-01-05 12:00:00 +0000, check date 2 of NSLog, Strange result, why?
Also when using a date format string using the correct format is important.
#"YYYY" is week-based calendar year.
#"yyyy" is ordinary calendar year.
You can go through the whole blog, its a good to give it a look
https://web.archive.org/web/20150423093107/http://realmacsoftware.com/blog/working-with-date-and-time
http://realmacsoftware.com/blog/working-with-date-and-time (dead link)
A common mistake is to use
YYYY. yyyy specifies the calendar year whereas YYYY specifies the year
(of “Week of Year”), used in the ISO year-week calendar. In most
cases, yyyy and YYYY yield the same number, however they may be
different. Typically you should use the calendar year.
from Apple Docs
dd/MMM/YYYY - e.g.:1 01/Jan/2000; answer : 19/dec/1999
(see weekly calendar December month last Monday
suppose leaf year + 1 day)
dd/MMM/yyyy - eg: ordinary - no problem.
All answers differentiating yyyy and YYYY are right answers for another question. The question itself refers to another thing.
Why does these two values are different? (extracted from question)
NSLog(#"Date 2 : %#",datee); //2013-01-05 12:00:00 +0000
NSLog(#"Date 3 : %#", dateString); //Jan 05, 2013 05:30PM
The answer here #P.J is that they are not really different in value. When you log an NSDate (which is Date 2) you are getting the full description of your object which happens to be on UTC Timezone. This logic does not happen when logging Date 3 because it was already converted to a String and applied your Timezone.
For printing Date 3 the 'same way' as you are getting Date 2. You should specify UTC TimeZone for Date 3. Something like this :
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM dd, YYYY hh:mma"];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSString *dateString = [dateFormat stringFromDate:datee];
NSLog(#"date 3 : %#", dateString);
Hope this helps.
tl;dr the Timezone

NSDateFormatter doesn't show time zone abbreviation for "Asia/Kolkata" for the "z" or "zzz" specifier, just the GMT offset

On iOS5 simulator and device, NSDateFormatter doesn't show time zone abbreviation for "Asia/Kolkata" for the "z" or "zzz" specifier.
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"Asia/Kolkata"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"z"; // or #"zzz"
dateFormatter.timeZone = timeZone;
NSLog(#"date string: %#", [dateFormatter stringFromDate:[NSDate date]]); // "GMT+05:30", expected "IST"
NSLog(#"time zone abbreviation: %#", [timeZone abbreviationForDate:[NSDate date]]); // "IST"
I expect the above code to output:
IST
IST
but it outputs:
GMT+05:30
IST
EDIT
Setting the locale to an indian locale doesn't seem to help.
NSLocale *indianEnglishLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_IN"] autorelease];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"Asia/Kolkata"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:indianEnglishLocale];
[dateFormatter setDateFormat:#"z"]; // or #"zzz"
[dateFormatter setTimeZone:timeZone];
NSLog(#"date string: %#", [dateFormatter stringFromDate:[NSDate date]]); // "GMT+05:30", expected "IST"
NSLog(#"time zone abbreviation: %#", [timeZone abbreviationForDate:[NSDate date]]); // "IST"
I expect the above code to output:
IST
IST
but it outputs:
GMT+05:30
IST
Is this a bug? Am I doing something wrong? People have mentioned that NSDateFormatter has bugs, especially when a time zone is specified in the format string. Could this be one of those bugs?
From http://www.cocoabuilder.com/archive/cocoa/310977-nsdateformatter-not-working-on-ios-5.html#311281
The change in parsing of abbreviated time zone names in iOS 5.0 is a
result of an intentional change in the open-source ICU 4.8 library
(and the open-source CLDR 2.0 data that it uses), a modified version
of which is used to implement some of the NSDateFormatter
functionality.
The issue is this: With the short timezone formats as specified by z
(=zzz) or v (=vvv), there can be a lot of ambiguity. For example, "ET"
for Eastern Time" could apply to different time zones in many
different regions. To improve formatting and parsing reliability, the
short forms are only used in a locale if the "cu" (commonly used) flag
is set for the locale. Otherwise, only the long forms are used (for
both formatting and parsing).
For the "en" locale (= "en_US"), the cu flag is set for metazones such
as Alaska, America_Central, America_Eastern, America_Mountain,
America_Pacific, Atlantic, Hawaii_Aleutian, and GMT. It is not set
for Europe_Central.
However, for the "en_GB" locale, the cu flag is set for
Europe_Central.
So a formatter set for short timezone style "z" or "zzz" and locale
"en" or "en_US" will not parse "CEST" or "CET", but if the locale is
instead set to "en_GB" it will parse those. The "GMT" style will be
parsed by all.
If the formatter is set for the long timezone style "zzzz", and the
locale is any of "en", "en_US", or "en_GB", then any of the following
will be parsed, because they are unambiguous: "Pacific Daylight Time"
"Central European Summer Time" "Central European Time"
Hope this helps.
Peter Edberg
From http://www.cocoabuilder.com/archive/cocoa/313301-nsdateformatter-not-working-on-ios-5.html#313301
Heath,
Yes, you are correct, for the example you provided above,
[dateFormatter stringFromDate:[NSDate date]] should use the short
time zone name "IST". The fact that it does not is due to a deficiency
in the "en_IN" locale data in the versions of CLDR data used by ICU in
the current OSX and iOS releases (CLDR 1.9.1 and 2.0 respectively).
The "en_IN" locale in those CLDR versions did not override or
supplement any of the timezone name data from the base "en" locale,
whose default content is for "en_US".
This is already fixed for the CLDR 21 release coming in a few days.
That is being incorporated into ICU 49 which will be picked up in
future OSX and iOS releases.
Peter E
---Edit---
According to the unicode documentation on formats and their rules, the V format may have been a better choice:
...the same format as z, except that metazone timezone abbreviations are to be displayed if available, regardless of the value of [the] commonlyUsed [flag].
In my case, for the following code:
NSLocale *indianEnglishLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_IN"] autorelease];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"Asia/Kolkata"];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:indianEnglishLocale];
[dateFormatter setDateFormat:#"V"];
[dateFormatter setTimeZone:timeZone];
NSLog(#"V date string: %#", [dateFormatter stringFromDate:[NSDate date]]);
I receive the following output:
V date string: IST

Resources