Last active
May 29, 2018 14:55
-
-
Save sketchytech/2afffc11a7231bb56ce4c3e8b2ffab53 to your computer and use it in GitHub Desktop.
Playing with Date, DateInterval, DateComponents, Calendar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Date { | |
init?(iso:String) { | |
let d = ISO8601DateFormatter() | |
guard let date = d.date(from: iso) else { | |
return nil | |
} | |
self = date | |
} | |
func year() -> String { | |
let formatter = DateFormatter() | |
formatter.dateFormat = "yyyy" | |
return formatter.string(from: self) | |
} | |
} | |
extension DateInterval { | |
init?(from startDate:String, to endDate:String) { | |
guard let firstDate = Date(iso: startDate), | |
let secondDate = Date(iso: endDate) else { | |
return nil | |
} | |
self = DateInterval(start: firstDate, end: secondDate) | |
} | |
func number(of:Calendar.Component) -> Int? { | |
let calendar = Calendar.current | |
// Replace the hour (time) of both dates with 00:00 | |
let date1 = calendar.startOfDay(for: self.start) | |
let date2 = calendar.startOfDay(for: self.end) | |
let components = calendar.dateComponents([of], from: date1, to: date2) | |
switch of { | |
case .year: | |
return components.year | |
case .day: | |
return components.day | |
case .month: | |
return components.month | |
case .era: | |
return components.era | |
case .hour: | |
return components.hour | |
case .minute: | |
return components.minute | |
case .second: | |
return components.second | |
case .weekday: | |
return components.weekday | |
case .weekdayOrdinal: | |
return components.weekdayOrdinal | |
case .quarter: | |
return components.quarter | |
case .weekOfMonth: | |
return components.weekOfMonth | |
case .weekOfYear: | |
return components.weekOfYear | |
case .yearForWeekOfYear: | |
return components.yearForWeekOfYear | |
case .nanosecond: | |
return components.nanosecond | |
default: | |
return nil | |
} | |
} | |
func dateArray(intervalType:Calendar.Component, interval:Int) -> [Date]? { | |
let calendar = Calendar.current | |
let date1 = calendar.startOfDay(for: self.start) | |
var dates = [date1] | |
var dateComponent = DateComponents() | |
switch intervalType { | |
case .year: | |
dateComponent.year = interval | |
case .day: | |
dateComponent.day = interval | |
case .month: | |
dateComponent.month = interval | |
case .era: | |
dateComponent.era = interval | |
case .hour: | |
dateComponent.hour = interval | |
case .minute: | |
dateComponent.minute = interval | |
case .second: | |
dateComponent.second = interval | |
case .weekday: | |
dateComponent.weekday = interval | |
case .weekdayOrdinal: | |
dateComponent.weekdayOrdinal = interval | |
case .quarter: | |
dateComponent.quarter = interval | |
case .weekOfMonth: | |
dateComponent.weekOfMonth = interval | |
case .weekOfYear: | |
dateComponent.weekOfYear = interval | |
case .yearForWeekOfYear: | |
dateComponent.yearForWeekOfYear = interval | |
case .nanosecond: | |
dateComponent.nanosecond = interval | |
default: | |
return nil | |
} | |
// replace with | |
repeat { | |
dates.append(calendar.date(byAdding: dateComponent, to: dates.last!)!) | |
} | |
while self.contains(dates.last!) | |
if !self.contains(dates.last!) { | |
dates.removeLast() | |
} | |
return dates | |
} | |
func years() -> [String]? { | |
guard let dates = self.dateArray(intervalType: .year, interval: 10) else { return nil} | |
let d = dates.map({$0.year()}) | |
return d | |
} | |
} | |
let int = DateInterval(from: "1870-01-01T12:00:00Z", to: "2020-01-01T12:00:00Z") | |
int?.number(of: .year) | |
int?.number(of: .day) | |
int?.number(of: .nanosecond) | |
int?.dateArray(intervalType: .year, interval: 10) | |
int?.dateArray(intervalType: .month, interval: 120) | |
int?.years() // returns [String]? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment