I'm seeing a problem with NSDateFormatter on iOS when Settings/General/International/Calendar is set to either Japanese or Buddhist on both the simulator and a real device. The year is not parsed correctly
DateFormatter
static NSDateFormatter *formatter = nil; // cache this the first time through
if (formatter == nil) {
formatter = [NSDateFormatter new];
formatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease]; // Fix for QC79748 - Michael Marceau
formatter.dateFormat = #"EEE, d MMM yyyy HH:mm:ss zzz";
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"EST"];
formatter.calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
formatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]] autorelease];
}
NSLog(#"CorrectDate%#",[serviceHeaders safeObjectForKey:#"Date"] );
NSLog(#"Formatted date:%#",[formatter dateFromString:[serviceHeaders safeObjectForKey:#"Date"]]);
Output
Correct - Mon, 27 Aug 2012 16:33:14 GMT
Formatted date:0024-08-27 16:33:14 +0000
This is working just as it should. I took your code and added it to my project, then set the Simulator to use the Buddhist calendar.
NSLog(#"date=%#", [NSDate date]);
2012-08-27 18:42:10.201 Searcher[43537:f803] date=2555-08-27 22:42:10 +0000
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"]; // Fix for QC79748 - Michael Marceau
formatter.dateFormat = #"EEE, d MMM yyyy HH:mm:ss zzz";
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"EST"];
formatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
//formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]];
Then the output:
NSLog(#"CorrectDate%#", #"Mon, 27 Aug 2012 16:33:14 GMT" );
2012-08-27 18:42:10.203 Searcher[43537:f803] CorrectDateMon, 27 Aug 2012 16:33:14 GMT
NSLog(#"Formatted date:%#",[formatter dateFromString:#"Mon, 27 Aug 2012 16:33:14 GMT"]);
2012-08-27 18:42:10.206 Searcher[43537:f803] Formatted date:2555-08-27 16:33:14 +0000
Analysis:
Its all working perfectly. In the Buddhist calendar, the year is 2555 now. When you provide a Gregorian date, and ask the formatter to use the Gregorian calendar, it reads it in properly, then converts it to the Buddhist date, and when you print that out, the date is 2555 again. Just what you would expect.
EDIT: Just to press the point, the NSDate is always the same, what changes is the representation of it. So I set the calendar to Buddhist again, and used your formatter to get the current time in Gregorian time:
NSLog(#"date=%#", [NSDate date]);
NSLog(#"Date using the Gregorian calendar: %#", [formatter stringFromDate:[NSDate date]]);
outputs
2012-08-28 07:13:10.658 Searcher[69194:f803] date=2555-08-28 11:13:10 +0000
2012-08-28 07:13:10.660 Searcher[69194:f803] Date using the Gregorian calendar: Tue, 28 Aug 2012 07:13:10 EDT
PS: your code sets locale twice.
Related
I tried to add one day from November 3rd with timezone like dallas, but i can't do it.
NSDate *intime = #"2013-11-03 05:00:00 +0000";
NSDate *nextday= [NSDate dateWithTimeInterval:24*3600 sinceDate:intime];
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSString *convert=[formatter stringFromDate:nextday];
NSLog(#"convert:%#",convert);
Nslog values:
intime: 2013-11-03 05:00:00 +0000
nextday: 2013-11-04 05:00:00 +0000
convert: 11/03/2013 23:00:00 // but I need this 11/04/2013.
Please let me know, how to do that,
Thanks in advance
The problem is with the intime - you have to use formatter to initialize a NSDate from string. So my tested example would be:
// NSDate *intime = #"2013-11-03 05:00:00 +0000"; // wrong
NSString *str =#"2013-11-03 05:00:00 +0000";
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSDate *intime = [formatter dateFromString:str];
NSDate *nextday= [NSDate dateWithTimeInterval:24*3600 sinceDate:intime];
NSDateFormatter *formatter2=[[NSDateFormatter alloc]init];
[formatter2 setDateFormat:#"MM/dd/yyyy"];
NSString *convert=[formatter2 stringFromDate:nextday];
NSLog(#"%#, %#, %#", intime, nextday, convert);
The output is:
2013-08-08 15:03:23.762 2013-11-03 05:00:00 +0000, 2013-11-04 05:00:00 +0000, 11/04/2013
One small comment: by default XCode writes out these kind of problems with the code when showing issues is switched on (Preferences->General->Show live issues).
Eg. in this case XCode warns you with this issue: Incompatible pointer types initializing 'NSDate *__strong' with an expression of type 'NSString *'
Input: Fri, 26 Apr 2013 21:56:31 EDT
NSDateFormatter *df1 = [[NSDateFormatter alloc] init];
[df1 setDateFormat:#"EE, dd MMM YYYY HH:mm:ss zzz"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSString *startDateStr2 = [df1 stringFromDate:[NSDate date]];
NSLog(#"currentDate: %#", startDateStr2);
but i am getting output : Sat, 05 Jan 2013 07:26:31 GMT+05:30
Use below method which is used to change the format of the NSDate..
-(NSString *)changeDateFormat:(NSString*)stringDate dateFormat:(NSString*)dateFormat getwithFormat:(NSString *)getwithFormat{
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:dateFormat];
NSDate *date = [dateFormatter dateFromString:stringDate];
dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:getwithFormat];
NSString *convertedString = [dateFormatter stringFromDate:date];
NSLog(#"Converted String : %#",convertedString);
return convertedString;
}
Call above method with its 3 parameters..
1. stringDate : Pass your date which in string type.
2. dateFormat : set format which is used in your passed string date. For example, if your string date is "14-03-2013 11:22 am" then set the format to #"dd-MM-yyyy hh:mm a".
3. getwithFormat : Set format which you want, as if you want date 14/03/2013 then just set format #"dd/MM/yyyy".
How to call this see below example with method:
NSString *strSDate = [self changeDateFormat:#"14-03-2013 11:22 am" dateFormat:#"dd-MM-yyyy hh:mm a" getwithFormat:#"dd/MM/yyyy"];
NSLog(#"\n\n Now Date => %#",strSDate);
Output is : Now Date => 14/03/2013
hope its helpful to you...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
NSString to NSDate
I have a date in format Mon Jan 14 14:00:00 CET 2013 I try to convert it to NSDate:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"EEE MMM dd HH:mm:ss zzz y"];
NSString *dateString = #"Mon Jan 14 14:00:00 CET 2013"
NSDate *date = [df dateFromString:dateString];
but it doesn't work and my date is nil
Input data is in en-GB locale, my device's locale is nb-NO
Any suggestions?
You're missing day in your format:
[df setDateFormat:#"EEE MMM dd HH:mm:ss zzz y"];
If it was not a typo, then next thing is to set proper locale so formatter will recognise CET timezone, for example en-GB will fix that:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
// that will fix the problem with not recognized CET timezone
[df setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en-GB"]];
[df setDateFormat:#"EEE MMM dd HH:mm:ss zzz y"];
NSString *dateString = #"Mon Jan 14 14:00:00 CET 2013"
NSDate *date = [df dateFromString:dateString];
Try to use this function
- (NSDate*) dateFromString:(NSString*)aStr
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"] autorelease]];
//[dateFormatter setDateFormat:#"YYYY-MM-dd HH:mm:ss a"];
[dateFormatter setDateFormat:#"MM/dd/yyyy HH:mm:ss a"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSLog(#"%#", aStr);
NSDate *aDate = [dateFormatter dateFromString:aStr];
[dateFormatter release];
return aDate;
}
I hope this will helps u.
I think your Time Zone is wrong. Just use this code , it will work Perfectly :
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"EEE MMM dd HH:mm:ss zzz y"];
NSString *dateString = #"Mon Jan 14 14:00:00 EDT 2013";
NSDate *date = [df dateFromString:dateString];
NSLog(#"date :: %#",date);
It will log Output as :
date :: 2013-01-14 18:00:00 +0000
EDIT :
I found Something for you : NSDateFormatter doesn't parse some timezones
You can solve this by using en_GB Locale , as stated : "These abbreviations do still work with the en_GB locale" in Working with Date and Time in Cocoa .
CET is not recognised
Try this :-
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"EEE MMM dd HH:mm:ss yyyy"];
NSString *dateString = #"Mon Jan 14 14:00:00 2013";
NSDate *date = [df dateFromString:dateString];
NSLog(#"%#",date);
Hope it helps you
Simply "CET" is not a recognized time zone by NSDateFormatter.
Also the date/tine is over specified, best to not try include the day or week (Mon).
Here is an example that demonstrates working code with a recognized timezone:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"EEE MMM dd HH:mm:ss zzz yyyy"];
NSString *dateString = #"Mon Jan 14 14:00:00 EST 2013";
NSDate *date = [df dateFromString:dateString];
NSLog(#"date: %#", date);
NSLog output
date: 2013-01-14 19:00:00 +0000
NSLog(#"abbreviationDictionary: %#", [NSTimeZone abbreviationDictionary]);
does show
CET = "Europe/Paris";
so this looks like an Apple bug in NSDateFormatter.
Report the bug at: Apple Bug Reporter
You can use:
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
If you still want to custom your date format try this one:
yyyy-MM-dd HH:mm:ss ZZZ
Because can't invent your own formatted string syntax and expect it to work; you need to actually use a documented format as the documentation points it out : Formatters in OS X v10.8 and iOS 6.0 use version tr35-25.
-> https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html
If you are curious: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
How can I get my NSDate to display in the format for example i.e "Tue Feb 26, 2011"
Do it right. Don't hardcode your date formats. There are countries that are not your country and they might have different date formats. So if you want to show this date to the user you should use a method that takes the users locale into account.
You could use the dateFormatFromTemplate:options:locale: method introduced in iOS4 to get the appropriate format with all the information you want.
And if you have to support iOS < 4 you should create a plist with this template method to create the correct date format for the user locale.
NSLocale *locale = [NSLocale currentLocale];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:#"E MMM d yyyy" options:0 locale:locale];
[formatter setDateFormat:dateFormat];
[formatter setLocale:locale];
NSLog(#"Formatted date: %#", [formatter stringFromDate:myDate]);
gives So., 27. Feb 2011 for my locale.
and Sun, Feb 27, 2011 for the en_US locale
NSDateFormatter *gmtFormatter = [[NSDateFormatter alloc] init];
[gmtFormatter setDateFormat:#"E MMM d yyyy"];
I need the date as a string but not the time and it has to be localized.
So for example USA should be Sep 25 2009 but for New Zealand it would be 25 Sep 2009.
I can get the date into a string by specifying the format "MMM dd YYYY" but It's not localized.
Any ideas?
[NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterMediumStyle
timeStyle:0]
The key is to send setTimeStyle:kCFDateFormatterNoStyle to the dateFormatter. That sets the dateFormatter so that it will only format the date and not output the time:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale: [NSLocale currentLocale]];
[dateFormatter setDateStyle:kCFDateFormatterShortStyle]; // or whichever style...
[dateFormatter setTimeStyle:kCFDateFormatterNoStyle];
NSString* dateString = [dateFormatter stringFromDate: [NSDate date]];
This gives me the following output:
12/18/09