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

4

36

I am trying to calculate the difference between 2 dates (one is the current date and the other from datepicker) in weeks and days then displaying the result on a label, that's what i have done so far, i appreciate the help of more experienced developers here!

let EDD = datePicker.date
let now = NSDate()

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .short
formatter.allowedUnits = [.day]
formatter.maximumUnitCount = 2   

let string = formatter.string (from: now as Date, to: EDD)

label.text = string
Vereen answered 17/2, 2017 at 9:59 Comment(3)
Hey FormulaOne.... Please See this answer #27182523Suu
It would improve the question if you said how your current code (which is fine as far as it goes) is falling short of your desired outcome.Destruction
Makes sense as it would save you time to find me an answer, next time! :)Vereen
C
60

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
Clutch answered 17/2, 2017 at 10:4 Comment(7)
Thanks for your help, the first solution worked beautifully for me though :)Vereen
Right, what i really wanted was the difference between the dates in days (or weeks) then i can use that difference to make a calculation, what i am getting from your solution is a string that i can't make any calculations on, ThanksVereen
If you look how the string is constructed, you'll see the components.month and components.weekOfYear these are Int valuesClutch
@Vereen I'm always happy to accept an upvote by way of thanks! ;)Clutch
don't even know how to do that!Vereen
If you see an answer you like, click the up arrow at the top left of that answer. If someone answers your question, click on the checkmarkClutch
Thank you for your helpful answer. However, what is the difference between the different Calendar Components for Week, like weekOfYear, weekOfMonth, weekday and weekdayOrdinal, when comparing two Dates? And why did you chose weekOfYear? Does this still work, when the two Dates are in different Years, even though the weekOfYear counter should reset?Usquebaugh
F
12

You are close. Just add .weekOfMonth (meaning "quantity of weeks" according to the API documentation) to the allowed units. Example:

let now = Date()
let endDate = now.addingTimeInterval(24 * 3600 * 17)

let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.day, .weekOfMonth]
formatter.unitsStyle = .full
let string = formatter.string(from: now, to: endDate)!

print(string) // 2 weeks, 3 days

Setting maximumUnitCount = 2 is not necessary because there are only two allowed units.

Folklore answered 17/2, 2017 at 10:11 Comment(2)
Right, what i really wanted was the difference between the dates in days (or weeks) then i can use that difference to make a calculation, what i am getting from your solution is a string that i can't make any calculations on, ThanksVereen
@FormulaOne: Well that wasn't apparent from your question. You said "... then displaying the result on a label... " which means that you want a string. – If you need the difference as numbers then use DateComponents as suggested in Ashley's answer.Folklore
C
5

Swift 4

testing using Xcode Version 9.2

  • combining the above two answers that helps me

Use the following method to get the string by the difference between two dates the idea is to localize the words weeks/ days /minutes by the format.

func getTimeComponentString(olderDate older: Date,newerDate newer: Date) -> (String?)  {
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full

    let componentsLeftTime = Calendar.current.dateComponents([.minute , .hour , .day,.month, .weekOfMonth,.year], from: older, to: newer)

    let year = componentsLeftTime.year ?? 0
    if  year > 0 {
        formatter.allowedUnits = [.year]
        return formatter.string(from: older, to: newer)
    }


    let month = componentsLeftTime.month ?? 0
    if  month > 0 {
        formatter.allowedUnits = [.month]
        return formatter.string(from: older, to: newer)
    }

    let weekOfMonth = componentsLeftTime.weekOfMonth ?? 0
    if  weekOfMonth > 0 {
        formatter.allowedUnits = [.weekOfMonth]
        return formatter.string(from: older, to: newer)
    }

    let day = componentsLeftTime.day ?? 0
    if  day > 0 {
        formatter.allowedUnits = [.day]
        return formatter.string(from: older, to: newer)
    }

    let hour = componentsLeftTime.hour ?? 0
    if  hour > 0 {
        formatter.allowedUnits = [.hour]
        return formatter.string(from: older, to: newer)
    }

    let minute = componentsLeftTime.minute ?? 0
    if  minute > 0 {
        formatter.allowedUnits = [.minute]
        return formatter.string(from: older, to: newer) ?? ""
    }

    return nil
}

Here is how you can use

    let nowDate = Date()
    let endDate = Date().addingTimeInterval(12345678)

    let string =  String.getTimeComponentString(olderDate: nowDate, newerDate: endDate)!
    print(nowDate)
    print(endDate)
    print(string)
  • Output

  • 2018-03-08 08:11:22 +0000
  • 2018-07-29 05:32:41 +0000
  • 4 months
Cataract answered 8/3, 2018 at 8:20 Comment(0)
D
5

Swift 4,5

You can find date different in weeks with this one line code.

let totalWeeks = Calendar.current.dateComponents([.weekOfMonth], from: Date(), to: endDate).weekOfMonth!

//for totalDays
let totalDays = Calendar.current.dateComponents([.day], from: Date(), to: endDate).day!
Dicrotic answered 7/1, 2020 at 7:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.