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

IosIphoneSwiftDate

Ios Problem Overview


I have been researching, but I couldnt find exact solution for my problem. I have been trying to get 1 hour ago from a date. How can I achieve this in swift?

Ios Solutions


Solution 1 - Ios

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: [])

Solution 2 - Ios

Use this method and paste in your helper class.

Updated for Swift 3 and Xcode 8.3

class func timeAgoSinceDate(_ date:Date,currentDate:Date, numericDates:Bool) -> String {
    let calendar = Calendar.current
    let now = currentDate
    let earliest = (now as NSDate).earlierDate(date)
    let latest = (earliest == now) ? date : now
    let components:DateComponents = (calendar as NSCalendar).components([NSCalendar.Unit.minute , NSCalendar.Unit.hour , NSCalendar.Unit.day , NSCalendar.Unit.weekOfYear , NSCalendar.Unit.month , NSCalendar.Unit.year , NSCalendar.Unit.second], from: earliest, to: latest, options: NSCalendar.Options())
    
    if (components.year! >= 2) {
        return "\(components.year!) years ago"
    } else if (components.year! >= 1){
        if (numericDates){
            return "1 year ago"
        } else {
            return "Last year"
        }
    } else if (components.month! >= 2) {
        return "\(components.month!) months ago"
    } else if (components.month! >= 1){
        if (numericDates){
            return "1 month ago"
        } else {
            return "Last month"
        }
    } else if (components.weekOfYear! >= 2) {
        return "\(components.weekOfYear!) weeks ago"
    } else if (components.weekOfYear! >= 1){
        if (numericDates){
            return "1 week ago"
        } else {
            return "Last week"
        }
    } else if (components.day! >= 2) {
        return "\(components.day!) days ago"
    } else if (components.day! >= 1){
        if (numericDates){
            return "1 day ago"
        } else {
            return "Yesterday"
        }
    } else if (components.hour! >= 2) {
        return "\(components.hour!) hours ago"
    } else if (components.hour! >= 1){
        if (numericDates){
            return "1 hour ago"
        } else {
            return "An hour ago"
        }
    } else if (components.minute! >= 2) {
        return "\(components.minute!) minutes ago"
    } else if (components.minute! >= 1){
        if (numericDates){
            return "1 minute ago"
        } else {
            return "A minute ago"
        }
    } else if (components.second! >= 3) {
        return "\(components.second!) seconds ago"
    } else {
        return "Just now"
    }
    
}

Use of this method:

var timeAgo:String=AppHelper.timeAgoSinceDate(date, numericDates: true)
Print("\(timeAgo)")   // Ex- 1 hour ago

Solution 3 - Ios

Please read the NSDate class reference.

let oneHourAgo = NSDate.dateWithTimeIntervalSinceNow(-3600)

should do it.

Or, for any NSDate object:

let oneHourBack = myDate.dateByAddingTimeInterval(-3600)

Swift 4:

let oneHourAgo = NSDate(timeIntervalSinceNow: -3600)

Solution 4 - Ios

According to your needs, you may choose one of the 3 following Swift 5 methods to get one hour ago from a Date instance.


1. date(byAdding:value:to:wrappingComponents:)

Calendar has a method called date(byAdding:value:to:wrappingComponents:). date(byAdding:value:to:wrappingComponents:) has the following declaration:

func date(byAdding component: Calendar.Component, value: Int, to date: Date, wrappingComponents: Bool = default) -> Date?

> Returns a new Date representing the date calculated by adding an amount of a specific component to a given date.

The Playground code below shows how to use it:

import Foundation

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

print(now) // 2016-12-19 21:52:04 +0000
print(String(describing: oneHourAgo)) // Optional(2016-12-19 20:52:04 +0000)

2. date(byAdding:to:wrappingComponents:)

Calendar has a method called date(byAdding:to:wrappingComponents:). date(byAdding:value:to:wrappingComponents:) has the following declaration:

func date(byAdding components: DateComponents, to date: Date, wrappingComponents: Bool = default) -> Date?

> Returns a new Date representing the date calculated by adding components to a given date.

The Playground code below shows how to use it:

import Foundation

let now = Date()

var components = DateComponents()
components.hour = -1
let oneHourAgo = Calendar.current.date(byAdding: components, to: now)

print(now) // 2016-12-19 21:52:04 +0000
print(String(describing: oneHourAgo)) // Optional(2016-12-19 20:52:04 +0000)

Alternative:

import Foundation

// Get the date that was 1hr before now
let now = Date()

let components = DateComponents(hour: -1)
let oneHourAgo = Calendar.current.date(byAdding: components, to: now)

print(now) // 2016-12-19 21:52:04 +0000
print(String(describing: oneHourAgo)) // Optional(2016-12-19 20:52:04 +0000)

3. addingTimeInterval(_:) (use with caution)

Date has a method called addingTimeInterval(_:). addingTimeInterval(_:) has the following declaration:

func addingTimeInterval(_ timeInterval: TimeInterval) -> Date

> Return a new Date by adding a TimeInterval to this Date.

Note that this method comes with a warning: > This only adjusts an absolute value. If you wish to add calendrical concepts like hours, days, months then you must use a Calendar. That will take into account complexities like daylight saving time, months with different numbers of days, and more.

The Playground code below shows how to use it:

import Foundation

let now = Date()
let oneHourAgo = now.addingTimeInterval(-3600)

print(now) // 2016-12-19 21:52:04 +0000
print(oneHourAgo) // 2016-12-19 20:52:04 +0000

Solution 5 - Ios

If you are using NSDate you can do:

let date = NSDate()
date.dateByAddingTimeInterval(-3600)

It will change the date object to be "1 hour ago".

Solution 6 - Ios

Swift3:

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

Solution 7 - Ios

I achieve time ago functionality by creating extension of Date. Which is given below:

extension Date {
 // Returns the number of years 
 func yearsCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
 }
 // Returns the number of months
 func monthsCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
 }
 // Returns the number of weeks
 func weeksCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
 }
 // Returns the number of days
 func daysCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
 }
 // Returns the number of hours
 func hoursCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
 }
 // Returns the number of minutes
func minutesCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
 }
 // Returns the number of seconds
 func secondsCount(from date: Date) -> Int {
    return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
 }
 // Returns time ago by checking if the time differences between two dates are in year or months or weeks or days or hours or minutes or seconds
 func timeAgo(from date: Date) -> String {
    if yearsCount(from: date)   > 0 { return "\(yearsCount(from: date))years ago"   }
    if monthsCount(from: date)  > 0 { return "\(monthsCount(from: date))months ago"  }
    if weeksCount(from: date)   > 0 { return "\(weeksCount(from: date))weeks ago"   }
    if daysCount(from: date)    > 0 { return "\(daysCount(from: date))days ago"    }
    if hoursCount(from: date)   > 0 { return "\(hoursCount(from: date))hours ago"   }
    if minutesCount(from: date) > 0 { return "\(minutesCount(from: date))minutes ago" }
    if secondsCount(from: date) > 0 { return "\(secondsCount(from: date))seconds ago" }
    return ""
  }
}

Then i get the time ago by calculating the difference between current date and specified date:

   let timeAgo = Date().timeAgo(from: sender.date)

Solution 8 - Ios

for Swift 2:

extension NSDate {
    func after(value: Int, calendarUnit:NSCalendarUnit) -> NSDate {
        return calendar.dateByAddingUnit(calendarUnit, value: value, toDate: self, options: [])!
    }
}

how to use:

let lastHour = NSDate().after(-1, calendarUnit: .Hour)

Solution 9 - Ios

You can also use an operator

let date = Date()
let anHourAgo = date - TimeInterval(3600.0)

Apple Docs: https://developer.apple.com/documentation/foundation/date/2293436

Solution 10 - Ios

This works for iOS 13 / Swift 5. Credit goes to Sourabh Sharma

func timeAgoSinceNow(numericDates: Bool = true) -> String {
    let calendar = Calendar.current
    let now = Date()
    let earliest = (now as NSDate).earlierDate(self)
    let latest = (earliest == now) ? self : now
    let components: DateComponents = (calendar as NSCalendar).components([NSCalendar.Unit.minute,
                                                                          NSCalendar.Unit.hour,
                                                                          NSCalendar.Unit.day,
                                                                          NSCalendar.Unit.weekOfYear,
                                                                          NSCalendar.Unit.month,
                                                                          NSCalendar.Unit.year,
                                                                          NSCalendar.Unit.second],
                                                                         from: earliest,
                                                                         to: latest,
                                                                         options: NSCalendar.Options())
    
    guard
        let year = components.year,
        let month = components.month,
        let weekOfYear = components.weekOfYear,
        let day = components.day,
        let hour = components.hour,
        let minute = components.minute,
        let second = components.second
    else { return "A while ago"}

    if year >= 1 {
        return year >= 2 ? "\(year) years ago" : numericDates ? "1 year ago" : "Last year"
    } else if month >= 1 {
        return month >= 2 ? "\(month) months ago" : numericDates ? "1 month ago" : "Last month"
    } else if weekOfYear >= 1 {
        return weekOfYear >= 2 ? "\(weekOfYear) weeks ago" : numericDates ? "1 week ago" : "Last week"
    } else if day >= 1 {
        return day >= 2 ? "\(day) days ago" : numericDates ? "1 day ago" : "Yesterday"
    } else if hour >= 1 {
        return hour >= 2 ? "\(hour) hours ago" : numericDates ? "1 hour ago" : "An hour ago"
    } else if minute >= 1 {
        return minute >= 2 ? "\(minute) minutes ago" : numericDates ? "1 minute ago" : "A minute ago"
    } else {
        return second >= 3 ? "\(second) seconds ago" : "Just now"
    }
}

Usage:

var date = Date() // Or any date you wish to convert to text
print("\(date.timeAgoSinceNow())") // "Just Now"

Solution 11 - Ios

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

Solution 12 - Ios

In swift 5 You can use

      let earlyDate = Calendar.current.date( byAdding: .hour, value: -1, to: Date())
      let df = DateFormatter()
      df.dateFormat = "yyyy-MM-dd HH:mm:ss"
      let dateString = df.string(from: earlyDate!)

Out put will Be like bellow

Current DateTime--> 2019-12-20 09:40:08
One Hour Previous Date Time--> 2019-12-20 08:40:08

Solution 13 - Ios

Details

  • Xcode 11.4 (11E146), Swift 5.2

Solution

import Foundation

extension Date {

    typealias Component = (value: Int, type: Calendar.Component)

    init?(bySubtracting components: Component..., calendar: Calendar = Calendar.current, from date: Date) {
        guard let date = date.subtract(components, calendar: calendar) else { return nil }
        self = date
    }
    
    func subtract(_ components: Component..., calendar: Calendar = Calendar.current) -> Date? {
        subtract(components, calendar: calendar)
    }
    
    func subtract(_ components: [Component], calendar: Calendar = Calendar.current) -> Date? {
        components.reduce(self) { (result, component) -> Date? in
            guard let date = result else { return nil }
            return calendar.date(byAdding: component.type, value: (-1)*component.value, to: date)
        }
    }

    static func beforeNow(difference component: Component..., calendar: Calendar = Calendar.current) -> Date? {
        Date().subtract(component, calendar: calendar)
    }
    
    static func beforeNow(difference component: [Component], calendar: Calendar = Calendar.current) -> Date? {
        Date().subtract(component, calendar: calendar)
    }
}

extension Date {
    static func - (date: Date, component: Date.Component) -> Date? { date.subtract(component, calendar: Calendar.current) }
    static func -= (date: inout Date, component: Date.Component) {
        guard let newDate = date.subtract(component, calendar: Calendar.current) else { return }
        date = newDate
    }
}

Usage

var currentDate = Date()
let date1 = Date(bySubtracting: (30, .day), from: currentDate)

let date2 = Date().subtract((30, .day))

let date3 = Date().subtract([(1, .minute), (2, .hour), (3, .day), (4, .month)])

let component = Date.Component(value: 1, type: .day)
let date4 = Date.beforeNow(difference: component)

let date5 = Date.beforeNow(difference: (1, .minute), (2, .hour), (3, .day), (4, .month))

let date6 = Date.beforeNow(difference: [(1, .minute), (2, .hour), (3, .day), (4, .month)])

let date7 = currentDate - (1, .day)

currentDate -= Date.Component(value: 1, type: .day)

More

Solution 14 - Ios

let now = Date()
let nowMinusTwoAndAHalfHours = now - 2.5*60*60

print(now)
print(nowMinusTwoAndAHalfHours)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsaksutView Question on Stackoverflow
Solution 1 - IosVladimirView Answer on Stackoverflow
Solution 2 - IosSourabh SharmaView Answer on Stackoverflow
Solution 3 - IoszisoftView Answer on Stackoverflow
Solution 4 - IosImanou PetitView Answer on Stackoverflow
Solution 5 - IoskbagiView Answer on Stackoverflow
Solution 6 - IosChris AllinsonView Answer on Stackoverflow
Solution 7 - IosH S ProgrView Answer on Stackoverflow
Solution 8 - IosDeepak SharmaView Answer on Stackoverflow
Solution 9 - IoscocoView Answer on Stackoverflow
Solution 10 - IosDanView Answer on Stackoverflow
Solution 11 - IosSai SiddeshwarView Answer on Stackoverflow
Solution 12 - IosEnamul HaqueView Answer on Stackoverflow
Solution 13 - IosVasily BodnarchukView Answer on Stackoverflow
Solution 14 - IosRoi ZakaiView Answer on Stackoverflow