Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display date with human language like "Today at xx:xx pm", "Yesterday at xx:xx am"?

I have a date "2014-07-02 20:57:38 +0000" and I want to format it as "Today at 8:57 pm". I want that if a string is yesterday, then display it as "Yesterday at 9:00 am". If it is neither today or yesterday, just show the actually date like "27/6 at 7:53 pm".

I was able to get the time with format like "8:57 AM" with the code below.

            var formatter : NSDateFormatter = NSDateFormatter()             formatter.dateFormat = "h:mm a"              // message.createdAt is the date             let dateString = formatter.stringFromDate(message.createdAt)             println(dateString)              //output = 8:57 AM 

However, when I use the following code, it returns a blank string.

            var formatter : NSDateFormatter = NSDateFormatter()             formatter.dateFormat = "h:mm a"             formatter.doesRelativeDateFormatting = true  //<-- This doesn't work              let dateString = formatter.stringFromDate(message.createdAt)             println(dateString)              //output = (nothing, its a blank string) 

How do I make this work and display "Today" or "Yesterday" in Swift?

like image 518
Henry Ngan Avatar asked Jul 02 '14 21:07

Henry Ngan


2 Answers

The reason it's blank is that your date format only has time components. Combined with .doesRelativeDateFormatting that gives you the empty string. If you want that custom time format, I think you need separate formatters for the date and the time:

let now = NSDate()  let dateFormatter = NSDateFormatter() dateFormatter.dateStyle = .MediumStyle dateFormatter.doesRelativeDateFormatting = true  let timeFormatter = NSDateFormatter() timeFormatter.dateFormat = "h:mm a"  let time = "\(dateFormatter.stringFromDate(now)), \(timeFormatter.stringFromDate(now))" println(time)      // prints "Today, 5:10 PM" 
like image 62
Nate Cook Avatar answered Sep 22 '22 16:09

Nate Cook


With Swift 5.1, Apple Developer API Reference states about DateFormatter's dateFormat property:

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.


The following Playground sample code shows how to display your dates in the desired format using dateStyle, timeStyle and doesRelativeDateFormatting properties:

import Foundation  let now = Date() // 2019-08-09 12:25:12 +0000 let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: now)! // 2019-08-08 12:25:12 +0000 let aWeekAgo = Calendar.current.date(byAdding: .weekOfMonth, value: -1, to: now)! // 2019-08-02 12:25:12 +0000  let dateFormatter = DateFormatter() dateFormatter.dateStyle = .long dateFormatter.timeStyle = .short dateFormatter.doesRelativeDateFormatting = true  let nowString = dateFormatter.string(from: now) print(nowString) // prints: Today at 2:25 PM  let yesterdayString = dateFormatter.string(from: yesterday) print(yesterdayString) // prints: Yesterday at 2:25 PM  let aWeekAgoString = dateFormatter.string(from: aWeekAgo) print(aWeekAgoString) // prints: August 2, 2019 at 2:25 PM 
like image 30
Imanou Petit Avatar answered Sep 20 '22 16:09

Imanou Petit