Getting the difference between two NSDates in (months/days/hours/minutes/seconds)
I am trying to get the difference between the current date as NSDate()
and a date from a PHP time();
call for example: NSDate(timeIntervalSinceReferenceDate: 1417147270)
. How do I go about getting the difference in time between the two dates. I'd like to have a function that compares the two dates and if(seconds > 60)
then it returns minutes, if(minutes > 60)
return hours and if(hours > 24)
return days and so on.
How should I go about this?
EDIT: The current accepted answer has done exactly what I've wanted to do. I recommend it for easy usage for getting the time between two dates in the form that that PHP time()
function uses. If you aren't particularly familiar with PHP, that's the time in seconds from January 1st, 1970. This is beneficial for a backend in PHP. If perhaps you're using a backend like NodeJS you might want to consider some of the other options you'll find below.
ios swift macos nsdate
add a comment |
I am trying to get the difference between the current date as NSDate()
and a date from a PHP time();
call for example: NSDate(timeIntervalSinceReferenceDate: 1417147270)
. How do I go about getting the difference in time between the two dates. I'd like to have a function that compares the two dates and if(seconds > 60)
then it returns minutes, if(minutes > 60)
return hours and if(hours > 24)
return days and so on.
How should I go about this?
EDIT: The current accepted answer has done exactly what I've wanted to do. I recommend it for easy usage for getting the time between two dates in the form that that PHP time()
function uses. If you aren't particularly familiar with PHP, that's the time in seconds from January 1st, 1970. This is beneficial for a backend in PHP. If perhaps you're using a backend like NodeJS you might want to consider some of the other options you'll find below.
ios swift macos nsdate
2
I realize this is kind of old, but what do you intend to do with the difference? For example, if you're looking to format a string for the user, you should be usingNSDateComponentsFormatter
. It's very configurable, allowing you to get appropriately terse results (e.g..maximumUnitCount = 1
).
– Ken Thomases
Jul 31 '15 at 6:10
Really, the question what you intend to do is absolutely essential. Consider that a month can be as little as 28 days, or as much as 31 days plus one hour.
– gnasher729
Oct 16 '15 at 15:33
stackoverflow.com/a/54452429/3908884
– Meet Doshi
Jan 31 at 2:46
add a comment |
I am trying to get the difference between the current date as NSDate()
and a date from a PHP time();
call for example: NSDate(timeIntervalSinceReferenceDate: 1417147270)
. How do I go about getting the difference in time between the two dates. I'd like to have a function that compares the two dates and if(seconds > 60)
then it returns minutes, if(minutes > 60)
return hours and if(hours > 24)
return days and so on.
How should I go about this?
EDIT: The current accepted answer has done exactly what I've wanted to do. I recommend it for easy usage for getting the time between two dates in the form that that PHP time()
function uses. If you aren't particularly familiar with PHP, that's the time in seconds from January 1st, 1970. This is beneficial for a backend in PHP. If perhaps you're using a backend like NodeJS you might want to consider some of the other options you'll find below.
ios swift macos nsdate
I am trying to get the difference between the current date as NSDate()
and a date from a PHP time();
call for example: NSDate(timeIntervalSinceReferenceDate: 1417147270)
. How do I go about getting the difference in time between the two dates. I'd like to have a function that compares the two dates and if(seconds > 60)
then it returns minutes, if(minutes > 60)
return hours and if(hours > 24)
return days and so on.
How should I go about this?
EDIT: The current accepted answer has done exactly what I've wanted to do. I recommend it for easy usage for getting the time between two dates in the form that that PHP time()
function uses. If you aren't particularly familiar with PHP, that's the time in seconds from January 1st, 1970. This is beneficial for a backend in PHP. If perhaps you're using a backend like NodeJS you might want to consider some of the other options you'll find below.
ios swift macos nsdate
ios swift macos nsdate
edited Nov 24 '18 at 10:30
Leo Dabus
134k32277350
134k32277350
asked Nov 28 '14 at 4:43
uhfocuzuhfocuz
1,2052821
1,2052821
2
I realize this is kind of old, but what do you intend to do with the difference? For example, if you're looking to format a string for the user, you should be usingNSDateComponentsFormatter
. It's very configurable, allowing you to get appropriately terse results (e.g..maximumUnitCount = 1
).
– Ken Thomases
Jul 31 '15 at 6:10
Really, the question what you intend to do is absolutely essential. Consider that a month can be as little as 28 days, or as much as 31 days plus one hour.
– gnasher729
Oct 16 '15 at 15:33
stackoverflow.com/a/54452429/3908884
– Meet Doshi
Jan 31 at 2:46
add a comment |
2
I realize this is kind of old, but what do you intend to do with the difference? For example, if you're looking to format a string for the user, you should be usingNSDateComponentsFormatter
. It's very configurable, allowing you to get appropriately terse results (e.g..maximumUnitCount = 1
).
– Ken Thomases
Jul 31 '15 at 6:10
Really, the question what you intend to do is absolutely essential. Consider that a month can be as little as 28 days, or as much as 31 days plus one hour.
– gnasher729
Oct 16 '15 at 15:33
stackoverflow.com/a/54452429/3908884
– Meet Doshi
Jan 31 at 2:46
2
2
I realize this is kind of old, but what do you intend to do with the difference? For example, if you're looking to format a string for the user, you should be using
NSDateComponentsFormatter
. It's very configurable, allowing you to get appropriately terse results (e.g. .maximumUnitCount = 1
).– Ken Thomases
Jul 31 '15 at 6:10
I realize this is kind of old, but what do you intend to do with the difference? For example, if you're looking to format a string for the user, you should be using
NSDateComponentsFormatter
. It's very configurable, allowing you to get appropriately terse results (e.g. .maximumUnitCount = 1
).– Ken Thomases
Jul 31 '15 at 6:10
Really, the question what you intend to do is absolutely essential. Consider that a month can be as little as 28 days, or as much as 31 days plus one hour.
– gnasher729
Oct 16 '15 at 15:33
Really, the question what you intend to do is absolutely essential. Consider that a month can be as little as 28 days, or as much as 31 days plus one hour.
– gnasher729
Oct 16 '15 at 15:33
stackoverflow.com/a/54452429/3908884
– Meet Doshi
Jan 31 at 2:46
stackoverflow.com/a/54452429/3908884
– Meet Doshi
Jan 31 at 2:46
add a comment |
17 Answers
17
active
oldest
votes
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 = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second]
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"
1
In Swift 2.0,.CalendarUnitSecond
gives error'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?
– Matte.Car
Jul 30 '15 at 19:42
2
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
1
I hate the duplications in this answer, I would use a method based onNSCalendarUnit
, implemented asreturn Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).
– Sulthan
Jun 19 '16 at 21:01
3
Since the answer usingDateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.
– rmaddy
Apr 6 '17 at 20:21
1
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
|
show 10 more comments
If someone would need to display all time units e.g "hours minutes seconds" not just "hours". Let's say the time difference between two dates is 1hour 59minutes 20seconds. This function will display "1h 59m 20s".
Here is my code:
extension NSDate {
func offsetFrom(date : NSDate) -> String {
let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: )
let seconds = "(difference.second)s"
let minutes = "(difference.minute)m" + " " + seconds
let hours = "(difference.hour)h" + " " + minutes
let days = "(difference.day)d" + " " + hours
if difference.day > 0 { return days }
if difference.hour > 0 { return hours }
if difference.minute > 0 { return minutes }
if difference.second > 0 { return seconds }
return ""
}
}
In Swift 3:
extension Date {
func offsetFrom(date : Date) -> String {
let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self);
let seconds = "(difference.second ?? 0)s"
let minutes = "(difference.minute ?? 0)m" + " " + seconds
let hours = "(difference.hour ?? 0)h" + " " + minutes
let days = "(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
2
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
add a comment |
You ask:
I'd like to have a function that compares the two dates and if(seconds > 60) then it returns minutes, if(minutes > 60) return hours and if(hours > 24) return days and so on.
I'm assuming that you're trying to build a string representation of the elapsed time between two dates. Rather than writing your own code to do that, Apple already has a class designed to do precisely that. Namely, use DateComponentsFormatter
, set allowedUnits
to whatever values make sense to your app, set unitsStyle
to whatever you want (e.g. .full
), and then call string(from:to:)
.
E.g. in Swift 3:
let previousDate = ...
let now = Date()
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
formatter.maximumUnitCount = 2 // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case
let string = formatter.string(from: previousDate, to: now)
This also will localize the string appropriate for the device in question.
Or, in Swift 2.3:
let previousDate = ...
let now = NSDate()
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
formatter.maximumUnitCount = 2
let string = formatter.stringFromDate(previousDate, toDate: now)
If you're looking for the actual numeric values, just use dateComponents
. E.g. in Swift 3:
let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)
Or, in Swift 2.3:
let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: )
add a comment |
func dateDiff(dateStr:String) -> String {
var f:NSDateFormatter = NSDateFormatter()
f.timeZone = NSTimeZone.localTimeZone()
f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"
var now = f.stringFromDate(NSDate())
var startDate = f.dateFromString(dateStr)
var endDate = f.dateFromString(now)
var calendar: NSCalendar = NSCalendar.currentCalendar()
let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond
let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil)
let weeks = abs(dateComponents.weekOfMonth)
let days = abs(dateComponents.day)
let hours = abs(dateComponents.hour)
let min = abs(dateComponents.minute)
let sec = abs(dateComponents.second)
var timeAgo = ""
if (sec > 0){
if (sec > 1) {
timeAgo = "(sec) Seconds Ago"
} else {
timeAgo = "(sec) Second Ago"
}
}
if (min > 0){
if (min > 1) {
timeAgo = "(min) Minutes Ago"
} else {
timeAgo = "(min) Minute Ago"
}
}
if(hours > 0){
if (hours > 1) {
timeAgo = "(hours) Hours Ago"
} else {
timeAgo = "(hours) Hour Ago"
}
}
if (days > 0) {
if (days > 1) {
timeAgo = "(days) Days Ago"
} else {
timeAgo = "(days) Day Ago"
}
}
if(weeks > 0){
if (weeks > 1) {
timeAgo = "(weeks) Weeks Ago"
} else {
timeAgo = "(weeks) Week Ago"
}
}
print("timeAgo is===> (timeAgo)")
return timeAgo;
}
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
1
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
add a comment |
combined Extension + DateComponentsFormatter from the answer of @leo-dabus
Xcode 8.3 • Swift 3.1
extension DateComponentsFormatter {
func difference(from fromDate: Date, to toDate: Date) -> String? {
self.allowedUnits = [.year,.month,.weekOfMonth,.day]
self.maximumUnitCount = 1
self.unitsStyle = .full
return self.string(from: fromDate, to: toDate)
}
}
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"
add a comment |
I added a "long" version to Leo Dabus's asnwer in case you want to have a string that says something like "2 weeks ago" instead of just "2w"...
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([.weekOfYear], from: date, to: self).weekOfYear ?? 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 ""
}
func offsetLong(from date: Date) -> String {
if years(from: date) > 0 { return years(from: date) > 1 ? "(years(from: date)) years ago" : "(years(from: date)) year ago" }
if months(from: date) > 0 { return months(from: date) > 1 ? "(months(from: date)) months ago" : "(months(from: date)) month ago" }
if weeks(from: date) > 0 { return weeks(from: date) > 1 ? "(weeks(from: date)) weeks ago" : "(weeks(from: date)) week ago" }
if days(from: date) > 0 { return days(from: date) > 1 ? "(days(from: date)) days ago" : "(days(from: date)) day ago" }
if hours(from: date) > 0 { return hours(from: date) > 1 ? "(hours(from: date)) hours ago" : "(hours(from: date)) hour ago" }
if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "(minutes(from: date)) minutes ago" : "(minutes(from: date)) minute ago" }
if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "(seconds(from: date)) seconds ago" : "(seconds(from: date)) second ago" }
return ""
}
}
add a comment |
Slightly modified code for Swift 3.0
let calendar = NSCalendar.current as NSCalendar
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: startDateTime)
let date2 = calendar.startOfDay(for: endDateTime)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2, options: )
return components.day!
add a comment |
With Swift 3, according to your needs, you may choose one of the two following ways to solve your problem.
1. Display the difference between two dates to the user
You can use a DateComponentsFormatter
to create strings for your app’s interface. DateComponentsFormatter
has a maximumUnitCount
property with the following declaration:
var maximumUnitCount: Int { get set }
Use this property to limit the number of units displayed in the resulting string. For example, with this property set to 2, instead of “1h 10m, 30s”, the resulting string would be “1h 10m”. Use this property when you are constrained for space or want to round up values to the nearest large unit.
By setting maximumUnitCount
's value to 1
, you are guaranteed to display the difference in only one DateComponentsFormatter
's unit (years, months, days, hours or minutes).
The Playground code below shows how to display the difference between two dates:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Note that DateComponentsFormatter
rounds up the result. Therefore, a difference of 4 hours and 30 minutes will be displayed as 5 hours.
If you need to repeat this operation, you can refactor your code:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Get the difference between two dates without formatting
If you don't need to display with formatting the difference between two dates to the user, you can use Calendar
. Calendar
has a method dateComponents(_:from:to:)
that has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Returns the difference between two dates.
The Playground code below that uses dateComponents(_:from:to:)
shows how to retrieve the difference between two dates by returning the difference in only one type of Calendar.Component
(years, months, days, hours or minutes).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
If you need to repeat this operation, you can refactor your code:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
add a comment |
In Swift 2.2
/// Returns the amount of years from another date
func years(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: ).year ?? 0
}
/// Returns the amount of months from another date
func months(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: ).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: ).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: ).day ?? 0
}
/// Returns the amount of hours from another date
func hours(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: ).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: ).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: ).second ?? 0
}
add a comment |
Here is my answer for the Swift 3 answers above. This is current as of Nov 2016, Xcode release was 8.2 Beta (8C23). Used some of both Sagar and Emin suggestions above and sometimes had to let Xcode autocomplete to suggest the syntax. It seemed like the syntax really changed to this beta version. buyDate
I got from a DatePicker:
let calendar = NSCalendar.current as NSCalendar
let currentDate = Date()
let date1 = calendar.startOfDay(for: buyDate!)
let date2 = calendar.startOfDay(for: currentDate)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2)
NSLog(" day= (components.day)")
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
You shouldn't really be usingNSCalendar
in Swift 3. UseCalendar
. So this is simplified tolet calendar = Calendar.current
. And thencomponents
would look like:let components = calendar.dateComponents([.day], from: date1, to: date2)
.
– Rob
Jan 13 '17 at 18:22
add a comment |
A small addition to Leo Dabus' answer to provide the plural versions and be more human readable.
Swift 3
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) == 1 { return "(years(from: date)) year" } else if years(from: date) > 1 { return "(years(from: date)) years" }
if months(from: date) == 1 { return "(months(from: date)) month" } else if months(from: date) > 1 { return "(months(from: date)) month" }
if weeks(from: date) == 1 { return "(weeks(from: date)) week" } else if weeks(from: date) > 1 { return "(weeks(from: date)) weeks" }
if days(from: date) == 1 { return "(days(from: date)) day" } else if days(from: date) > 1 { return "(days(from: date)) days" }
if hours(from: date) == 1 { return "(hours(from: date)) hour" } else if hours(from: date) > 1 { return "(hours(from: date)) hours" }
if minutes(from: date) == 1 { return "(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "(minutes(from: date)) minutes" }
return ""
}
}
add a comment |
--> Use this to find time gap between two dates in Swift(With two Strings).
func timeGapBetweenDates(previousDate : String,currentDate : String)
{
let dateString1 = previousDate
let dateString2 = currentDate
let Dateformatter = DateFormatter()
Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date1 = Dateformatter.date(from: dateString1)
let date2 = Dateformatter.date(from: dateString2)
let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
let secondsInAnHour: Double = 3600
let minsInAnHour: Double = 60
let secondsInDays: Double = 86400
let secondsInWeek: Double = 604800
let secondsInMonths : Double = 2592000
let secondsInYears : Double = 31104000
let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
let secbetweenDates = Int(distanceBetweenDates!)
if yearbetweenDates > 0
{
print(yearbetweenDates,"years")//0 years
}
else if monthsbetweenDates > 0
{
print(monthsbetweenDates,"months")//0 months
}
else if weekBetweenDates > 0
{
print(weekBetweenDates,"weeks")//0 weeks
}
else if daysBetweenDates > 0
{
print(daysBetweenDates,"days")//5 days
}
else if hoursBetweenDates > 0
{
print(hoursBetweenDates,"hours")//120 hours
}
else if minBetweenDates > 0
{
print(minBetweenDates,"minutes")//7200 minutes
}
else if secbetweenDates > 0
{
print(secbetweenDates,"seconds")//seconds
}
}
add a comment |
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
// Assuming that firstDate and secondDate are defined
// ...
var calendar: NSCalendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
components.day // This will return the number of day(s) between dates
add a comment |
This is the shorter version: Basically I try to get the difference between the post timestamp with the Date()
now.
// MARK: - UPDATE Time Stamp
static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) {
// date in the current state
let date = Date()
let dateComponentFormatter = DateComponentsFormatter()
// change the styling date, wether second minute or hour
dateComponentFormatter.unitsStyle = .abbreviated
dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
dateComponentFormatter.maximumUnitCount = 1
// return the date new format as a string in the completion
completion(dateComponentFormatter.string(from: postTimeStamp!, to: date))
}
add a comment |
For XCode Version 8.3.3 & Swift 3.0:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
var beginDate = "2017-08-24 12:00:00"
var endDate = "2017-09-07 12:00:00"
let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
print(startDateTime ?? "") //Convert String to Date
let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
print(endDateTime ?? "") //Convert String to Date
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]
let interval = endDateTime!.timeIntervalSince(startDateTime!)
var diff = dateComponentsFormatter.string(from: interval)!
print(diff)
var day_i = 0
var hour_i = 0
var min_i = 0
if (diff.contains("d"))
{
let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)
day_i = Int(day)!
print ("day --> (day_i)")
diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
print(diff)
}
let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
hour_i = Int(hour)!
print ("hour --> (hour_i)")
let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
min_i = Int(min)!
print ("min --> (min_i)")
add a comment |
Some addition in jose920405 answer to make it compatible with Swift 3.0 and above
func getDateTimeDiff(dateStr:String) -> String {
let formatter : DateFormatter = DateFormatter()
formatter.timeZone = NSTimeZone.local
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let now = formatter.string(from: NSDate() as Date)
let startDate = formatter.date(from: dateStr)
let endDate = formatter.date(from: now)
// *** create calendar object ***
var calendar = NSCalendar.current
// *** Get components using current Local & Timezone ***
print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))
// *** define calendar components to use as well Timezone to UTC ***
let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
calendar.timeZone = TimeZone(identifier: "UTC")!
let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)
// *** Get Individual components from date ***
let years = dateComponents.year!
let months = dateComponents.month!
let days = dateComponents.day!
let hours = dateComponents.hour!
let minutes = dateComponents.minute!
let seconds = dateComponents.second!
var timeAgo = ""
if (seconds > 0){
if seconds < 2 {
timeAgo = "Second Ago"
}
else{
timeAgo = "(seconds) Second Ago"
}
}
if (minutes > 0){
if minutes < 2 {
timeAgo = "Minute Ago"
}
else{
timeAgo = "(minutes) Minutes Ago"
}
}
if(hours > 0){
if minutes < 2 {
timeAgo = "Hour Ago"
}
else{
timeAgo = "(hours) Hours Ago"
}
}
if (days > 0) {
if minutes < 2 {
timeAgo = "Day Ago"
}
else{
timeAgo = "(days) Days Ago"
}
}
if(months > 0){
if minutes < 2 {
timeAgo = "Month Ago"
}
else{
timeAgo = "(months) Months Ago"
}
}
if(years > 0){
if minutes < 2 {
timeAgo = "Year Ago"
}
else{
timeAgo = "(years) Years Ago"
}
}
DLog("timeAgo is ===> (timeAgo)")
return timeAgo;
}
add a comment |
Use this code:
let registrationDateString = "2008-10-06 00:00:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
if let registrationDate = dateFormatter.date(from: registrationDateString) {
let currentDate = Date()
let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
from: registrationDate,
to: currentDate)
print("--------------------- Result: (dateDifference.year ?? 0) years (dateDifference.month ?? 0) months and (dateDifference.day ?? 0) days")
} else {
print("--------------------- No result")
}
Output is: Result: 10 years 1 months and 18 days
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f27182023%2fgetting-the-difference-between-two-nsdates-in-months-days-hours-minutes-seconds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
17 Answers
17
active
oldest
votes
17 Answers
17
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second]
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"
1
In Swift 2.0,.CalendarUnitSecond
gives error'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?
– Matte.Car
Jul 30 '15 at 19:42
2
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
1
I hate the duplications in this answer, I would use a method based onNSCalendarUnit
, implemented asreturn Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).
– Sulthan
Jun 19 '16 at 21:01
3
Since the answer usingDateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.
– rmaddy
Apr 6 '17 at 20:21
1
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
|
show 10 more comments
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 = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second]
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"
1
In Swift 2.0,.CalendarUnitSecond
gives error'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?
– Matte.Car
Jul 30 '15 at 19:42
2
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
1
I hate the duplications in this answer, I would use a method based onNSCalendarUnit
, implemented asreturn Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).
– Sulthan
Jun 19 '16 at 21:01
3
Since the answer usingDateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.
– rmaddy
Apr 6 '17 at 20:21
1
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
|
show 10 more comments
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 = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second]
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"
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 = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second]
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"
edited Dec 6 '18 at 16:54
answered Nov 28 '14 at 7:59
Leo DabusLeo Dabus
134k32277350
134k32277350
1
In Swift 2.0,.CalendarUnitSecond
gives error'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?
– Matte.Car
Jul 30 '15 at 19:42
2
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
1
I hate the duplications in this answer, I would use a method based onNSCalendarUnit
, implemented asreturn Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).
– Sulthan
Jun 19 '16 at 21:01
3
Since the answer usingDateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.
– rmaddy
Apr 6 '17 at 20:21
1
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
|
show 10 more comments
1
In Swift 2.0,.CalendarUnitSecond
gives error'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?
– Matte.Car
Jul 30 '15 at 19:42
2
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
1
I hate the duplications in this answer, I would use a method based onNSCalendarUnit
, implemented asreturn Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).
– Sulthan
Jun 19 '16 at 21:01
3
Since the answer usingDateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.
– rmaddy
Apr 6 '17 at 20:21
1
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
1
1
In Swift 2.0,
.CalendarUnitSecond
gives error 'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?– Matte.Car
Jul 30 '15 at 19:42
In Swift 2.0,
.CalendarUnitSecond
gives error 'NSCalendarUnit.Type' does not have a member named 'CalendarUnitSecond'
, do you know how to solve it?– Matte.Car
Jul 30 '15 at 19:42
2
2
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
@Matte.Car you need to use .Second and instead of options: nil you need to use options: . You can take a look at my edit.
– Leo Dabus
Jul 31 '15 at 3:08
1
1
I hate the duplications in this answer, I would use a method based on
NSCalendarUnit
, implemented as return Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).– Sulthan
Jun 19 '16 at 21:01
I hate the duplications in this answer, I would use a method based on
NSCalendarUnit
, implemented as return Calendar.current().components(unit, from: date, to: self, options: )?. valueForComponent(unit)
(on iOS > 8).– Sulthan
Jun 19 '16 at 21:01
3
3
Since the answer using
DateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.– rmaddy
Apr 6 '17 at 20:21
Since the answer using
DateComponentsFormatter
is SO much better than doing it the long way, that really should be at the top of the answer.– rmaddy
Apr 6 '17 at 20:21
1
1
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
@RaviVyas the correct unit is weekOfMonth
– Leo Dabus
May 5 '17 at 10:47
|
show 10 more comments
If someone would need to display all time units e.g "hours minutes seconds" not just "hours". Let's say the time difference between two dates is 1hour 59minutes 20seconds. This function will display "1h 59m 20s".
Here is my code:
extension NSDate {
func offsetFrom(date : NSDate) -> String {
let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: )
let seconds = "(difference.second)s"
let minutes = "(difference.minute)m" + " " + seconds
let hours = "(difference.hour)h" + " " + minutes
let days = "(difference.day)d" + " " + hours
if difference.day > 0 { return days }
if difference.hour > 0 { return hours }
if difference.minute > 0 { return minutes }
if difference.second > 0 { return seconds }
return ""
}
}
In Swift 3:
extension Date {
func offsetFrom(date : Date) -> String {
let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self);
let seconds = "(difference.second ?? 0)s"
let minutes = "(difference.minute ?? 0)m" + " " + seconds
let hours = "(difference.hour ?? 0)h" + " " + minutes
let days = "(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
2
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
add a comment |
If someone would need to display all time units e.g "hours minutes seconds" not just "hours". Let's say the time difference between two dates is 1hour 59minutes 20seconds. This function will display "1h 59m 20s".
Here is my code:
extension NSDate {
func offsetFrom(date : NSDate) -> String {
let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: )
let seconds = "(difference.second)s"
let minutes = "(difference.minute)m" + " " + seconds
let hours = "(difference.hour)h" + " " + minutes
let days = "(difference.day)d" + " " + hours
if difference.day > 0 { return days }
if difference.hour > 0 { return hours }
if difference.minute > 0 { return minutes }
if difference.second > 0 { return seconds }
return ""
}
}
In Swift 3:
extension Date {
func offsetFrom(date : Date) -> String {
let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self);
let seconds = "(difference.second ?? 0)s"
let minutes = "(difference.minute ?? 0)m" + " " + seconds
let hours = "(difference.hour ?? 0)h" + " " + minutes
let days = "(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
2
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
add a comment |
If someone would need to display all time units e.g "hours minutes seconds" not just "hours". Let's say the time difference between two dates is 1hour 59minutes 20seconds. This function will display "1h 59m 20s".
Here is my code:
extension NSDate {
func offsetFrom(date : NSDate) -> String {
let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: )
let seconds = "(difference.second)s"
let minutes = "(difference.minute)m" + " " + seconds
let hours = "(difference.hour)h" + " " + minutes
let days = "(difference.day)d" + " " + hours
if difference.day > 0 { return days }
if difference.hour > 0 { return hours }
if difference.minute > 0 { return minutes }
if difference.second > 0 { return seconds }
return ""
}
}
In Swift 3:
extension Date {
func offsetFrom(date : Date) -> String {
let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self);
let seconds = "(difference.second ?? 0)s"
let minutes = "(difference.minute ?? 0)m" + " " + seconds
let hours = "(difference.hour ?? 0)h" + " " + minutes
let days = "(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
If someone would need to display all time units e.g "hours minutes seconds" not just "hours". Let's say the time difference between two dates is 1hour 59minutes 20seconds. This function will display "1h 59m 20s".
Here is my code:
extension NSDate {
func offsetFrom(date : NSDate) -> String {
let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: )
let seconds = "(difference.second)s"
let minutes = "(difference.minute)m" + " " + seconds
let hours = "(difference.hour)h" + " " + minutes
let days = "(difference.day)d" + " " + hours
if difference.day > 0 { return days }
if difference.hour > 0 { return hours }
if difference.minute > 0 { return minutes }
if difference.second > 0 { return seconds }
return ""
}
}
In Swift 3:
extension Date {
func offsetFrom(date : Date) -> String {
let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self);
let seconds = "(difference.second ?? 0)s"
let minutes = "(difference.minute ?? 0)m" + " " + seconds
let hours = "(difference.hour ?? 0)h" + " " + minutes
let days = "(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
edited Apr 13 '18 at 4:29
Dev_Tandel
2,48911135
2,48911135
answered Apr 8 '16 at 8:14
Adam StudenicAdam Studenic
1,58812020
1,58812020
2
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
add a comment |
2
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
2
2
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
this is exactly what I need. simple, and gets the job done.
– Chen Li Yong
Aug 8 '17 at 8:07
add a comment |
You ask:
I'd like to have a function that compares the two dates and if(seconds > 60) then it returns minutes, if(minutes > 60) return hours and if(hours > 24) return days and so on.
I'm assuming that you're trying to build a string representation of the elapsed time between two dates. Rather than writing your own code to do that, Apple already has a class designed to do precisely that. Namely, use DateComponentsFormatter
, set allowedUnits
to whatever values make sense to your app, set unitsStyle
to whatever you want (e.g. .full
), and then call string(from:to:)
.
E.g. in Swift 3:
let previousDate = ...
let now = Date()
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
formatter.maximumUnitCount = 2 // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case
let string = formatter.string(from: previousDate, to: now)
This also will localize the string appropriate for the device in question.
Or, in Swift 2.3:
let previousDate = ...
let now = NSDate()
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
formatter.maximumUnitCount = 2
let string = formatter.stringFromDate(previousDate, toDate: now)
If you're looking for the actual numeric values, just use dateComponents
. E.g. in Swift 3:
let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)
Or, in Swift 2.3:
let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: )
add a comment |
You ask:
I'd like to have a function that compares the two dates and if(seconds > 60) then it returns minutes, if(minutes > 60) return hours and if(hours > 24) return days and so on.
I'm assuming that you're trying to build a string representation of the elapsed time between two dates. Rather than writing your own code to do that, Apple already has a class designed to do precisely that. Namely, use DateComponentsFormatter
, set allowedUnits
to whatever values make sense to your app, set unitsStyle
to whatever you want (e.g. .full
), and then call string(from:to:)
.
E.g. in Swift 3:
let previousDate = ...
let now = Date()
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
formatter.maximumUnitCount = 2 // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case
let string = formatter.string(from: previousDate, to: now)
This also will localize the string appropriate for the device in question.
Or, in Swift 2.3:
let previousDate = ...
let now = NSDate()
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
formatter.maximumUnitCount = 2
let string = formatter.stringFromDate(previousDate, toDate: now)
If you're looking for the actual numeric values, just use dateComponents
. E.g. in Swift 3:
let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)
Or, in Swift 2.3:
let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: )
add a comment |
You ask:
I'd like to have a function that compares the two dates and if(seconds > 60) then it returns minutes, if(minutes > 60) return hours and if(hours > 24) return days and so on.
I'm assuming that you're trying to build a string representation of the elapsed time between two dates. Rather than writing your own code to do that, Apple already has a class designed to do precisely that. Namely, use DateComponentsFormatter
, set allowedUnits
to whatever values make sense to your app, set unitsStyle
to whatever you want (e.g. .full
), and then call string(from:to:)
.
E.g. in Swift 3:
let previousDate = ...
let now = Date()
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
formatter.maximumUnitCount = 2 // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case
let string = formatter.string(from: previousDate, to: now)
This also will localize the string appropriate for the device in question.
Or, in Swift 2.3:
let previousDate = ...
let now = NSDate()
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
formatter.maximumUnitCount = 2
let string = formatter.stringFromDate(previousDate, toDate: now)
If you're looking for the actual numeric values, just use dateComponents
. E.g. in Swift 3:
let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)
Or, in Swift 2.3:
let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: )
You ask:
I'd like to have a function that compares the two dates and if(seconds > 60) then it returns minutes, if(minutes > 60) return hours and if(hours > 24) return days and so on.
I'm assuming that you're trying to build a string representation of the elapsed time between two dates. Rather than writing your own code to do that, Apple already has a class designed to do precisely that. Namely, use DateComponentsFormatter
, set allowedUnits
to whatever values make sense to your app, set unitsStyle
to whatever you want (e.g. .full
), and then call string(from:to:)
.
E.g. in Swift 3:
let previousDate = ...
let now = Date()
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
formatter.maximumUnitCount = 2 // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case
let string = formatter.string(from: previousDate, to: now)
This also will localize the string appropriate for the device in question.
Or, in Swift 2.3:
let previousDate = ...
let now = NSDate()
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
formatter.maximumUnitCount = 2
let string = formatter.stringFromDate(previousDate, toDate: now)
If you're looking for the actual numeric values, just use dateComponents
. E.g. in Swift 3:
let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)
Or, in Swift 2.3:
let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: )
edited Jan 13 '17 at 18:32
answered Jan 13 '17 at 18:10
RobRob
302k49564734
302k49564734
add a comment |
add a comment |
func dateDiff(dateStr:String) -> String {
var f:NSDateFormatter = NSDateFormatter()
f.timeZone = NSTimeZone.localTimeZone()
f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"
var now = f.stringFromDate(NSDate())
var startDate = f.dateFromString(dateStr)
var endDate = f.dateFromString(now)
var calendar: NSCalendar = NSCalendar.currentCalendar()
let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond
let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil)
let weeks = abs(dateComponents.weekOfMonth)
let days = abs(dateComponents.day)
let hours = abs(dateComponents.hour)
let min = abs(dateComponents.minute)
let sec = abs(dateComponents.second)
var timeAgo = ""
if (sec > 0){
if (sec > 1) {
timeAgo = "(sec) Seconds Ago"
} else {
timeAgo = "(sec) Second Ago"
}
}
if (min > 0){
if (min > 1) {
timeAgo = "(min) Minutes Ago"
} else {
timeAgo = "(min) Minute Ago"
}
}
if(hours > 0){
if (hours > 1) {
timeAgo = "(hours) Hours Ago"
} else {
timeAgo = "(hours) Hour Ago"
}
}
if (days > 0) {
if (days > 1) {
timeAgo = "(days) Days Ago"
} else {
timeAgo = "(days) Day Ago"
}
}
if(weeks > 0){
if (weeks > 1) {
timeAgo = "(weeks) Weeks Ago"
} else {
timeAgo = "(weeks) Week Ago"
}
}
print("timeAgo is===> (timeAgo)")
return timeAgo;
}
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
1
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
add a comment |
func dateDiff(dateStr:String) -> String {
var f:NSDateFormatter = NSDateFormatter()
f.timeZone = NSTimeZone.localTimeZone()
f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"
var now = f.stringFromDate(NSDate())
var startDate = f.dateFromString(dateStr)
var endDate = f.dateFromString(now)
var calendar: NSCalendar = NSCalendar.currentCalendar()
let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond
let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil)
let weeks = abs(dateComponents.weekOfMonth)
let days = abs(dateComponents.day)
let hours = abs(dateComponents.hour)
let min = abs(dateComponents.minute)
let sec = abs(dateComponents.second)
var timeAgo = ""
if (sec > 0){
if (sec > 1) {
timeAgo = "(sec) Seconds Ago"
} else {
timeAgo = "(sec) Second Ago"
}
}
if (min > 0){
if (min > 1) {
timeAgo = "(min) Minutes Ago"
} else {
timeAgo = "(min) Minute Ago"
}
}
if(hours > 0){
if (hours > 1) {
timeAgo = "(hours) Hours Ago"
} else {
timeAgo = "(hours) Hour Ago"
}
}
if (days > 0) {
if (days > 1) {
timeAgo = "(days) Days Ago"
} else {
timeAgo = "(days) Day Ago"
}
}
if(weeks > 0){
if (weeks > 1) {
timeAgo = "(weeks) Weeks Ago"
} else {
timeAgo = "(weeks) Week Ago"
}
}
print("timeAgo is===> (timeAgo)")
return timeAgo;
}
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
1
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
add a comment |
func dateDiff(dateStr:String) -> String {
var f:NSDateFormatter = NSDateFormatter()
f.timeZone = NSTimeZone.localTimeZone()
f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"
var now = f.stringFromDate(NSDate())
var startDate = f.dateFromString(dateStr)
var endDate = f.dateFromString(now)
var calendar: NSCalendar = NSCalendar.currentCalendar()
let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond
let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil)
let weeks = abs(dateComponents.weekOfMonth)
let days = abs(dateComponents.day)
let hours = abs(dateComponents.hour)
let min = abs(dateComponents.minute)
let sec = abs(dateComponents.second)
var timeAgo = ""
if (sec > 0){
if (sec > 1) {
timeAgo = "(sec) Seconds Ago"
} else {
timeAgo = "(sec) Second Ago"
}
}
if (min > 0){
if (min > 1) {
timeAgo = "(min) Minutes Ago"
} else {
timeAgo = "(min) Minute Ago"
}
}
if(hours > 0){
if (hours > 1) {
timeAgo = "(hours) Hours Ago"
} else {
timeAgo = "(hours) Hour Ago"
}
}
if (days > 0) {
if (days > 1) {
timeAgo = "(days) Days Ago"
} else {
timeAgo = "(days) Day Ago"
}
}
if(weeks > 0){
if (weeks > 1) {
timeAgo = "(weeks) Weeks Ago"
} else {
timeAgo = "(weeks) Week Ago"
}
}
print("timeAgo is===> (timeAgo)")
return timeAgo;
}
func dateDiff(dateStr:String) -> String {
var f:NSDateFormatter = NSDateFormatter()
f.timeZone = NSTimeZone.localTimeZone()
f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ"
var now = f.stringFromDate(NSDate())
var startDate = f.dateFromString(dateStr)
var endDate = f.dateFromString(now)
var calendar: NSCalendar = NSCalendar.currentCalendar()
let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond
let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil)
let weeks = abs(dateComponents.weekOfMonth)
let days = abs(dateComponents.day)
let hours = abs(dateComponents.hour)
let min = abs(dateComponents.minute)
let sec = abs(dateComponents.second)
var timeAgo = ""
if (sec > 0){
if (sec > 1) {
timeAgo = "(sec) Seconds Ago"
} else {
timeAgo = "(sec) Second Ago"
}
}
if (min > 0){
if (min > 1) {
timeAgo = "(min) Minutes Ago"
} else {
timeAgo = "(min) Minute Ago"
}
}
if(hours > 0){
if (hours > 1) {
timeAgo = "(hours) Hours Ago"
} else {
timeAgo = "(hours) Hour Ago"
}
}
if (days > 0) {
if (days > 1) {
timeAgo = "(days) Days Ago"
} else {
timeAgo = "(days) Day Ago"
}
}
if(weeks > 0){
if (weeks > 1) {
timeAgo = "(weeks) Weeks Ago"
} else {
timeAgo = "(weeks) Week Ago"
}
}
print("timeAgo is===> (timeAgo)")
return timeAgo;
}
edited Sep 14 '16 at 12:38
answered Oct 16 '15 at 15:19
jose920405jose920405
5,81623150
5,81623150
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
1
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
add a comment |
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
1
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
try to lazy load the date formatter and even better option would be to make it static
– thesummersign
Nov 13 '15 at 17:47
1
1
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
giving error in swift 2.2
– Usama Sadiq
May 30 '16 at 15:17
add a comment |
combined Extension + DateComponentsFormatter from the answer of @leo-dabus
Xcode 8.3 • Swift 3.1
extension DateComponentsFormatter {
func difference(from fromDate: Date, to toDate: Date) -> String? {
self.allowedUnits = [.year,.month,.weekOfMonth,.day]
self.maximumUnitCount = 1
self.unitsStyle = .full
return self.string(from: fromDate, to: toDate)
}
}
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"
add a comment |
combined Extension + DateComponentsFormatter from the answer of @leo-dabus
Xcode 8.3 • Swift 3.1
extension DateComponentsFormatter {
func difference(from fromDate: Date, to toDate: Date) -> String? {
self.allowedUnits = [.year,.month,.weekOfMonth,.day]
self.maximumUnitCount = 1
self.unitsStyle = .full
return self.string(from: fromDate, to: toDate)
}
}
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"
add a comment |
combined Extension + DateComponentsFormatter from the answer of @leo-dabus
Xcode 8.3 • Swift 3.1
extension DateComponentsFormatter {
func difference(from fromDate: Date, to toDate: Date) -> String? {
self.allowedUnits = [.year,.month,.weekOfMonth,.day]
self.maximumUnitCount = 1
self.unitsStyle = .full
return self.string(from: fromDate, to: toDate)
}
}
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"
combined Extension + DateComponentsFormatter from the answer of @leo-dabus
Xcode 8.3 • Swift 3.1
extension DateComponentsFormatter {
func difference(from fromDate: Date, to toDate: Date) -> String? {
self.allowedUnits = [.year,.month,.weekOfMonth,.day]
self.maximumUnitCount = 1
self.unitsStyle = .full
return self.string(from: fromDate, to: toDate)
}
}
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"
edited May 9 '17 at 16:56
answered May 9 '17 at 16:40
Adam SmakaAdam Smaka
2,29211831
2,29211831
add a comment |
add a comment |
I added a "long" version to Leo Dabus's asnwer in case you want to have a string that says something like "2 weeks ago" instead of just "2w"...
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([.weekOfYear], from: date, to: self).weekOfYear ?? 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 ""
}
func offsetLong(from date: Date) -> String {
if years(from: date) > 0 { return years(from: date) > 1 ? "(years(from: date)) years ago" : "(years(from: date)) year ago" }
if months(from: date) > 0 { return months(from: date) > 1 ? "(months(from: date)) months ago" : "(months(from: date)) month ago" }
if weeks(from: date) > 0 { return weeks(from: date) > 1 ? "(weeks(from: date)) weeks ago" : "(weeks(from: date)) week ago" }
if days(from: date) > 0 { return days(from: date) > 1 ? "(days(from: date)) days ago" : "(days(from: date)) day ago" }
if hours(from: date) > 0 { return hours(from: date) > 1 ? "(hours(from: date)) hours ago" : "(hours(from: date)) hour ago" }
if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "(minutes(from: date)) minutes ago" : "(minutes(from: date)) minute ago" }
if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "(seconds(from: date)) seconds ago" : "(seconds(from: date)) second ago" }
return ""
}
}
add a comment |
I added a "long" version to Leo Dabus's asnwer in case you want to have a string that says something like "2 weeks ago" instead of just "2w"...
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([.weekOfYear], from: date, to: self).weekOfYear ?? 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 ""
}
func offsetLong(from date: Date) -> String {
if years(from: date) > 0 { return years(from: date) > 1 ? "(years(from: date)) years ago" : "(years(from: date)) year ago" }
if months(from: date) > 0 { return months(from: date) > 1 ? "(months(from: date)) months ago" : "(months(from: date)) month ago" }
if weeks(from: date) > 0 { return weeks(from: date) > 1 ? "(weeks(from: date)) weeks ago" : "(weeks(from: date)) week ago" }
if days(from: date) > 0 { return days(from: date) > 1 ? "(days(from: date)) days ago" : "(days(from: date)) day ago" }
if hours(from: date) > 0 { return hours(from: date) > 1 ? "(hours(from: date)) hours ago" : "(hours(from: date)) hour ago" }
if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "(minutes(from: date)) minutes ago" : "(minutes(from: date)) minute ago" }
if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "(seconds(from: date)) seconds ago" : "(seconds(from: date)) second ago" }
return ""
}
}
add a comment |
I added a "long" version to Leo Dabus's asnwer in case you want to have a string that says something like "2 weeks ago" instead of just "2w"...
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([.weekOfYear], from: date, to: self).weekOfYear ?? 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 ""
}
func offsetLong(from date: Date) -> String {
if years(from: date) > 0 { return years(from: date) > 1 ? "(years(from: date)) years ago" : "(years(from: date)) year ago" }
if months(from: date) > 0 { return months(from: date) > 1 ? "(months(from: date)) months ago" : "(months(from: date)) month ago" }
if weeks(from: date) > 0 { return weeks(from: date) > 1 ? "(weeks(from: date)) weeks ago" : "(weeks(from: date)) week ago" }
if days(from: date) > 0 { return days(from: date) > 1 ? "(days(from: date)) days ago" : "(days(from: date)) day ago" }
if hours(from: date) > 0 { return hours(from: date) > 1 ? "(hours(from: date)) hours ago" : "(hours(from: date)) hour ago" }
if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "(minutes(from: date)) minutes ago" : "(minutes(from: date)) minute ago" }
if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "(seconds(from: date)) seconds ago" : "(seconds(from: date)) second ago" }
return ""
}
}
I added a "long" version to Leo Dabus's asnwer in case you want to have a string that says something like "2 weeks ago" instead of just "2w"...
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([.weekOfYear], from: date, to: self).weekOfYear ?? 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 ""
}
func offsetLong(from date: Date) -> String {
if years(from: date) > 0 { return years(from: date) > 1 ? "(years(from: date)) years ago" : "(years(from: date)) year ago" }
if months(from: date) > 0 { return months(from: date) > 1 ? "(months(from: date)) months ago" : "(months(from: date)) month ago" }
if weeks(from: date) > 0 { return weeks(from: date) > 1 ? "(weeks(from: date)) weeks ago" : "(weeks(from: date)) week ago" }
if days(from: date) > 0 { return days(from: date) > 1 ? "(days(from: date)) days ago" : "(days(from: date)) day ago" }
if hours(from: date) > 0 { return hours(from: date) > 1 ? "(hours(from: date)) hours ago" : "(hours(from: date)) hour ago" }
if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "(minutes(from: date)) minutes ago" : "(minutes(from: date)) minute ago" }
if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "(seconds(from: date)) seconds ago" : "(seconds(from: date)) second ago" }
return ""
}
}
answered Feb 9 '17 at 17:54
zumzumzumzum
5,326126796
5,326126796
add a comment |
add a comment |
Slightly modified code for Swift 3.0
let calendar = NSCalendar.current as NSCalendar
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: startDateTime)
let date2 = calendar.startOfDay(for: endDateTime)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2, options: )
return components.day!
add a comment |
Slightly modified code for Swift 3.0
let calendar = NSCalendar.current as NSCalendar
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: startDateTime)
let date2 = calendar.startOfDay(for: endDateTime)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2, options: )
return components.day!
add a comment |
Slightly modified code for Swift 3.0
let calendar = NSCalendar.current as NSCalendar
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: startDateTime)
let date2 = calendar.startOfDay(for: endDateTime)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2, options: )
return components.day!
Slightly modified code for Swift 3.0
let calendar = NSCalendar.current as NSCalendar
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDay(for: startDateTime)
let date2 = calendar.startOfDay(for: endDateTime)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2, options: )
return components.day!
edited Aug 1 '17 at 13:56
Phyber
1,022621
1,022621
answered Oct 22 '16 at 13:57
Sagar DesaiSagar Desai
226139
226139
add a comment |
add a comment |
With Swift 3, according to your needs, you may choose one of the two following ways to solve your problem.
1. Display the difference between two dates to the user
You can use a DateComponentsFormatter
to create strings for your app’s interface. DateComponentsFormatter
has a maximumUnitCount
property with the following declaration:
var maximumUnitCount: Int { get set }
Use this property to limit the number of units displayed in the resulting string. For example, with this property set to 2, instead of “1h 10m, 30s”, the resulting string would be “1h 10m”. Use this property when you are constrained for space or want to round up values to the nearest large unit.
By setting maximumUnitCount
's value to 1
, you are guaranteed to display the difference in only one DateComponentsFormatter
's unit (years, months, days, hours or minutes).
The Playground code below shows how to display the difference between two dates:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Note that DateComponentsFormatter
rounds up the result. Therefore, a difference of 4 hours and 30 minutes will be displayed as 5 hours.
If you need to repeat this operation, you can refactor your code:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Get the difference between two dates without formatting
If you don't need to display with formatting the difference between two dates to the user, you can use Calendar
. Calendar
has a method dateComponents(_:from:to:)
that has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Returns the difference between two dates.
The Playground code below that uses dateComponents(_:from:to:)
shows how to retrieve the difference between two dates by returning the difference in only one type of Calendar.Component
(years, months, days, hours or minutes).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
If you need to repeat this operation, you can refactor your code:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
add a comment |
With Swift 3, according to your needs, you may choose one of the two following ways to solve your problem.
1. Display the difference between two dates to the user
You can use a DateComponentsFormatter
to create strings for your app’s interface. DateComponentsFormatter
has a maximumUnitCount
property with the following declaration:
var maximumUnitCount: Int { get set }
Use this property to limit the number of units displayed in the resulting string. For example, with this property set to 2, instead of “1h 10m, 30s”, the resulting string would be “1h 10m”. Use this property when you are constrained for space or want to round up values to the nearest large unit.
By setting maximumUnitCount
's value to 1
, you are guaranteed to display the difference in only one DateComponentsFormatter
's unit (years, months, days, hours or minutes).
The Playground code below shows how to display the difference between two dates:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Note that DateComponentsFormatter
rounds up the result. Therefore, a difference of 4 hours and 30 minutes will be displayed as 5 hours.
If you need to repeat this operation, you can refactor your code:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Get the difference between two dates without formatting
If you don't need to display with formatting the difference between two dates to the user, you can use Calendar
. Calendar
has a method dateComponents(_:from:to:)
that has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Returns the difference between two dates.
The Playground code below that uses dateComponents(_:from:to:)
shows how to retrieve the difference between two dates by returning the difference in only one type of Calendar.Component
(years, months, days, hours or minutes).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
If you need to repeat this operation, you can refactor your code:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
add a comment |
With Swift 3, according to your needs, you may choose one of the two following ways to solve your problem.
1. Display the difference between two dates to the user
You can use a DateComponentsFormatter
to create strings for your app’s interface. DateComponentsFormatter
has a maximumUnitCount
property with the following declaration:
var maximumUnitCount: Int { get set }
Use this property to limit the number of units displayed in the resulting string. For example, with this property set to 2, instead of “1h 10m, 30s”, the resulting string would be “1h 10m”. Use this property when you are constrained for space or want to round up values to the nearest large unit.
By setting maximumUnitCount
's value to 1
, you are guaranteed to display the difference in only one DateComponentsFormatter
's unit (years, months, days, hours or minutes).
The Playground code below shows how to display the difference between two dates:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Note that DateComponentsFormatter
rounds up the result. Therefore, a difference of 4 hours and 30 minutes will be displayed as 5 hours.
If you need to repeat this operation, you can refactor your code:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Get the difference between two dates without formatting
If you don't need to display with formatting the difference between two dates to the user, you can use Calendar
. Calendar
has a method dateComponents(_:from:to:)
that has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Returns the difference between two dates.
The Playground code below that uses dateComponents(_:from:to:)
shows how to retrieve the difference between two dates by returning the difference in only one type of Calendar.Component
(years, months, days, hours or minutes).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
If you need to repeat this operation, you can refactor your code:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
With Swift 3, according to your needs, you may choose one of the two following ways to solve your problem.
1. Display the difference between two dates to the user
You can use a DateComponentsFormatter
to create strings for your app’s interface. DateComponentsFormatter
has a maximumUnitCount
property with the following declaration:
var maximumUnitCount: Int { get set }
Use this property to limit the number of units displayed in the resulting string. For example, with this property set to 2, instead of “1h 10m, 30s”, the resulting string would be “1h 10m”. Use this property when you are constrained for space or want to round up values to the nearest large unit.
By setting maximumUnitCount
's value to 1
, you are guaranteed to display the difference in only one DateComponentsFormatter
's unit (years, months, days, hours or minutes).
The Playground code below shows how to display the difference between two dates:
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
Note that DateComponentsFormatter
rounds up the result. Therefore, a difference of 4 hours and 30 minutes will be displayed as 5 hours.
If you need to repeat this operation, you can refactor your code:
import Foundation
struct Formatters {
static let dateComponentsFormatter: DateComponentsFormatter = {
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full
return dateComponentsFormatter
}()
}
extension Date {
func offset(from: Date) -> String? {
return Formatters.dateComponentsFormatter.string(from: oldDate, to: self)
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let timeDifference = newDate.offset(from: oldDate)
print(String(reflecting: timeDifference)) // prints Optional("5 hours")
2. Get the difference between two dates without formatting
If you don't need to display with formatting the difference between two dates to the user, you can use Calendar
. Calendar
has a method dateComponents(_:from:to:)
that has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Returns the difference between two dates.
The Playground code below that uses dateComponents(_:from:to:)
shows how to retrieve the difference between two dates by returning the difference in only one type of Calendar.Component
(years, months, days, hours or minutes).
import Foundation
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
print(component, value) // prints hour 4
break
}
}
If you need to repeat this operation, you can refactor your code:
import Foundation
extension Date {
func offset(from: Date) -> (Calendar.Component, Int)? {
let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute]
let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self)
let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) }
for (component, value) in arrayOfTuples {
if let value = value, value > 0 {
return (component, value)
}
}
return nil
}
}
let oldDate = Date(timeIntervalSinceReferenceDate: -16200)
let newDate = Date(timeIntervalSinceReferenceDate: 0)
if let (component, value) = newDate.offset(from: oldDate) {
print(component, value) // prints hour 4
}
edited Mar 19 '17 at 21:00
answered Mar 3 '17 at 23:34
Imanou PetitImanou Petit
48.3k13154146
48.3k13154146
add a comment |
add a comment |
In Swift 2.2
/// Returns the amount of years from another date
func years(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: ).year ?? 0
}
/// Returns the amount of months from another date
func months(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: ).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: ).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: ).day ?? 0
}
/// Returns the amount of hours from another date
func hours(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: ).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: ).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: ).second ?? 0
}
add a comment |
In Swift 2.2
/// Returns the amount of years from another date
func years(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: ).year ?? 0
}
/// Returns the amount of months from another date
func months(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: ).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: ).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: ).day ?? 0
}
/// Returns the amount of hours from another date
func hours(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: ).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: ).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: ).second ?? 0
}
add a comment |
In Swift 2.2
/// Returns the amount of years from another date
func years(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: ).year ?? 0
}
/// Returns the amount of months from another date
func months(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: ).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: ).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: ).day ?? 0
}
/// Returns the amount of hours from another date
func hours(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: ).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: ).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: ).second ?? 0
}
In Swift 2.2
/// Returns the amount of years from another date
func years(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: ).year ?? 0
}
/// Returns the amount of months from another date
func months(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: ).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: ).weekOfYear ?? 0
}
/// Returns the amount of days from another date
func days(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: ).day ?? 0
}
/// Returns the amount of hours from another date
func hours(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: ).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: ).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(fromdate: NSDate) -> Int {
return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: ).second ?? 0
}
answered Apr 19 '17 at 7:26
Mohsin QureshiMohsin Qureshi
75621021
75621021
add a comment |
add a comment |
Here is my answer for the Swift 3 answers above. This is current as of Nov 2016, Xcode release was 8.2 Beta (8C23). Used some of both Sagar and Emin suggestions above and sometimes had to let Xcode autocomplete to suggest the syntax. It seemed like the syntax really changed to this beta version. buyDate
I got from a DatePicker:
let calendar = NSCalendar.current as NSCalendar
let currentDate = Date()
let date1 = calendar.startOfDay(for: buyDate!)
let date2 = calendar.startOfDay(for: currentDate)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2)
NSLog(" day= (components.day)")
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
You shouldn't really be usingNSCalendar
in Swift 3. UseCalendar
. So this is simplified tolet calendar = Calendar.current
. And thencomponents
would look like:let components = calendar.dateComponents([.day], from: date1, to: date2)
.
– Rob
Jan 13 '17 at 18:22
add a comment |
Here is my answer for the Swift 3 answers above. This is current as of Nov 2016, Xcode release was 8.2 Beta (8C23). Used some of both Sagar and Emin suggestions above and sometimes had to let Xcode autocomplete to suggest the syntax. It seemed like the syntax really changed to this beta version. buyDate
I got from a DatePicker:
let calendar = NSCalendar.current as NSCalendar
let currentDate = Date()
let date1 = calendar.startOfDay(for: buyDate!)
let date2 = calendar.startOfDay(for: currentDate)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2)
NSLog(" day= (components.day)")
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
You shouldn't really be usingNSCalendar
in Swift 3. UseCalendar
. So this is simplified tolet calendar = Calendar.current
. And thencomponents
would look like:let components = calendar.dateComponents([.day], from: date1, to: date2)
.
– Rob
Jan 13 '17 at 18:22
add a comment |
Here is my answer for the Swift 3 answers above. This is current as of Nov 2016, Xcode release was 8.2 Beta (8C23). Used some of both Sagar and Emin suggestions above and sometimes had to let Xcode autocomplete to suggest the syntax. It seemed like the syntax really changed to this beta version. buyDate
I got from a DatePicker:
let calendar = NSCalendar.current as NSCalendar
let currentDate = Date()
let date1 = calendar.startOfDay(for: buyDate!)
let date2 = calendar.startOfDay(for: currentDate)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2)
NSLog(" day= (components.day)")
Here is my answer for the Swift 3 answers above. This is current as of Nov 2016, Xcode release was 8.2 Beta (8C23). Used some of both Sagar and Emin suggestions above and sometimes had to let Xcode autocomplete to suggest the syntax. It seemed like the syntax really changed to this beta version. buyDate
I got from a DatePicker:
let calendar = NSCalendar.current as NSCalendar
let currentDate = Date()
let date1 = calendar.startOfDay(for: buyDate!)
let date2 = calendar.startOfDay(for: currentDate)
let flags = NSCalendar.Unit.day
let components = calendar.components(flags, from: date1, to: date2)
NSLog(" day= (components.day)")
edited Aug 1 '17 at 13:56
Phyber
1,022621
1,022621
answered Nov 30 '16 at 19:28
flashgordonflashgordon
325
325
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
You shouldn't really be usingNSCalendar
in Swift 3. UseCalendar
. So this is simplified tolet calendar = Calendar.current
. And thencomponents
would look like:let components = calendar.dateComponents([.day], from: date1, to: date2)
.
– Rob
Jan 13 '17 at 18:22
add a comment |
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
You shouldn't really be usingNSCalendar
in Swift 3. UseCalendar
. So this is simplified tolet calendar = Calendar.current
. And thencomponents
would look like:let components = calendar.dateComponents([.day], from: date1, to: date2)
.
– Rob
Jan 13 '17 at 18:22
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
Sorry, now that I look at this, this is Sagar's solution. I did so many iterations and tried so many things I thought it had changed. Emin's solution doesn't work for the latest Swift 3.
– flashgordon
Nov 30 '16 at 19:33
You shouldn't really be using
NSCalendar
in Swift 3. Use Calendar
. So this is simplified to let calendar = Calendar.current
. And then components
would look like: let components = calendar.dateComponents([.day], from: date1, to: date2)
.– Rob
Jan 13 '17 at 18:22
You shouldn't really be using
NSCalendar
in Swift 3. Use Calendar
. So this is simplified to let calendar = Calendar.current
. And then components
would look like: let components = calendar.dateComponents([.day], from: date1, to: date2)
.– Rob
Jan 13 '17 at 18:22
add a comment |
A small addition to Leo Dabus' answer to provide the plural versions and be more human readable.
Swift 3
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) == 1 { return "(years(from: date)) year" } else if years(from: date) > 1 { return "(years(from: date)) years" }
if months(from: date) == 1 { return "(months(from: date)) month" } else if months(from: date) > 1 { return "(months(from: date)) month" }
if weeks(from: date) == 1 { return "(weeks(from: date)) week" } else if weeks(from: date) > 1 { return "(weeks(from: date)) weeks" }
if days(from: date) == 1 { return "(days(from: date)) day" } else if days(from: date) > 1 { return "(days(from: date)) days" }
if hours(from: date) == 1 { return "(hours(from: date)) hour" } else if hours(from: date) > 1 { return "(hours(from: date)) hours" }
if minutes(from: date) == 1 { return "(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "(minutes(from: date)) minutes" }
return ""
}
}
add a comment |
A small addition to Leo Dabus' answer to provide the plural versions and be more human readable.
Swift 3
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) == 1 { return "(years(from: date)) year" } else if years(from: date) > 1 { return "(years(from: date)) years" }
if months(from: date) == 1 { return "(months(from: date)) month" } else if months(from: date) > 1 { return "(months(from: date)) month" }
if weeks(from: date) == 1 { return "(weeks(from: date)) week" } else if weeks(from: date) > 1 { return "(weeks(from: date)) weeks" }
if days(from: date) == 1 { return "(days(from: date)) day" } else if days(from: date) > 1 { return "(days(from: date)) days" }
if hours(from: date) == 1 { return "(hours(from: date)) hour" } else if hours(from: date) > 1 { return "(hours(from: date)) hours" }
if minutes(from: date) == 1 { return "(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "(minutes(from: date)) minutes" }
return ""
}
}
add a comment |
A small addition to Leo Dabus' answer to provide the plural versions and be more human readable.
Swift 3
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) == 1 { return "(years(from: date)) year" } else if years(from: date) > 1 { return "(years(from: date)) years" }
if months(from: date) == 1 { return "(months(from: date)) month" } else if months(from: date) > 1 { return "(months(from: date)) month" }
if weeks(from: date) == 1 { return "(weeks(from: date)) week" } else if weeks(from: date) > 1 { return "(weeks(from: date)) weeks" }
if days(from: date) == 1 { return "(days(from: date)) day" } else if days(from: date) > 1 { return "(days(from: date)) days" }
if hours(from: date) == 1 { return "(hours(from: date)) hour" } else if hours(from: date) > 1 { return "(hours(from: date)) hours" }
if minutes(from: date) == 1 { return "(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "(minutes(from: date)) minutes" }
return ""
}
}
A small addition to Leo Dabus' answer to provide the plural versions and be more human readable.
Swift 3
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) == 1 { return "(years(from: date)) year" } else if years(from: date) > 1 { return "(years(from: date)) years" }
if months(from: date) == 1 { return "(months(from: date)) month" } else if months(from: date) > 1 { return "(months(from: date)) month" }
if weeks(from: date) == 1 { return "(weeks(from: date)) week" } else if weeks(from: date) > 1 { return "(weeks(from: date)) weeks" }
if days(from: date) == 1 { return "(days(from: date)) day" } else if days(from: date) > 1 { return "(days(from: date)) days" }
if hours(from: date) == 1 { return "(hours(from: date)) hour" } else if hours(from: date) > 1 { return "(hours(from: date)) hours" }
if minutes(from: date) == 1 { return "(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "(minutes(from: date)) minutes" }
return ""
}
}
edited Dec 13 '17 at 3:58
XueYu
1,2501622
1,2501622
answered Aug 24 '17 at 18:28
brycejlbrycejl
686715
686715
add a comment |
add a comment |
--> Use this to find time gap between two dates in Swift(With two Strings).
func timeGapBetweenDates(previousDate : String,currentDate : String)
{
let dateString1 = previousDate
let dateString2 = currentDate
let Dateformatter = DateFormatter()
Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date1 = Dateformatter.date(from: dateString1)
let date2 = Dateformatter.date(from: dateString2)
let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
let secondsInAnHour: Double = 3600
let minsInAnHour: Double = 60
let secondsInDays: Double = 86400
let secondsInWeek: Double = 604800
let secondsInMonths : Double = 2592000
let secondsInYears : Double = 31104000
let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
let secbetweenDates = Int(distanceBetweenDates!)
if yearbetweenDates > 0
{
print(yearbetweenDates,"years")//0 years
}
else if monthsbetweenDates > 0
{
print(monthsbetweenDates,"months")//0 months
}
else if weekBetweenDates > 0
{
print(weekBetweenDates,"weeks")//0 weeks
}
else if daysBetweenDates > 0
{
print(daysBetweenDates,"days")//5 days
}
else if hoursBetweenDates > 0
{
print(hoursBetweenDates,"hours")//120 hours
}
else if minBetweenDates > 0
{
print(minBetweenDates,"minutes")//7200 minutes
}
else if secbetweenDates > 0
{
print(secbetweenDates,"seconds")//seconds
}
}
add a comment |
--> Use this to find time gap between two dates in Swift(With two Strings).
func timeGapBetweenDates(previousDate : String,currentDate : String)
{
let dateString1 = previousDate
let dateString2 = currentDate
let Dateformatter = DateFormatter()
Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date1 = Dateformatter.date(from: dateString1)
let date2 = Dateformatter.date(from: dateString2)
let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
let secondsInAnHour: Double = 3600
let minsInAnHour: Double = 60
let secondsInDays: Double = 86400
let secondsInWeek: Double = 604800
let secondsInMonths : Double = 2592000
let secondsInYears : Double = 31104000
let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
let secbetweenDates = Int(distanceBetweenDates!)
if yearbetweenDates > 0
{
print(yearbetweenDates,"years")//0 years
}
else if monthsbetweenDates > 0
{
print(monthsbetweenDates,"months")//0 months
}
else if weekBetweenDates > 0
{
print(weekBetweenDates,"weeks")//0 weeks
}
else if daysBetweenDates > 0
{
print(daysBetweenDates,"days")//5 days
}
else if hoursBetweenDates > 0
{
print(hoursBetweenDates,"hours")//120 hours
}
else if minBetweenDates > 0
{
print(minBetweenDates,"minutes")//7200 minutes
}
else if secbetweenDates > 0
{
print(secbetweenDates,"seconds")//seconds
}
}
add a comment |
--> Use this to find time gap between two dates in Swift(With two Strings).
func timeGapBetweenDates(previousDate : String,currentDate : String)
{
let dateString1 = previousDate
let dateString2 = currentDate
let Dateformatter = DateFormatter()
Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date1 = Dateformatter.date(from: dateString1)
let date2 = Dateformatter.date(from: dateString2)
let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
let secondsInAnHour: Double = 3600
let minsInAnHour: Double = 60
let secondsInDays: Double = 86400
let secondsInWeek: Double = 604800
let secondsInMonths : Double = 2592000
let secondsInYears : Double = 31104000
let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
let secbetweenDates = Int(distanceBetweenDates!)
if yearbetweenDates > 0
{
print(yearbetweenDates,"years")//0 years
}
else if monthsbetweenDates > 0
{
print(monthsbetweenDates,"months")//0 months
}
else if weekBetweenDates > 0
{
print(weekBetweenDates,"weeks")//0 weeks
}
else if daysBetweenDates > 0
{
print(daysBetweenDates,"days")//5 days
}
else if hoursBetweenDates > 0
{
print(hoursBetweenDates,"hours")//120 hours
}
else if minBetweenDates > 0
{
print(minBetweenDates,"minutes")//7200 minutes
}
else if secbetweenDates > 0
{
print(secbetweenDates,"seconds")//seconds
}
}
--> Use this to find time gap between two dates in Swift(With two Strings).
func timeGapBetweenDates(previousDate : String,currentDate : String)
{
let dateString1 = previousDate
let dateString2 = currentDate
let Dateformatter = DateFormatter()
Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date1 = Dateformatter.date(from: dateString1)
let date2 = Dateformatter.date(from: dateString2)
let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
let secondsInAnHour: Double = 3600
let minsInAnHour: Double = 60
let secondsInDays: Double = 86400
let secondsInWeek: Double = 604800
let secondsInMonths : Double = 2592000
let secondsInYears : Double = 31104000
let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
let secbetweenDates = Int(distanceBetweenDates!)
if yearbetweenDates > 0
{
print(yearbetweenDates,"years")//0 years
}
else if monthsbetweenDates > 0
{
print(monthsbetweenDates,"months")//0 months
}
else if weekBetweenDates > 0
{
print(weekBetweenDates,"weeks")//0 weeks
}
else if daysBetweenDates > 0
{
print(daysBetweenDates,"days")//5 days
}
else if hoursBetweenDates > 0
{
print(hoursBetweenDates,"hours")//120 hours
}
else if minBetweenDates > 0
{
print(minBetweenDates,"minutes")//7200 minutes
}
else if secbetweenDates > 0
{
print(secbetweenDates,"seconds")//seconds
}
}
answered Jan 10 at 8:54
Ayush jainAyush jain
214
214
add a comment |
add a comment |
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
// Assuming that firstDate and secondDate are defined
// ...
var calendar: NSCalendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
components.day // This will return the number of day(s) between dates
add a comment |
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
// Assuming that firstDate and secondDate are defined
// ...
var calendar: NSCalendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
components.day // This will return the number of day(s) between dates
add a comment |
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
// Assuming that firstDate and secondDate are defined
// ...
var calendar: NSCalendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
components.day // This will return the number of day(s) between dates
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
// Assuming that firstDate and secondDate are defined
// ...
var calendar: NSCalendar = NSCalendar.currentCalendar()
// Replace the hour (time) of both dates with 00:00
let date1 = calendar.startOfDayForDate(firstDate)
let date2 = calendar.startOfDayForDate(secondDate)
let flags = NSCalendarUnit.DayCalendarUnit
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
components.day // This will return the number of day(s) between dates
answered Jan 27 '15 at 5:06
Emin Buğra SaralEmin Buğra Saral
2,37411219
2,37411219
add a comment |
add a comment |
This is the shorter version: Basically I try to get the difference between the post timestamp with the Date()
now.
// MARK: - UPDATE Time Stamp
static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) {
// date in the current state
let date = Date()
let dateComponentFormatter = DateComponentsFormatter()
// change the styling date, wether second minute or hour
dateComponentFormatter.unitsStyle = .abbreviated
dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
dateComponentFormatter.maximumUnitCount = 1
// return the date new format as a string in the completion
completion(dateComponentFormatter.string(from: postTimeStamp!, to: date))
}
add a comment |
This is the shorter version: Basically I try to get the difference between the post timestamp with the Date()
now.
// MARK: - UPDATE Time Stamp
static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) {
// date in the current state
let date = Date()
let dateComponentFormatter = DateComponentsFormatter()
// change the styling date, wether second minute or hour
dateComponentFormatter.unitsStyle = .abbreviated
dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
dateComponentFormatter.maximumUnitCount = 1
// return the date new format as a string in the completion
completion(dateComponentFormatter.string(from: postTimeStamp!, to: date))
}
add a comment |
This is the shorter version: Basically I try to get the difference between the post timestamp with the Date()
now.
// MARK: - UPDATE Time Stamp
static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) {
// date in the current state
let date = Date()
let dateComponentFormatter = DateComponentsFormatter()
// change the styling date, wether second minute or hour
dateComponentFormatter.unitsStyle = .abbreviated
dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
dateComponentFormatter.maximumUnitCount = 1
// return the date new format as a string in the completion
completion(dateComponentFormatter.string(from: postTimeStamp!, to: date))
}
This is the shorter version: Basically I try to get the difference between the post timestamp with the Date()
now.
// MARK: - UPDATE Time Stamp
static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) {
// date in the current state
let date = Date()
let dateComponentFormatter = DateComponentsFormatter()
// change the styling date, wether second minute or hour
dateComponentFormatter.unitsStyle = .abbreviated
dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
dateComponentFormatter.maximumUnitCount = 1
// return the date new format as a string in the completion
completion(dateComponentFormatter.string(from: postTimeStamp!, to: date))
}
answered Apr 10 '17 at 17:43
Buka CakrawalaBuka Cakrawala
796
796
add a comment |
add a comment |
For XCode Version 8.3.3 & Swift 3.0:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
var beginDate = "2017-08-24 12:00:00"
var endDate = "2017-09-07 12:00:00"
let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
print(startDateTime ?? "") //Convert String to Date
let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
print(endDateTime ?? "") //Convert String to Date
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]
let interval = endDateTime!.timeIntervalSince(startDateTime!)
var diff = dateComponentsFormatter.string(from: interval)!
print(diff)
var day_i = 0
var hour_i = 0
var min_i = 0
if (diff.contains("d"))
{
let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)
day_i = Int(day)!
print ("day --> (day_i)")
diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
print(diff)
}
let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
hour_i = Int(hour)!
print ("hour --> (hour_i)")
let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
min_i = Int(min)!
print ("min --> (min_i)")
add a comment |
For XCode Version 8.3.3 & Swift 3.0:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
var beginDate = "2017-08-24 12:00:00"
var endDate = "2017-09-07 12:00:00"
let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
print(startDateTime ?? "") //Convert String to Date
let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
print(endDateTime ?? "") //Convert String to Date
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]
let interval = endDateTime!.timeIntervalSince(startDateTime!)
var diff = dateComponentsFormatter.string(from: interval)!
print(diff)
var day_i = 0
var hour_i = 0
var min_i = 0
if (diff.contains("d"))
{
let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)
day_i = Int(day)!
print ("day --> (day_i)")
diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
print(diff)
}
let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
hour_i = Int(hour)!
print ("hour --> (hour_i)")
let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
min_i = Int(min)!
print ("min --> (min_i)")
add a comment |
For XCode Version 8.3.3 & Swift 3.0:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
var beginDate = "2017-08-24 12:00:00"
var endDate = "2017-09-07 12:00:00"
let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
print(startDateTime ?? "") //Convert String to Date
let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
print(endDateTime ?? "") //Convert String to Date
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]
let interval = endDateTime!.timeIntervalSince(startDateTime!)
var diff = dateComponentsFormatter.string(from: interval)!
print(diff)
var day_i = 0
var hour_i = 0
var min_i = 0
if (diff.contains("d"))
{
let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)
day_i = Int(day)!
print ("day --> (day_i)")
diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
print(diff)
}
let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
hour_i = Int(hour)!
print ("hour --> (hour_i)")
let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
min_i = Int(min)!
print ("min --> (min_i)")
For XCode Version 8.3.3 & Swift 3.0:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
var beginDate = "2017-08-24 12:00:00"
var endDate = "2017-09-07 12:00:00"
let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
print(startDateTime ?? "") //Convert String to Date
let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
print(endDateTime ?? "") //Convert String to Date
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]
let interval = endDateTime!.timeIntervalSince(startDateTime!)
var diff = dateComponentsFormatter.string(from: interval)!
print(diff)
var day_i = 0
var hour_i = 0
var min_i = 0
if (diff.contains("d"))
{
let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)
day_i = Int(day)!
print ("day --> (day_i)")
diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
print(diff)
}
let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
hour_i = Int(hour)!
print ("hour --> (hour_i)")
let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
min_i = Int(min)!
print ("min --> (min_i)")
edited Aug 16 '17 at 15:09
answered Aug 16 '17 at 12:16
Muge CevikMuge Cevik
8914
8914
add a comment |
add a comment |
Some addition in jose920405 answer to make it compatible with Swift 3.0 and above
func getDateTimeDiff(dateStr:String) -> String {
let formatter : DateFormatter = DateFormatter()
formatter.timeZone = NSTimeZone.local
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let now = formatter.string(from: NSDate() as Date)
let startDate = formatter.date(from: dateStr)
let endDate = formatter.date(from: now)
// *** create calendar object ***
var calendar = NSCalendar.current
// *** Get components using current Local & Timezone ***
print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))
// *** define calendar components to use as well Timezone to UTC ***
let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
calendar.timeZone = TimeZone(identifier: "UTC")!
let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)
// *** Get Individual components from date ***
let years = dateComponents.year!
let months = dateComponents.month!
let days = dateComponents.day!
let hours = dateComponents.hour!
let minutes = dateComponents.minute!
let seconds = dateComponents.second!
var timeAgo = ""
if (seconds > 0){
if seconds < 2 {
timeAgo = "Second Ago"
}
else{
timeAgo = "(seconds) Second Ago"
}
}
if (minutes > 0){
if minutes < 2 {
timeAgo = "Minute Ago"
}
else{
timeAgo = "(minutes) Minutes Ago"
}
}
if(hours > 0){
if minutes < 2 {
timeAgo = "Hour Ago"
}
else{
timeAgo = "(hours) Hours Ago"
}
}
if (days > 0) {
if minutes < 2 {
timeAgo = "Day Ago"
}
else{
timeAgo = "(days) Days Ago"
}
}
if(months > 0){
if minutes < 2 {
timeAgo = "Month Ago"
}
else{
timeAgo = "(months) Months Ago"
}
}
if(years > 0){
if minutes < 2 {
timeAgo = "Year Ago"
}
else{
timeAgo = "(years) Years Ago"
}
}
DLog("timeAgo is ===> (timeAgo)")
return timeAgo;
}
add a comment |
Some addition in jose920405 answer to make it compatible with Swift 3.0 and above
func getDateTimeDiff(dateStr:String) -> String {
let formatter : DateFormatter = DateFormatter()
formatter.timeZone = NSTimeZone.local
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let now = formatter.string(from: NSDate() as Date)
let startDate = formatter.date(from: dateStr)
let endDate = formatter.date(from: now)
// *** create calendar object ***
var calendar = NSCalendar.current
// *** Get components using current Local & Timezone ***
print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))
// *** define calendar components to use as well Timezone to UTC ***
let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
calendar.timeZone = TimeZone(identifier: "UTC")!
let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)
// *** Get Individual components from date ***
let years = dateComponents.year!
let months = dateComponents.month!
let days = dateComponents.day!
let hours = dateComponents.hour!
let minutes = dateComponents.minute!
let seconds = dateComponents.second!
var timeAgo = ""
if (seconds > 0){
if seconds < 2 {
timeAgo = "Second Ago"
}
else{
timeAgo = "(seconds) Second Ago"
}
}
if (minutes > 0){
if minutes < 2 {
timeAgo = "Minute Ago"
}
else{
timeAgo = "(minutes) Minutes Ago"
}
}
if(hours > 0){
if minutes < 2 {
timeAgo = "Hour Ago"
}
else{
timeAgo = "(hours) Hours Ago"
}
}
if (days > 0) {
if minutes < 2 {
timeAgo = "Day Ago"
}
else{
timeAgo = "(days) Days Ago"
}
}
if(months > 0){
if minutes < 2 {
timeAgo = "Month Ago"
}
else{
timeAgo = "(months) Months Ago"
}
}
if(years > 0){
if minutes < 2 {
timeAgo = "Year Ago"
}
else{
timeAgo = "(years) Years Ago"
}
}
DLog("timeAgo is ===> (timeAgo)")
return timeAgo;
}
add a comment |
Some addition in jose920405 answer to make it compatible with Swift 3.0 and above
func getDateTimeDiff(dateStr:String) -> String {
let formatter : DateFormatter = DateFormatter()
formatter.timeZone = NSTimeZone.local
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let now = formatter.string(from: NSDate() as Date)
let startDate = formatter.date(from: dateStr)
let endDate = formatter.date(from: now)
// *** create calendar object ***
var calendar = NSCalendar.current
// *** Get components using current Local & Timezone ***
print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))
// *** define calendar components to use as well Timezone to UTC ***
let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
calendar.timeZone = TimeZone(identifier: "UTC")!
let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)
// *** Get Individual components from date ***
let years = dateComponents.year!
let months = dateComponents.month!
let days = dateComponents.day!
let hours = dateComponents.hour!
let minutes = dateComponents.minute!
let seconds = dateComponents.second!
var timeAgo = ""
if (seconds > 0){
if seconds < 2 {
timeAgo = "Second Ago"
}
else{
timeAgo = "(seconds) Second Ago"
}
}
if (minutes > 0){
if minutes < 2 {
timeAgo = "Minute Ago"
}
else{
timeAgo = "(minutes) Minutes Ago"
}
}
if(hours > 0){
if minutes < 2 {
timeAgo = "Hour Ago"
}
else{
timeAgo = "(hours) Hours Ago"
}
}
if (days > 0) {
if minutes < 2 {
timeAgo = "Day Ago"
}
else{
timeAgo = "(days) Days Ago"
}
}
if(months > 0){
if minutes < 2 {
timeAgo = "Month Ago"
}
else{
timeAgo = "(months) Months Ago"
}
}
if(years > 0){
if minutes < 2 {
timeAgo = "Year Ago"
}
else{
timeAgo = "(years) Years Ago"
}
}
DLog("timeAgo is ===> (timeAgo)")
return timeAgo;
}
Some addition in jose920405 answer to make it compatible with Swift 3.0 and above
func getDateTimeDiff(dateStr:String) -> String {
let formatter : DateFormatter = DateFormatter()
formatter.timeZone = NSTimeZone.local
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let now = formatter.string(from: NSDate() as Date)
let startDate = formatter.date(from: dateStr)
let endDate = formatter.date(from: now)
// *** create calendar object ***
var calendar = NSCalendar.current
// *** Get components using current Local & Timezone ***
print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))
// *** define calendar components to use as well Timezone to UTC ***
let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
calendar.timeZone = TimeZone(identifier: "UTC")!
let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)
// *** Get Individual components from date ***
let years = dateComponents.year!
let months = dateComponents.month!
let days = dateComponents.day!
let hours = dateComponents.hour!
let minutes = dateComponents.minute!
let seconds = dateComponents.second!
var timeAgo = ""
if (seconds > 0){
if seconds < 2 {
timeAgo = "Second Ago"
}
else{
timeAgo = "(seconds) Second Ago"
}
}
if (minutes > 0){
if minutes < 2 {
timeAgo = "Minute Ago"
}
else{
timeAgo = "(minutes) Minutes Ago"
}
}
if(hours > 0){
if minutes < 2 {
timeAgo = "Hour Ago"
}
else{
timeAgo = "(hours) Hours Ago"
}
}
if (days > 0) {
if minutes < 2 {
timeAgo = "Day Ago"
}
else{
timeAgo = "(days) Days Ago"
}
}
if(months > 0){
if minutes < 2 {
timeAgo = "Month Ago"
}
else{
timeAgo = "(months) Months Ago"
}
}
if(years > 0){
if minutes < 2 {
timeAgo = "Year Ago"
}
else{
timeAgo = "(years) Years Ago"
}
}
DLog("timeAgo is ===> (timeAgo)")
return timeAgo;
}
answered Aug 21 '18 at 4:47
Ajit SatarkarAjit Satarkar
472320
472320
add a comment |
add a comment |
Use this code:
let registrationDateString = "2008-10-06 00:00:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
if let registrationDate = dateFormatter.date(from: registrationDateString) {
let currentDate = Date()
let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
from: registrationDate,
to: currentDate)
print("--------------------- Result: (dateDifference.year ?? 0) years (dateDifference.month ?? 0) months and (dateDifference.day ?? 0) days")
} else {
print("--------------------- No result")
}
Output is: Result: 10 years 1 months and 18 days
add a comment |
Use this code:
let registrationDateString = "2008-10-06 00:00:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
if let registrationDate = dateFormatter.date(from: registrationDateString) {
let currentDate = Date()
let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
from: registrationDate,
to: currentDate)
print("--------------------- Result: (dateDifference.year ?? 0) years (dateDifference.month ?? 0) months and (dateDifference.day ?? 0) days")
} else {
print("--------------------- No result")
}
Output is: Result: 10 years 1 months and 18 days
add a comment |
Use this code:
let registrationDateString = "2008-10-06 00:00:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
if let registrationDate = dateFormatter.date(from: registrationDateString) {
let currentDate = Date()
let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
from: registrationDate,
to: currentDate)
print("--------------------- Result: (dateDifference.year ?? 0) years (dateDifference.month ?? 0) months and (dateDifference.day ?? 0) days")
} else {
print("--------------------- No result")
}
Output is: Result: 10 years 1 months and 18 days
Use this code:
let registrationDateString = "2008-10-06 00:00:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
if let registrationDate = dateFormatter.date(from: registrationDateString) {
let currentDate = Date()
let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
from: registrationDate,
to: currentDate)
print("--------------------- Result: (dateDifference.year ?? 0) years (dateDifference.month ?? 0) months and (dateDifference.day ?? 0) days")
} else {
print("--------------------- No result")
}
Output is: Result: 10 years 1 months and 18 days
answered Nov 24 '18 at 6:52
iDev750iDev750
5961316
5961316
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f27182023%2fgetting-the-difference-between-two-nsdates-in-months-days-hours-minutes-seconds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I realize this is kind of old, but what do you intend to do with the difference? For example, if you're looking to format a string for the user, you should be using
NSDateComponentsFormatter
. It's very configurable, allowing you to get appropriately terse results (e.g..maximumUnitCount = 1
).– Ken Thomases
Jul 31 '15 at 6:10
Really, the question what you intend to do is absolutely essential. Consider that a month can be as little as 28 days, or as much as 31 days plus one hour.
– gnasher729
Oct 16 '15 at 15:33
stackoverflow.com/a/54452429/3908884
– Meet Doshi
Jan 31 at 2:46