Get Total Include Months Between 2 Date in Swift

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

Xcode 8.3 • Swift 3.1 or later

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

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

Using Date Components Formatter

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


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

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

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

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

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

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

Calculate duration between date ios in Years, months and date format

If you need the difference (in years, months, days) numerically then
compute NSDateComponents as in Swift days between two NSDates or Rajan's answer.

If you need the difference as a (localized) string to present it to the user,
then use NSDateComponentsFormatter like this

let form = NSDateComponentsFormatter()
form.maximumUnitCount = 2
form.unitsStyle = .Full
form.allowedUnits = [.Year, .Month, .Day]
let s = form.stringFromDate(date1, toDate: date2)

As already mentioned in the comments, computing the difference
from the pure time interval between the dates cannot give correct
results because most information about the dates is lost.

Update for Swift 3:

let form = DateComponentsFormatter()
form.maximumUnitCount = 2
form.unitsStyle = .full
form.allowedUnits = [.year, .month, .day]
let s = form.string(from: date1, to: date2)

Calculating the difference between two dates in Swift

I ended up creating a custom operator for Date:

extension Date {

static func - (lhs: Date, rhs: Date) -> TimeInterval {
return lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
}

}

With this operator I can now compute the difference between two dates on a more abstract level without caring about timeIntervalSinceReferenceDate or what exactly the reference date is – and without losing precision, for example:

let delta = toDate - fromDate

Obviously, I didn't change much, but for me it's a lot more readable and consequent: Swift has the + operator already implemented for a Date and a TimeInterval:

/// Returns a `Date` with a specified amount of time added to it.
public static func + (lhs: Date, rhs: TimeInterval) -> Date

So it's already supporting

Date + TimeInterval = Date

Consequently, it should also support

Date - Date = TimeInterval

in my opinion and that's what I added with the simple implementation of the - operator. Now I can simply write the example function exactly as mentioned in my question:

func computeNewDate(from fromDate: Date, to toDate: Date) -> Date    
let delta = toDate - fromDate // `Date` - `Date` = `TimeInterval`
let today = Date()
if delta < 0 {
return today
} else {
return today + delta // `Date` + `TimeInterval` = `Date`
}
}

It might very well be that this has some downsides that I'm not aware of at this moment and I'd love to hear your thoughts on this.

Getting the difference in two dates - Swift

Change all of your NSDate to Date, then replace your requestedComponent with this:

let requestedComponent: Set<Calendar.Component> = [ .month, .day, .hour, .minute, .second]

Your difference will be:

let timeDifference = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime!)

FYI: Your dateFormatter doesn't work with this "25/12/16 00:00:00"
here is your whole class in correct form:

class ViewController: UIViewController {

@IBOutlet weak var dateLabelOutlet: UILabel!

let currentDate = Date()
let dateFormatter = DateFormatter()

let userCalendar = Calendar.current

let requestedComponent: Set<Calendar.Component> = [.month,.day,.hour,.minute,.second]

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

func printTime() {
dateFormatter.dateFormat = "dd/MM/yy hh:mm:ss"
let startTime = Date()
let endTime = dateFormatter.date(from: "25/12/16 00:00:00")
let timeDifference = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime!)

dateLabelOutlet.text = "\(timeDifference.month) Months \(timeDifference.day) Days \(timeDifference.minute) Minutes \(timeDifference.second) Seconds"
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Swift 3 - find number of calendar days between two dates

Turns out this is much simpler to do in Swift 3:

extension Date {    

func interval(ofComponent comp: Calendar.Component, fromDate date: Date) -> Int {

let currentCalendar = Calendar.current

guard let start = currentCalendar.ordinality(of: comp, in: .era, for: date) else { return 0 }
guard let end = currentCalendar.ordinality(of: comp, in: .era, for: self) else { return 0 }

return end - start
}
}

Edit

Comparing the ordinality of the two dates should be within the same era instead of the same year, since naturally the two dates may fall in different years.

Usage

let yesterday = Date(timeInterval: -86400, since: Date())
let tomorrow = Date(timeInterval: 86400, since: Date())

let diff = tomorrow.interval(ofComponent: .day, fromDate: yesterday)
// return 2

All dates between two Date objects (Swift)

Just add one day unit to the date until it reaches
the current date (Swift 2 code):

var date = startDateNSDate // first date
let endDate = NSDate() // last date

// Formatter for printing the date, adjust it according to your needs:
let fmt = NSDateFormatter()
fmt.dateFormat = "dd/MM/yyyy"

// While date <= endDate ...
while date.compare(endDate) != .OrderedDescending {
print(fmt.stringFromDate(date))
// Advance by one day:
date = calendar.dateByAddingUnit(.Day, value: 1, toDate: date, options: [])!
}

Update for Swift 3:

var date = startDate // first date
let endDate = Date() // last date

// Formatter for printing the date, adjust it according to your needs:
let fmt = DateFormatter()
fmt.dateFormat = "dd/MM/yyyy"

while date <= endDate {
print(fmt.string(from: date))
date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
}

Difference between 2 dates in weeks and days using swift 3 and xcode 8

You can use Calendar's dateComponents(_:from:to:) to find the difference between 2 dates to your desired units.

Example:

let dateRangeStart = Date()
let dateRangeEnd = Date().addingTimeInterval(12345678)
let components = Calendar.current.dateComponents([.weekOfYear, .month], from: dateRangeStart, to: dateRangeEnd)

print(dateRangeStart)
print(dateRangeEnd)
print("difference is \(components.month ?? 0) months and \(components.weekOfYear ?? 0) weeks")

> 2017-02-17 10:05:19 +0000
> 2017-07-10 07:26:37 +0000
> difference is 4 months and 3 weeks

let months = components.month ?? 0
let weeks = components.weekOfYear ?? 0

Calculating the number of days between two dates in swift

It has to do with the order that you're creating your variables and comparing them.

The first thing you do is create today. Then, you create twoWeeksFromNow, based on a new Date() that will be slightly further in the future than today was. On my machine, in a playground, the second date is about 300 microseconds further in the future than the first.

Then, for numDaysWithDate, you compare twoWeeksFromNow to another new Date(), even more slightly in the future. So, your time frame is very slightly less than 2 full weeks, giving you 13 days.

But, for numDaysWithToday, you compare twoWeeksFromNow with the original today, which was created before twoWeeksFromNow was, making it slightly longer than 2 weeks, giving you 14 days.

If you change the order of the the today and twoWeeksFromNow declarations, you can see a different result:

var twoWeeksFromNow: Date = Calendar.current.date(byAdding: .day,
value: 14, to: Date())!
var today = Date()

Now, because today was created slightly later than the date that twoWeeksFromNow was created from, both results are 13.

How to determine date falls in between two dates swift

If you have Date objects, they are Comparable and Equatable. You can write code like:

if breakDate >= startDate && breakDate <= endDate {
// breakDate is between startDate and endDate
}

Edit:

As pointed out by LeoDabus in the comments, you could also use the pattern match operator (although I personally don't like it)

if startDate ... endDate ~= breakDate {
// breakDate is between startDate and endDate
}

or contains:

if (startDate...endDate).contains(breakDate) {
// breakDate is between startDate and endDate
}

If you have date strings, create a date formatter that converts your date strings to Date objects, then use code like the above.

If the date strings are always in "Internet" date format (ISO 8601), and you are certain they will always be in the same time zone, you can also use string comparison and compare the date strings directly (using any of the above forms of comparison, except maybe contains?)



Related Topics



Leave a reply



Submit