I've recently been working on a French version of our application use NSLocalizedStrings, so far everything is working great.
But my problem now is with dates. I show dates often in my application, in different formats, depending on the situation.
Ex:
-Fri Feb 22, 2013
-Monday February 18, 2013
-Feb 18
-Dec 5, 2012
The thing is, dates in French are not only different in terms of the name of the month, but also the order in which month, day and year appear.
Ex:
-Dec 5, 2012 would be 5 Dec 2012
-Monday February 18, 2013 would be Lundi le 18 Fevrier 2013.
I have the individual month/day names in my Localizable.string files, but how do I manage the order of how it's displayed.
Should I have an if statement that checks the current device language like so?:
NSString *currentLanguage = [[NSLocale preferredLanguages] objectAtIndex:0];
if([currentLanguage isEqualToString:#"fr"])
{
//Handle French logic
}
This is probably not the best way to go about it.
Any ideas?
You should use an NSDateFormatter and feed it your desired NSLocale like this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"nl_NL"];
dateFormatter.dateFormat = #"EEEE d MMMM yyyy HH:mm";
'EEEE' is the full name of the day of the week, which, in my case, will be displayed in dutch.
Use NSDateFormatter. For example:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:162000];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
NSLog(#"formattedDateString: %#", formattedDateString);
NSDateFormatterMediumStyle will automatically format the date according to the user's preference (English, French, etc.).
If you need custom styling and the app runs in iOS 4.0+, you can use a custom template in your date formatter:
NSString *formatString = [NSDateFormatter dateFormatFromTemplate:#"EdMMMyyy" options:0
locale:[NSLocale currentLocale]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:formatString];
NSString *todayString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"todayString: %#", todayString);
Set proper locale to your NSDateFormatter when you convert date to string, then date formatter will handle all specifics of formats depending on user settings for you:
NSDateFormatter *formatter = ... // Create and setup formatter
[formatter setLocale:[NSLocale autoupdatingCurrentLocale]];
// Now you can convert date to string
That's probaly much easier:
There is something which is called
NSDateFormatterShortStyle,
NSDateFormatterMediumStyle
NSDateFormatterLongStyle
Set Date and Time components individually:
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
Ios will format that correctly if the language of the user.
Further look at Data Formatting Guide
I would try the class function localizedStringFromDate:dateStyle:timeStyle: in NSDateFormatter before attempting to use the NSDateFormatter and a template (from Unicode Technical Standard #35):
Example:
[NSDateFormatter localizedStringFromDate:dateTime dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle];
You can select both different date and time outputs of various lengths detailed in the docs.
Apple documentation: NSDateFormatter localizedStringFromDate:dateStyle:timeStyle:
Related
I'm having a problem. I get incoming time strings in 12-hour format, and I'm turning them into NSDate objects. When the iPhone is in 12 hour format, no problem. But when it's in 24 Hour format, things go wrong. Here's some sample code to demonstrate:
NSString *theTime = #"3:19 PM";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"]; // "3:19 PM"
NSDate *date = [formatter dateFromString:theTime];
NSString *theString = [formatter stringFromDate:date];
In 24 hour mode, date is 1970-01-01 03:19:00, and theString is "3:19" - WRONG
In 12 hour mode, date is 1970-01-01 15:19:00, and theString is "3:19 PM" - RIGHT
So... question 1: why is the device's 24 hour setting overriding my date formatter setting?
and more importantly, question 2: How do I get a proper conversion from 12 hour time to 24 hour time?
I already have code to detect if the phone is in 24 hour mode, but other than digging around in the string and swapping the 3 with a 15, there doesn't seem to be a clean way to do this.
Not sure if you still need it, but I've had a similar problem which got solved by setting the locale for the date formatter. That is, if you want to force it to 12-hour mode, regardless of the user's 24/12 hour mode setting, you should set the locale to en_US_POSIX.
The reason for this behaviour is Locale, set the correct Locale
NSString *strAgendaDate = #"01/17/2012 12:00 AM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease];
[dateFormatter setDateFormat:AgendaDateFormatForMeeting];
NSDate *meetingDate = [dateFormatter dateFromString:aStrDate];
[dateFormatter setDateFormat:AgendaDateRepresentation];
strAgendaDate = [dateFormatter stringFromDate:meetingDate];
It works for both 24-hour and 12 hour format
I believe the #"h:mm a" should be #"HH:mm a".
If you use the pre-build dateformatter in cocoa, everything will be taken care of for you.
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
[timeFormatter setDateStyle:NSDateFormatterNoStyle];
NSDateFormatterShortStyle and NSDateFormatterNoStyle comes in different varieties.
Using those will make sure you respect the settings the user has selected for dates and times.
The 12-14 hour clock conversion is taken care of by the SDK, if you have a model or some value object for storing your dates try to keep them as NSDate. This way you can format them only when you need to display them. Saving dates as strings could open a world of trouble when you maybe parse them from xml where the GMT is specified separately or try to add and subtract NSTimeIntervals.
I changed from #"hh:mm:ss" to #"HH:mm:ss" and time style was changed from "1:03 PM" to "13:03".
Hope this will help you.
Okay, I left a comment, but it squished all the code together, so I'll have to "answer" my question with a comment:
Thanks. I gave it a whirl with this code:
NSString *theTime = #"3:19 PM";
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
[timeFormatter setDateStyle:NSDateFormatterNoStyle];
NSDate *date = [timeFormatter dateFromString:theTime];
NSString *theString = [timeFormatter stringFromDate:date];
And date comes up nil. I ran into this earlier when I tried this route, and it's not working. Very frustrating.
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]);
I would like to format a date to display in a uitableview custom cell
The data is passed into the app from a CMS - it is provided as a string in the following format and stored in a date type variable-
2014-04-15 10:10:45 +0000
Our app will initially be UK based - so I need to convert the format into DD/MM/YYYY format.
I tried the following code to parse my date (dateadded which is of type date).
NSDateFormatter *formatter = [NSDateFormatter new];
cellRecP.artDate.text = [formatter stringFromDate:resItem.dateadded];
but this just returns null - i guess the date format provided above is not anything that stringfromdate understands - is there any other way to format date?
Use an 'NSDateFormatter'
NSDateFormatter* newFormatter = [[[NSDateFormatter alloc] init] autorelease];
with this format to parse the string
[newFormatter setDateFormat:#"yyyy-MM-dd hh:mm:ss zzz"];
NSDate* aDate = [newFormatter dateFromString:dateString];
and you should get a valid 'NSDate' object
Try This and also Checkout this All Formate It is really good and helpful.
NSString *yourString = #"2014-04-15 10:10:45 +0000";
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setTimeZone:[NSTimeZone systemTimeZone]];//Set Your Timezone
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];//You have to set this formate.
NSDate *dd = [df dateFromString:yourString];//This will convert into date;
//Now you can set your formate.
[df setDateFormat:#"dd/MM/yyyy"];
NSString *str = [df stringFromDate:dd];
You need an NSDateFormatter and a proper unicode parse string. NSDateFormatter by default automatically checks the device locale setting the correct output.
This is an example from some code of mine:
NSDateFormatter *dateWriter = [[NSDateFormatter alloc] init];
dateWriter.dateFormat = #"yyyy'-'MM'-'dd' 'HH':'mm':'ss' 'ZZZ";
dateWriter.dateStyle = NSDateFormatterMediumStyle;
dateWriter.timeStyle = NSDateFormatterMediumStyle;
Pay attention that date formatters are pretty expensive to create.
I am using NSDateFormatter to convert the current date to a string (in the format: February 16, 2013). How can I convert this string back to a NSDate object?
NSString *dateString = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterLongStyle timeStyle:NSDateFormatterNoStyle];
The problem appears to be that the month is written out (February vs. 02), and other questions only explain to use NSDateFormatter with a format such as MM-dd-yyyy, which I do not believe is possible here. Must I parse this date manually, convert February to 02, and go from there?
You can use dateFromString of the same NSDateFormatter class to perform backward conversion.
To make it work you need to define dateStyle, so parser will know how text string should be parsed. For the date style that you provided code below will work:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
NSDate *date = [dateFormatter dateFromString:#"February 16, 2013"];
NSLog(#"%#", date);
If you want to be able to use localized date formats, you should go with templates
NSString *dateString = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterLongStyle
timeStyle:NSDateFormatterNoStyle];
NSLog(#"%#", dateString);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:[NSDateFormatter dateFormatFromTemplate:#"MMMdY"
options:0
locale:[NSLocale currentLocale]]];
NSLog(#"%#", [dateFormatter dateFromString:dateString]);
Since you have a fixed format that you wish to parse, you must setup the date formatter with the locale of en_US_POSIX. Then you must set he date format to MMMM dd, yyyy. This will pare any date string that has the full month name, the month day, a comma, then the four-digit year.
I have set the locale and timezone but when I format the date, I always get invalid date. The month is always December and year is one less that the specified year. In my case I dont need the day component.
I checked other similar post but it didn't solved the problem.
Any help is appreciated. Thank you.
Here is the code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[dateFormatter setDateFormat:#"MMM YYYY"];
NSDate *formattedDate = [dateFormatter dateFromString:#"Sep 2013"];
NSLog(#"Date: %#", [dateFormatter stringFromDate:formattedDate]);
[dateFormatter release]; dateFormatter = nil;
OUTPUT: Date: Dec 2012
"YYYY" format is used for "Week of Year" based calendars. Use "yyyy" format specifier instead:
[dateFormatter setDateFormat:#"MMM yyyy"];
I just wanted to add something to the great answer by Vladimir. If you do this before setting your locale, it seems that the date formatting goes crazy. What I had to do was to set the locale before setting the new format, and then use the setDateFormat to change the format based on the locale used.So something like this would do:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[NSLocale currentLocale]];//I wanted to set the locale to wherever user is using my app in
[formatter setDateFormat:#"MMM YYYY"];
NSDate *now = [NSDate Date];
NSString *fancyLookingDate = [formatter stringFromDate:now];