Here is how I am localising days:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSString *dayFormat = [NSDateFormatter dateFormatFromTemplate:#"EEEE" options:0 locale:[NSLocale currentLocale]];
[dateFormatter setDateFormat:dayFormat];
[dateFormatter setLocale:[NSLocale currentLocale]];
NSString *day = [dateFormatter stringFromDate:date];
And yet it seems to be returning English days of the week (Monday, Tuesday etc) rather than the device language (which has been set to German in the simulator).
Any idea where I'm going wrong?
Update after doing some research on device I've realised that its actually the region setting, not the language setting which changes the date language. Odd, but I guess its done for a reason.
Thanks
The language of the date is set by the region not the language. This has to be a bug. If I'm in Germany, but an English speaker I don't want to have my dates in German, surely?
Anyway, this is why. You have to change language and region.
I've had the same issue. It wouldn't work on the simulator, but it would on a device. Can you try it ? I did not however solve it, I did not even look more into it as it was working perfectly on the device, which is truly the main target of your app.
Edit:
This comes from Apple's doc:
currentLocale
Returns the logical locale for the current user.
+ (id)currentLocale
Return Value
The logical locale for the current user. The locale is formed from the settings for the current user’s chosen system locale overlaid with any custom settings the user has specified in System Preferences.
Discussion
Settings you get from this locale do not change as a user’s
Preferences are changed so that your operations are consistent.
Typically you perform some operations on the returned object and then
allow it to be disposed of. Moreover, since the returned object may be
cached, you do not need to hold on to it indefinitely. Contrast with
autoupdatingCurrentLocale.
Maybe you can try using:
preferredLanguages
Returns the user's language preference order as an array of strings.
+ (NSArray *)preferredLanguages
Return Value
The user's language preference order as an array of NSString objects, each of which is a canonicalized IETF BCP 47 language identifier.
Related
Our iOS iPhone app contains this code which produced a valid NSDate object below named resultDate in iOS 5:
static NSDateFormatter *invariantFmt = nil;
if (!invariantFmt) {
invariantFmt = [[NSDateFormatter alloc] init];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[invariantFmt setLocale:locale];
[locale release];
[invariantFmt setDateStyle:NSDateFormatterShortStyle];
[invariantFmt setTimeStyle:NSDateFormatterMediumStyle];
}
NSDate *resultDate = [invariantFmt dateFromString:#"08/04/2010 10:43:39 AM"];
After upgrading to XCode 4.6 and iOS 6.1, that code now gives a nil for resultDate, so something has changed with what they use to parse. The release notes says nothing about NSDateFormatter changing. Internet research has turned up only that they might have changed to use a newer Unicode UTS Locale parsing standard. Obviously they changed something. After twiddling with code and taking a known valid NSDate object and applying the same NSDateFormatter settings to get a NSString, I find that iOS 6.1 likes this string instead: #"08/04/2010, 10:43:39 AM"
The only difference being that extra comma after the date portion. Using that in iOS 6.1 gives back a valid date with the same above code. Anyone seeing this and understand why that's different or if that's an ok Unicode change or a Apple bug?
The format styles should only be used to convert NSDate objects to text to display to the user. When parsing a date string in a known format, you must use a specific format, never the styles. The use of the en_US_POSIX locale is used to ensure that the format you specify isn't tweaked by the OS based on user preferences such as the 24-hour time setting.
So, as you suspected, you need to remove the two calls to set the date and time styles and replace them with a call to set a specific format that matches your known date/time string you need to parse.
Generally you should not output a formatted Date to a file, and later want to parse it back.
A Date should be stored as long value UTC (with or without additional TimeZone offset).
Only in the last moment, before visualizing a Date to UI it should be formatted and local time applied.
This not only i smy experience, it it is also stated in Apple DateFormatting Doku.
What am I doing wrong?
I am trying to getNSDateFormatter to translate custom patterns for dates using the current locale.
Example:
dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = [NSLocale currentLocale];
[dateFormat setDateFormat:#"MMM"];
output = [self.dateFormat stringFromDate:dateObject];
No matter what I change my current locale settings to, I always see the English month abbreviations.
Thanks for any help you can provide.
It looks like it was working all of the time. I had been leaving my location set to United States and changing only the language. To get it to work correctly you have to change the location as well as the language.
I want to get current selected iphone language. If using "NSLocale" it returns always the same language. It seems that this is not the one you choose inside iphone settings.
NSLocale * locale = [NSLocale currentLocale];
NSString * localLanguage = [locale objectForKey:NSLocaleLanguageCode];
NSLog (#"Language : %#", localLanguage); // Returns always : "en_US"
How to obtain the current language?
The answer is to check the preferred language :
NSString *preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
This question is old, but the reason is new since upgrading to Xcode 6.1
Due to a bug, the iOS8 simulator's [NSLocale currentLocale] always returns "en_US". It is alright on the device though.
Hence, I recommend doing a test on a real device before bashing your head against a wall in frustration.
Sources: https://stackoverflow.com/a/26510914/3099609
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-DontLinkElementID_23
Locales encapsulate information about linguistic, cultural, and technological conventions and standards.
Your code returns the "Region Format" information, if set "China", it will return "zh".
Settings | General | International | Region Format
See “NSLocale Class Reference” for more information.
To add to what SteamTrout suggested:
To get your language to respond to changes in iPhone settings you're going to want to use autoupdatingCurrentLocale:
https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSLocale_Class/Reference/Reference.html#//apple_ref/occ/clm/NSLocale/autoupdatingCurrentLocale
If you read closely in the currentLocale reference you'll see that this value will not update from the settings panel:
https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSLocale_Class/Reference/Reference.html#//apple_ref/occ/clm/NSLocale/currentLocale
Try [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleLanguageCode]
In particular I'm interested in shortStandaloneWeekdaySymbols. I'm using this code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSArray *shortWeekdaySymbols = [dateFormatter shortStandaloneWeekdaySymbols];
But if iPhone region format is set to US but language to French/German/any other, NSDateFormatter returns English strings (mon tue ...). But I want to respect the language settings and get weekday names in the current language (standard Clock app does this for example). Is this possible?
The only way I can think of to do this would be to get the current user language (how?) and set locale on the date formatter to this language's region.
The only way you can think of, "get the current user language (how?) and set locale on the date formatter to this language's region" is correct. This is how.
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]] autorelease]];
Try to look here
Detecting current iPhone input language
I have a shortage of screen real estate for my time labels in my iPhone app.
My solution is to have the time e.g. 12:00 on one line and then if the users current locale specifies that an AM-PM is used, have these in a second label below it.
Since AM-PM also have localized variants I can't just look for the letters "AM" or "PM", then I thought about stripping the last two letters, but by checking I found out some languages uses a format like this: "F.M." "E.M". My next thought was to strip everything after the first 5 digits(12:34), but for hour intervals below 10 that is no good either.
Is there a "locale safe" way of always removing the localized suffix and move it to a new string, regardless of the users settings?
Thank you in advance:)
There is no locale safe way of doing that.
Use NSDateFormatter to generate two strings.
NSDateFormatter *timeOfDayFormatter = [[[NSDateFormatter alloc] init] retain];
[timeOfDayFormatter setDateFormat:#"hh:mm"];
NSDateFormatter *amPmFormatter = [[[NSDateFormatter alloc] init] retain];
[amPmFormatter setDateFormat:#"aa"];
NSLog(#"Time is: %# %#",
[timeOfDayFormatter stringFromDate:theDate],
[amPmFormatter stringFromDate:theDate]);
Now you can layout your user interface with the two strings.
The 24-hour format is standard where I live. I'd "force" that format on the user if screen real estate is a real problem.
I ended up solving it like this and then manually test it with 15+ locale settings:
NSArray *timeParts = [NSArray arrayWithArray:[[timeFormatter stringFromDate:myDate] componentsSeparatedByString:#" "]];
Then I test the timeParts array:
if ([timeParts count] > 1) {...}
If the count is 1 it is a locale without the suffix and I don't set the "AM/PM" label.
Else, I set both labels, the timeLable with [timeParts objectAtIndex:0] and the localeLabel with [timeParts objectAtIndex:1]
This seems to be a stable solution for all locales.