Is a Date in Same Week, Month, Year of Another Date in Swift

Is a date in same week, month, year of another date in swift

You can use calendar method isDate(equalTo:granularity:) to check it as follow:

Xcode 11 • Swift 5.1

extension Date {

func isEqual(to date: Date, toGranularity component: Calendar.Component, in calendar: Calendar = .current) -> Bool {
calendar.isDate(self, equalTo: date, toGranularity: component)
}

func isInSameYear(as date: Date) -> Bool { isEqual(to: date, toGranularity: .year) }
func isInSameMonth(as date: Date) -> Bool { isEqual(to: date, toGranularity: .month) }
func isInSameWeek(as date: Date) -> Bool { isEqual(to: date, toGranularity: .weekOfYear) }

func isInSameDay(as date: Date) -> Bool { Calendar.current.isDate(self, inSameDayAs: date) }

var isInThisYear: Bool { isInSameYear(as: Date()) }
var isInThisMonth: Bool { isInSameMonth(as: Date()) }
var isInThisWeek: Bool { isInSameWeek(as: Date()) }

var isInYesterday: Bool { Calendar.current.isDateInYesterday(self) }
var isInToday: Bool { Calendar.current.isDateInToday(self) }
var isInTomorrow: Bool { Calendar.current.isDateInTomorrow(self) }

var isInTheFuture: Bool { self > Date() }
var isInThePast: Bool { self < Date() }
}

Get the current week number in month from Date

This is due to the 1st day of the month falling on a sunday, try march 01, 2020 if you want confirmation.

The first week of the month is chosen by Swift according to their own standards as ISO standards do not suggest any specific implementations so the Swift team went with this. You can ask them in their forums what their reasoning behind this is Wikipedia link

Swift - Check if date is in next week / month. ( isDateInNextWeek() isDateInNextMonth() )

The algorithm is not very spectacular:

  1. Calculate start of current week
  2. Use result from 1 to calculate start of next week
  3. Use result from 2 to calculate start of week after next week
  4. Date is in next week if its on or after the start of next week and before the start of the week after next week

NSCalendar does most of the work for us. But it looks still a bit intimidating, at least if you don't use these date methods often. You should read the documentation of all of these methods to understand them.

let calendar = NSCalendar.currentCalendar()
let date = NSDate()

var startOfThisWeek: NSDate?
if !calendar.rangeOfUnit(.CalendarUnitWeekOfMonth, startDate: &startOfThisWeek, interval: nil, forDate: date) {
fatalError("Can't calculate start of this week")
}
let startOfNextWeek = calendar.dateByAddingUnit(.CalendarUnitWeekOfMonth, value: 1, toDate: startOfThisWeek!, options: nil)!
let startOfNextNextWeek = calendar.dateByAddingUnit(.CalendarUnitWeekOfMonth, value: 1, toDate: startOfNextWeek, options: nil)!

Just switch .CalendarUnitWeekOfMonth with .CalendarUnitMonth and you get the calculation for this, next and the following month.

var startOfThisMonth: NSDate?
if !calendar.rangeOfUnit(.CalendarUnitMonth, startDate: &startOfThisMonth, interval: nil, forDate: date) {
fatalError("Can't calculate start of this month")
}
let startOfNextMonth = calendar.dateByAddingUnit(.CalendarUnitMonth, value: 1, toDate: startOfThisMonth!, options: nil)!
let startOfNextNextMonth = calendar.dateByAddingUnit(.CalendarUnitMonth, value: 1, toDate: startOfNextMonth, options: nil)!

 

And the test:

let testDate = NSDate(timeIntervalSinceNow: 7*24*60*60)

if startOfThisWeek <= testDate && testDate < startOfNextWeek {
println("\(testDate) is this week")
}
if startOfNextWeek <= testDate && testDate < startOfNextNextWeek {
println("\(testDate) is next week")
}
if startOfThisMonth <= testDate && testDate < startOfNextMonth {
println("\(testDate) is this month")
}
if startOfNextMonth <= testDate && testDate < startOfNextNextMonth {
println("\(testDate) is next month")
}

Result:

"2015-03-22 02:55:19 +0000 is next week"

"2015-03-22 02:55:19 +0000 is this month"

Sounds right.

And if you want to use <=, ==, < etc. instead of the ugly (and confusing) NSComparisonResult you need this as well:

public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs === rhs || lhs.compare(rhs) == .OrderedSame
}

public func <(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}

extension NSDate: Comparable { }

This is iOS8 code. If you want to write code that works on older versions you have to replace dateByAddingUnit:value::toDate:options: by good old NSDateComponents. i.e:

let offSetComponents = NSDateComponents()
offSetComponents.weekOfMonth = 1
let startOfNextWeek = calendar.dateByAddingComponents(offSetComponents, toDate: startOfThisWeek, options: nil)

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"

Make sure returned dates are within seven days of current date

This is a solution getting the end date with the nextDate(after:matching:matchingPolicy:) API of Calendar

extension Date {
func isInSevenDays() -> Bool {
let now = Date()
let calendar = Calendar.current
let weekday = calendar.dateComponents([.weekday], from: now)
let startDate = calendar.startOfDay(for: now)
let nextWeekday = calendar.nextDate(after: now, matching: weekday, matchingPolicy: .nextTime)!
let endDate = calendar.date(byAdding: .day, value: 1, to: nextWeekday)!
return self >= startDate && self < endDate
}
}

Swift - Print what the current week of the year is

Try the following code snippet. It is written in Swift 3 and Swift 4.

let calendar = Calendar.current
let weekOfYear = calendar.component(.weekOfYear, from: Date())
print(weekOfYear)

This will print the total week of the year.



Related Topics



Leave a reply



Submit