31

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?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Henry Ngan
  • 572
  • 1
  • 4
  • 24

3 Answers3

51

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"
Nate Cook
  • 92,417
  • 32
  • 217
  • 178
  • 4
    Actually you only need one. You can do it like: var formatter : NSDateFormatter = NSDateFormatter() formatter.dateStyle = NSDateFormatterStyle.ShortStyle formatter.timeStyle = NSDateFormatterStyle.ShortStyle formatter.doesRelativeDateFormatting = true var dateString = formatter.stringFromDate(NSDate()) – Daniel Alexandrov Jul 02 '14 at 21:54
  • 1
    This solution does not provide the correct time for most time zones and summer/winter times. See Incyc solution below. – Vincent Dec 02 '15 at 18:23
19

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
Imanou Petit
  • 89,880
  • 29
  • 256
  • 218
13

Give this a try in Swift:

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true

let date = Date()
let dateString = dateFormatter.string(from:date)
pkamb
  • 33,281
  • 23
  • 160
  • 191
James Kuang
  • 10,710
  • 4
  • 28
  • 38