How to Get 1 Hour Ago from a Date in iOS Swift

How to get 1 hour ago from a date in iOS swift?

For correct calculations involving NSDate that take into account all edge cases of different calendars (e.g. switching between day saving time) you should use NSCalendar class:

Swift 3+

let earlyDate = Calendar.current.date(
byAdding: .hour,
value: -1,
to: Date())

Older

// Get the date that was 1hr before now
let earlyDate = NSCalendar.currentCalendar().dateByAddingUnit(
.Hour,
value: -1,
toDate: NSDate(),
options: [])

Swift display time ago from Date (NSDate)

If you just want a Time Ago extension for Date go to the bottom of the answer /p>

I'll show you an example just to get seconds ago and after I'll show your extension updated.

Note: you can use directly the date from Pase if you want:

if let pastDate = (object?["createdAt"] as? Date) {
cell.TimeAgo.text = pastDate.timeAgoDisplay()
}

Since Swift 5.1

Example how to display seconds ago with Swift 5.1:

Since iOS13 Apple introduce a new class RelativeDateTimeFormatter

extension Date {
func timeAgoDisplay() -> String {
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
return formatter.localizedString(for: self, relativeTo: Date())
}
}

This class will allow you to get a time ago string based on your language. It automatically select the right unit of time based on your interval, here is an example:

|--------------------------|------------------|
| Time interval in seconds | Display |
|--------------------------|------------------|
| -6 | 6 seconds ago |
| -60 | 1 minute ago |
| -600 | 10 minutes ago |
| -6000 | 1 hour ago |
| -60000 | 16 hours ago |
|--------------------------|------------------|

You'll notice that it handle automatically plurals for you.

Swift 3 or Swift 4

Example how to get seconds ago with Swift 3 or Swift 4:

First: To get the number of seconds ago we need to check if we have one minutes or less, to get the current Date minus one minute you can write that:

let minuteAgo = calendar.date(byAdding: .minute, value: -1, to: Date())!

Second: Now compare the 2 dates! (In the case of your extension we replace yourDate by self) and get the difference between this 2 dates.

if (minuteAgo < yourDate) {
let diff = Calendar.current.dateComponents([.second], from: yourDate, to: Date()).second ?? 0
print("\(diff) sec ago")
}

That's all, now you can print the time ago !

So your extension is like this:
(This is a simple extension to get the time ago)

extension Date {
func timeAgoDisplay() -> String {

let calendar = Calendar.current
let minuteAgo = calendar.date(byAdding: .minute, value: -1, to: Date())!
let hourAgo = calendar.date(byAdding: .hour, value: -1, to: Date())!
let dayAgo = calendar.date(byAdding: .day, value: -1, to: Date())!
let weekAgo = calendar.date(byAdding: .day, value: -7, to: Date())!

if minuteAgo < self {
let diff = Calendar.current.dateComponents([.second], from: self, to: Date()).second ?? 0
return "\(diff) sec ago"
} else if hourAgo < self {
let diff = Calendar.current.dateComponents([.minute], from: self, to: Date()).minute ?? 0
return "\(diff) min ago"
} else if dayAgo < self {
let diff = Calendar.current.dateComponents([.hour], from: self, to: Date()).hour ?? 0
return "\(diff) hrs ago"
} else if weekAgo < self {
let diff = Calendar.current.dateComponents([.day], from: self, to: Date()).day ?? 0
return "\(diff) days ago"
}
let diff = Calendar.current.dateComponents([.weekOfYear], from: self, to: Date()).weekOfYear ?? 0
return "\(diff) weeks ago"
}
}

To use it, this is very straightforward:

var now = Date()
now.timeAgoDisplay()

Swift convert time to time ago

I'll just update the Truongky's answer for Swif 3:

extension Date {

func getElapsedInterval() -> String {

let interval = Calendar.current.dateComponents([.year, .month, .day], from: self, to: Date())

if let year = interval.year, year > 0 {
return year == 1 ? "\(year)" + " " + "year ago" :
"\(year)" + " " + "years ago"
} else if let month = interval.month, month > 0 {
return month == 1 ? "\(month)" + " " + "month ago" :
"\(month)" + " " + "months ago"
} else if let day = interval.day, day > 0 {
return day == 1 ? "\(day)" + " " + "day ago" :
"\(day)" + " " + "days ago"
} else {
return "a moment ago"

}

}
}

If you prefer a localizable response instead of only english this code will do the work

extension Date {
func getElapsedInterval() -> String {

var calendar = Calendar.current
calendar.locale = Locale(identifier: Bundle.main.preferredLocalizations[0])
// IF THE USER HAVE THE PHONE IN SPANISH BUT YOUR APP ONLY SUPPORTS I.E. ENGLISH AND GERMAN
// WE SHOULD CHANGE THE LOCALE OF THE FORMATTER TO THE PREFERRED ONE
// (IS THE LOCALE THAT THE USER IS SEEING THE APP), IF NOT, THIS ELAPSED TIME
// IS GOING TO APPEAR IN SPANISH

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.maximumUnitCount = 1
formatter.calendar = calendar

var dateString: String?

let interval = calendar.dateComponents([.year, .month, .weekOfYear, .day], from: self, to: Date())

if let year = interval.year, year > 0 {
formatter.allowedUnits = [.year] //2 years
} else if let month = interval.month, month > 0 {
formatter.allowedUnits = [.month] //1 month
} else if let week = interval.weekOfYear, week > 0 {
formatter.allowedUnits = [.weekOfMonth] //3 weeks
} else if let day = interval.day, day > 0 {
formatter.allowedUnits = [.day] // 6 days
} else {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: Bundle.main.preferredLocalizations[0]) //--> IF THE USER HAVE THE PHONE IN SPANISH BUT YOUR APP ONLY SUPPORTS I.E. ENGLISH AND GERMAN WE SHOULD CHANGE THE LOCALE OF THE FORMATTER TO THE PREFERRED ONE (IS THE LOCALE THAT THE USER IS SEEING THE APP), IF NOT, THIS ELAPSED TIME IS GOING TO APPEAR IN SPANISH
dateFormatter.dateStyle = .medium
dateFormatter.doesRelativeDateFormatting = true

dateString = dateFormatter.string(from: self) // IS GOING TO SHOW 'TODAY'
}

if dateString == nil {
dateString = formatter.string(from: self, to: Date())
}

return dateString!
}

How to calculate days, hours, minutes from now to certain date in swift

You need to find out when is the next birth date based on the day and month of birthday. You can use Calendar's method nextDate(after: Date, matching: DateComponents)

func nextDate(after date: Date, matching components: DateComponents, matchingPolicy: Calendar.MatchingPolicy, repeatedTimePolicy: Calendar.RepeatedTimePolicy = default, direction: Calendar.SearchDirection = default) -> Date?

let birthDateCoponents = DateComponents(month: 4, day: 16)
let nextBirthDate = Calendar.current.nextDate(after: Date(), matching: birthDateCoponents, matchingPolicy: .nextTime)!

let difference = Calendar.current.dateComponents([.day, .hour, .minute, .second], from: Date(), to: nextBirthDate)

difference.day // 105
difference.hour // 2
difference.minute // 5
difference.second // 30

When displaying it to the user you can use DateComponentsFormatter with the appropriate unitsStyle. You can see below how it would look like when using .full style and limiting the units to .day, .hour, .minute, .second:

let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.day, .hour, .minute, .second]

formatter.unitsStyle = .full
formatter.string(from: Date(), to: nextBirthDate) // "105 days, 1 hour, 44 minutes, 36 seconds"

How to get the current time as datetime

Update for Swift 3:

let date = Date()
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date)
let minutes = calendar.component(.minute, from: date)

I do this:

let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute, fromDate: date)
let hour = components.hour
let minutes = components.minute

See the same question in objective-c How do I get hour and minutes from NSDate?

Compared to Nate’s answer, you’ll get numbers with this one, not strings… pick your choice!

Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift

Xcode 8.3 • Swift 3.1 or later

You can use Calendar to help you create an extension to do your date calculations as follow:

extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}

Using Date Components Formatter

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = .full
dateComponentsFormatter.string(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"


let date1 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date2 = DateComponents(calendar: .current, year: 2015, month: 8, day: 28, hour: 5, minute: 9).date!

let years = date2.years(from: date1) // 0
let months = date2.months(from: date1) // 9
let weeks = date2.weeks(from: date1) // 39
let days = date2.days(from: date1) // 273
let hours = date2.hours(from: date1) // 6,553
let minutes = date2.minutes(from: date1) // 393,180
let seconds = date2.seconds(from: date1) // 23,590,800

let timeOffset = date2.offset(from: date1) // "9M"

let date3 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date4 = DateComponents(calendar: .current, year: 2015, month: 11, day: 28, hour: 5, minute: 9).date!

let timeOffset2 = date4.offset(from: date3) // "1y"

let date5 = DateComponents(calendar: .current, year: 2017, month: 4, day: 28).date!
let now = Date()
let timeOffset3 = now.offset(from: date5) // "1w"

Swift How to convert Parse createdAt time to time ago?

You can use NSCalendar isDateInToday to check if createdAt date is in same day as today, and use isDateInYesterday to check if it was yesterday. Just add a conditional and return a custom string for those conditions, for all other conditions just let date components formatter take care of it for you.

extension Formatter {
static let time: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .gregorian)
formatter.dateFormat = "h:mm a"
return formatter
}()
static let dateComponents: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.unitsStyle = .full
formatter.maximumUnitCount = 1
formatter.zeroFormattingBehavior = .default
formatter.allowsFractionalUnits = false
formatter.allowedUnits = [.year, .month, .weekOfMonth, .day, .hour, .minute, .second]
return formatter
}()
}

extension Date {

var time: String { return Formatter.time.string(from: self) }

var year: Int { return Calendar.autoupdatingCurrent.component(.year, from: self) }
var month: Int { return Calendar.autoupdatingCurrent.component(.month, from: self) }
var day: Int { return Calendar.autoupdatingCurrent.component(.day, from: self) }

var elapsedTime: String {
if timeIntervalSinceNow > -60.0 { return "Just Now" }
if isInToday { return "Today at \(time)" }
if isInYesterday { return "Yesterday at \(time)" }
return (Formatter.dateComponents.string(from: Date().timeIntervalSince(self)) ?? "") + " ago"
}
var isInToday: Bool {
return Calendar.autoupdatingCurrent.isDateInToday(self)
}
var isInYesterday: Bool {
return Calendar.autoupdatingCurrent.isDateInYesterday(self)
}
}

testing:

Calendar.autoupdatingCurrent.date(byAdding: .second, value: -59, to: Date())!
.elapsedTime // "Just Now"

Calendar.autoupdatingCurrent.date(byAdding: .minute, value: -1, to: Date())!
.elapsedTime // "Today at 5:03 PM"
Calendar.autoupdatingCurrent.date(byAdding: .hour, value: -1, to: Date())!
.elapsedTime // "Today at 4:04 PM"

Calendar.autoupdatingCurrent.date(byAdding: .day, value: -1, to: Date())!
.elapsedTime // "Yesterday at 5:02 PM"
Calendar.autoupdatingCurrent.date(byAdding: .weekOfYear, value: -1, to: Date())!
.elapsedTime // "1 week ago"

Calendar.autoupdatingCurrent.date(byAdding: .month, value: -2, to: Date())!
.elapsedTime // "2 months ago"
Calendar.autoupdatingCurrent.date(byAdding: .year, value: -1, to: Date())!
.elapsedTime // "1 year ago"


Related Topics



Leave a reply



Submit