18

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.

Community
  • 1
  • 1
Andrius Steponavičius
  • 8,074
  • 3
  • 22
  • 25

3 Answers3

58

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.

vadian
  • 274,689
  • 30
  • 353
  • 361
1

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
Nishant
  • 12,529
  • 9
  • 59
  • 94
1

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()
Chris M
  • 316
  • 3
  • 9