If your iOS device is set to use a region that defaults to 12 hour time (e.g. United States) and you have a DateFormatter
set up like this:
var date
From the documentation for dateFormat on DateFormatter:
You should only set this property when working with fixed format representations, as discussed in Working With Fixed Format Date Representations. For user-visible representations, you should use the dateStyle and timeStyle properties, or the setLocalizedDateFormatFromTemplate(_:) method if your desired format cannot be achieved using the predefined styles; both of these properties and this method provide a localized date representation appropriate for display to the user.
I still don't really understand why Foundation bothers to modify the date format if you're not using a fixed locale on your date formatter, but it seems the documentation does not recommend using the custom date format for non-fixed format representations.
setLocalizedDateFormatFromTemplate
appears to be what you need if you can't just rely on dateStyle
and timeStyle
, although it doesn't appear to automatically change with a user's 24 hour time setting, so one could check to see if 24 hour time is on before specifying a template…
This method is supposed to allow you to specify a format without losing out on the formatting that is specific to each locale.
EDIT response from Apple Developer Relations (same idea, but more detail):
The correct way to handle this is to avoid specifying "hh" or "HH" based on locale and instead using the "jj" skeleton symbol in conjunction with
-[NSDateFormatter setLocalizedDateFormatFromTemplate:]
.From the "hour" section of the Date Field Symbol Table (https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-hour):
Input skeleton symbol In such a context, it requests the preferred hour format for the locale (h, H, K, or K), as determined by the preferred attribute of the hours element in the supplemental data.
By using "jj" you can get a format which best matches the user's current settings:
NSDateFormatter *formatter = [NSDateFormatter new]; [formatter setLocalizedDateFormatFromTemplate:@"jj:mm"]; NSLog(@"%@: 'jj:mm' => '%@' ('%@')", formatter.locale.localeIdentifier, formatter.dateFormat, [formatter stringFromDate:[NSDate date]]);
results in
- en_US (12-hour): "en_US: 'jj:mm' => 'h:mm a' ('1:44 PM')
- en_US (24-hour): "en_US: 'jj:mm' => 'HH:mm' ('13:44')
- en_GB (12-hour): "en_GB: 'jj:mm' => 'h:mm a' ('1:44 pm')
- en_GB (24-hour): "en_GB: 'jj:mm' => 'HH:mm' ('13:44')
This allows you to match your preferred format while keeping with the user's preferred time settings.