//: Advanced Dates and Times in Swift import Foundation #if os(macOS) import PlaygroundSupport import UserNotifications #endif // Date Intervals let calendar = Calendar.autoupdatingCurrent let timeZone = TimeZone(identifier: "America/Denver")! let talkStart = DateComponents( timeZone: timeZone, year: 2017, month: 8, day: 14, hour: 15, minute: 45, second: 00) let talkEnd = DateComponents( timeZone: timeZone, year: 2017, month: 8, day: 14, hour: 16, minute: 30, second: 00) let startDate = calendar.date(from: talkStart)! let endDate = calendar.date(from: talkEnd)! let talkInterval = DateInterval( start: startDate, end: endDate) // 2700 talkInterval.duration // "2017-08-14 21:45:00 +0000 to 2017-08-14 22:30:00 +0000" talkInterval.description // true talkInterval.contains(Date()) // Date Interval Formatting let formatter = DateIntervalFormatter() formatter.string(from: talkInterval) // "8/14/17, 3:45 - 4:30 PM" var prefix = "" if calendar.isDateInToday(startDate) && calendar.isDateInToday(endDate) { formatter.dateStyle = .none prefix = "Today " } else if calendar.isDateInYesterday(startDate) && calendar.isDateInYesterday(endDate) { formatter.dateStyle = .none prefix = "Yesterday " } else if calendar.isDateInTomorrow(startDate) && calendar.isDateInTomorrow(endDate) { formatter.dateStyle = .none prefix = "Tomorrow " } else { formatter.dateStyle = .short } prefix + formatter.string(from: talkInterval)! // "Today 3:45 – 4:30 PM" // Converting Between Units // How many days are there in this month? calendar.range(of: Calendar.Component.day, in: Calendar.Component.month, for: Date())! // Range(1..<31) // How many days are there in this year? calendar.range(of: .day, in: .year, for: Date()) // Range(1..<32) calendar.maximumRange(of: .second) // Range(0..<60) calendar.minimumRange(of: .day) // Range(1..<29) // How many seconds are there in this year? calendar.range(of: .second, in: .year, for: Date()) // Range(0..<60) let monthRange = calendar.range(of: .month, in: .year, for: Date())! for month in monthRange.lowerBound ..< monthRange.upperBound { let date = calendar.date(bySetting: .month, value: month, of: Date())! let dayRange = calendar.range(of: .day, in: .month, for: date)! for day in dayRange.lowerBound ..< dayRange.upperBound { let date = calendar.date(bySetting: .day, value: day, of: date)! let hourRange = calendar.range(of: .hour, in: .day, for: date)! for hour in hourRange.lowerBound ..< hourRange.upperBound { // This is getting out of hand! } } } // Measure time interval let year = 2017 let beginningOfAnyYearComponents = DateComponents( month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0) var beginningOfThisYearComponents = beginningOfAnyYearComponents beginningOfThisYearComponents.year = year let beginningOfThisYear = calendar.date(from: beginningOfThisYearComponents)! let beginningOfNextYear = calendar .nextDate(after: beginningOfThisYear, matching: beginningOfAnyYearComponents, matchingPolicy: .strict)! let seconds = beginningOfNextYear.timeIntervalSince(beginningOfThisYear) // Measure date interval let interval = DateInterval(start: beginningOfThisYear, end: beginningOfNextYear) interval.duration // Measure components calendar.dateComponents([.second], from: beginningOfThisYear, to: beginningOfNextYear).second calendar.dateComponents([.minute], from: beginningOfThisYear, to: beginningOfNextYear) // Notifications #if os(macOS) let trigger = UNCalendarNotificationTrigger(dateMatching:beginningOfAnyYearComponents, repeats: true) trigger.nextTriggerDate() // "Jan 1, 2018 at 12:00 AM" calendar.nextDate(after: Date(), matching: beginningOfAnyYearComponents, matchingPolicy: .nextTime) // "Jan 1, 2018 at 12:00 AM" let content = UNMutableNotificationContent() content.title = "Happy new year!" let request = UNNotificationRequest(identifier: "com.slaunchaman.happynewyear", content: content, trigger: trigger) PlaygroundPage.current.needsIndefiniteExecution = true UNUserNotificationCenter.current().add(request) { (error) in if let error = error { print("Error: \(error.localizedDescription)") } else { print("Success!") } PlaygroundPage.current.finishExecution() } #endif