I am trying to find a way to get time of the day in words. Obviously there is easy way of doing it Application to Display Morning,Evening If you are ok with static words in one language. Is there a way of making it depending on Locale? NSDateComponentsFormatter doesn't seem to do the trick.
-
I guess then that your question isn't really about NSDateFormatter, but about how, given some `enum` that has the values `.Morning` etc., do you return strings based on `NSLocale`? – Grimxn Sep 18 '15 at 10:35
-
Well that could be one of the approaches to take if it is possible – Andrius Steponavičius Sep 18 '15 at 10:40
3 Answers
Unfortunately there is no built-in solution – NSDateFormatter's relative formatting works only on a per day base.
Get the hour with Calendar.current.component(.hour, from: Date())
and use a range switch and NSLocalizedString()
to localize the strings.
For example:
// let hour = NSCalendar.currentCalendar().component(.Hour, fromDate: NSDate()) Swift 2 legacy
let hour = Calendar.current.component(.hour, from: Date())
switch hour {
case 6..<12 : print(NSLocalizedString("Morning", comment: "Morning"))
case 12 : print(NSLocalizedString("Noon", comment: "Noon"))
case 13..<17 : print(NSLocalizedString("Afternoon", comment: "Afternoon"))
case 17..<22 : print(NSLocalizedString("Evening", comment: "Evening"))
default: print(NSLocalizedString("Night", comment: "Night"))
}
Create a file localizable.strings
and add the localizations you need.

- 274,689
- 30
- 353
- 361
Actually, you can set locale in NSDateFormatter
like this:
let df = NSDateFormatter()
df.locale = NSLocale.currentLocale()
This date formatter will help you printing the date in the currentLocale
.
But for what you are expecting, you will have to implement localization in order to get the localized string of the "Morning", "Afternoon", "Night" strings.
At Best, you can do this with your date:
There is a property in NSDateFormatter
- doesRelativeDateFormatting
. It will format a date into a relative date in the correct locale.
From Apple's Documentation:
If a date formatter uses relative date formatting, where possible it replaces the date component of its output with a phrase—such as “today” or “tomorrow”—that indicates a relative date. The available phrases depend on the locale for the date formatter; whereas, for dates in the future, English may only allow “tomorrow,” French may allow “the day after the day after tomorrow,” as illustrated in the following example.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeStyle = NSDateFormatterNoStyle;
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
NSLocale *frLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];
dateFormatter.locale = frLocale;
dateFormatter.doesRelativeDateFormatting = YES;
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:60*60*24*3];
NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(@"dateString: %@", dateString);
// Output
// dateString: après-après-demain

- 12,529
- 9
- 59
- 94
-
I don't understand how that solves my question? I don't need I don't need formatted date, I need formatted time of the day in device locale – Andrius Steponavičius Sep 18 '15 at 10:18
-
This is exactly what I was trying to avoid, if needs to be localised anyway , there is no point using NSDateFormatter anyway, just translate static words – Andrius Steponavičius Sep 18 '15 at 10:24
-
@AndriusSteponavičius: unfortunately there is only so much Apple has provide. – Nishant Sep 18 '15 at 10:29
-
The update doesnt really help either, because that can return next week, tomorrow etc. and this in no way solves the problem – Andrius Steponavičius Sep 18 '15 at 10:39
Here's how I solved the problem using Swift 2. First, I used this article to identify the various parts of the day. From there, I used a series of if/else if statements. I'm curious if someone else can do this using ranges.
//BIG PICTURE SOLUTION
//Step 1: Build a .plist or REST API service or whatever made up of different ways to describe "parts of the day" in different languages.
//http://stackoverflow.com/questions/3910244/getting-current-device-language-in-ios
//List of Language Codes: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
//Step 2: Get the user's local time zone
//Step 3: Calculate whether the user's local time fits within these buckets of time
import Foundation
class DayParts{
var currentHour:Int
var localLang:String?
// IDEA: Build a .plist or a REST API service or whatever that simply returns a dictiontary
let letterCodes:[String:Array<String>] = [
"en": ["Early Morning", "Late Morning", "Early Afternoon", "Late Afternoon", "Evening", "Night"],
"fr": ["Tôt le matin", "Tard dans la matinée", "Début d'après-midi", "Tard dans l'après-midi", "Soir", "Nuit"],
"es": ["Mañana Temprano", "Mañana tarde", "Temprano en la tarde", "Fin de la tarde", "Anochecer", "Noche"]
]
init(){
//A. Get the current time
let date = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH"
//B. Get the current hour
currentHour = Int(dateFormatter.stringFromDate(date))!
//C. Get the current phone language
localLang = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode) as? String
}
func now() -> String {
if(currentHour < 08){
return letterCodes[localLang!]![0]
}
else if(currentHour < 11){
return letterCodes[localLang!]![1]
}
else if( currentHour < 15){
return letterCodes[localLang!]![2]
}
else if( currentHour < 17){
return letterCodes[localLang!]![3]
}
else if(currentHour < 21){
return letterCodes[localLang!]![4]
}
else{
return "Night"
}
}
}
let dayParts = DayParts().now()

- 316
- 3
- 9
-
Yeah this is not a feasable solution,these values not to be hardcoded – Andrius Steponavičius Nov 11 '15 at 15:11
-
I updated it to show you how you can create a REST API or dynamic solution around multiple languages. – Chris M Nov 11 '15 at 17:43