The new version of SwiftDate has some major updates, removes the original DateFormat and adds something new.
1. String to Date
SwiftDate can automatically identify the mainstream time formats (ISO8601, RSS, Alt RSS,. NET, SQL, HTTP...), and you can also specify formats manually. Creating a new Date has never been so easy.
// All default datetime formats (15+) are recognized automatically let _ = "2010-05-20 15:30:00".toDate() // You can also provide your own format! let _ = "2010-05-20 15:30".toDate("yyyy-MM-dd HH:mm") // All ISO8601 variants are supported too with timezone parsing! let _ = "2017-09-17T11:59:29+02:00".toISODate() // RSS, Extended, HTTP, SQL, .NET and all the major variants are supported! let _ = "19 Nov 2015 22:20:40 +0100".toRSS(alt: true)
2. Date operation
Dates can be manipulated by adding or deleting time components in natural language. Time expansion tools are simple and convenient, and support common time zones, calendars, and local operations.
Standard mathematical operators can be used to operate between dates, intervals, date components and related time units!
// Math operations support time units let _ = ("2010-05-20 15:30:00".toDate() + 3.months - 2.days) let _ = Date() + 3.hours let _ = date1 + [.year:1, .month:2, .hour:5] let _ = date1 + date2 // extract single time unit components from date manipulation let over1Year = (date3 - date2).year > 1
3. Date comparison
SwiftDate contains a comprehensive set of comparison functions; you can compare two dates by granularity, check whether the date is a certain day, a range, and any other comparison you actually need.
It can still be compared by the standard mathematical operators (>,>=,<,<=).
// Standard math comparison is allowed let _ = dateA >= dateB || dateC < dateB // Complex comparisons includes granularity support let _ = dateA.compare(toDate: dateB, granularity: .hour) == .orderedSame let _ = dateA.isAfterDate(dateB, orEqual: true, granularity: .month) // > until month granularity let _ = dateC.isInRange(date: dateA, and: dateB, orEqual: true, granularity: .day) // > until day granularity let _ = dateA.earlierDate(dateB) // earlier date let _ = dateA.laterDate(dateB) // later date // Check if date is close to another with a given precision let _ = dateA.compareCloseTo(dateB, precision: 1.hours.timeInterval // Compare for relevant events: // .isToday, .isYesterday, .isTomorrow, .isWeekend, isNextWeek // .isSameDay, .isMorning, .isWeekday ... let _ = date.compare(.isToday) let _ = date.compare(.isNight) let _ = date.compare(.isNextWeek) let _ = date.compare(.isThisMonth) let _ = date.compare(.startOfWeek) let _ = date.compare(.isNextYear) // ...and MORE THAN 30 OTHER COMPARISONS BUILT IN // Operation in arrays (oldestIn, newestIn, sortedByNewest, sortedByOldest...) let _ = DateInRegion.oldestIn(list: datesArray) let _ = DateInRegion.sortedByNewest(list: datesArray)
4. Create Date using Region (Timezone, Calendar & Locale)
You can create new dates from strings, intervals, or using date components. SwiftDate provides a series of functions to create and reverse your dates, even randomly generated!
// All dates includes timezone, calendar and locales! // Create from string let rome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian) let date1 = DateInRegion("2010-01-01 00:00:00", region: rome)! // Create date from intervals let _ = DateInRegion(seconds: 39940, region: rome) let _ = DateInRegion(milliseconds: 5000, region: rome) // Date from components let _ = DateInRegion(components: { $0.year = 2001 $0.month = 9 $0.day = 11 $0.hour = 12 $0.minute = 0 }, region: rome) let _ = DateInRegion(year: 2001, month: 1, day: 5, hour: 23, minute: 30, second: 0, region: rome) // Random date generation with/without bounds let _ = DateInRegion.randomDate(region: rome) let _ = DateInRegion.randomDate(withinDaysBeforeToday: 5) let _ = DateInRegion.randomDates(count: 50, between: lowerLimitDate, and: upperLimitDate, region: rome)
5. Date of assignment
Dates can also be generated from other dates, SwiftDate contains a broad set of constructors. Using the dateAt() function, you can easily create more than 20 different dispatch dates.
let _ = DateInRegion().dateAt(.endOfDay) // today at the end of the day // Over 20 different relevant dates including .startOfDay, // .endOfDay, .startOfWeek, .tomorrow, .nextWeekday, .nextMonth, .prevYear, .nearestMinute and many others! let _ = dateA.nextWeekday(.friday) // the next friday after dateA let _ = (date.dateAt(.startOfMonth) - 3.days) let _ = dateA.compare(.endOfWeek) // Enumerate dates in range by providing your own custom // increment expressed in date components let from = DateInRegion("2015-01-01 10:00:00", region: rome)! let to = DateInRegion("2015-01-02 03:00:00", region: rome)! let increment2 = DateComponents.create { $0.hour = 1 $0.minute = 30 $0.second = 10 } // generate dates in range by incrementing +1h,30m,10s each new date let dates = DateInRegion.enumerateDates(from: fromDate2, to: toDate2, increment: increment2) // Altering time components let _ = dateA.dateBySet(hour: 10, min: 0, secs: 0) // Truncating a date let _ = dateA.dateTruncated(at: [.year,.month,.day]) // reset all time components keeping only date // Rounding a date let _ = dateA.dateRoundedAt(.toMins(10)) let _ = dateA.dateRoundedAt(.toFloor30Mins) // Adding components let _ = dateA.dateByAdding(5,.year) // Date at the start/end of any time component let _ = dateA.dateAtEndOf(.year) // 31 of Dec at 23:59:59 let _ = dateA.dateAtStartOf(.day) // at 00:00:00 of the same day let _ = dateA.dateAtStartOf(.month) // at 00:00:00 of the first day of the month
6. Composition extraction
You can extract components directly from the date, including the exact values represented in the date area (the correct time zone and region settings!).
// Create a date in a region, London but with the lcoale set to IT let london = Region(calendar: .gregorian, zone: .europeLondon, locale: .italian) let date = DateInRegion("2018-02-05 23:14:45", format: dateFormat, region: london)! // You can extract any of the all available time units. // VALUES ARE EXPRESSED IN THE REGION OF THE DATE (THE RIGHT TIMEZONE). // (you can still get the UTC/absolute value by getting the inner's absoluteDate). let _ = date.year // 2018 let _ = date.month // 2 let _ = date.monthNameDefault // 'Febbraio' as the locale is the to IT! let _ = date.firstDayOfWeek // 5 let _ = date.weekdayNameShort // 'Lun' as locale is the to IT // ... all components are supported: .year, .month, .day, .hour, .minute, .second, // .monthName, .weekday, .nearestHour, .firstDayOfWeek. .quarter and so on...
7. Switching between time zone/area settings and Calendars
You can easily convert any date to another area (or other calendar, area, time zone settings)! The new date contains all the values representing the cause of the target.
// Conversion between timezones is easy using convertTo(region:) function let rNY = Region(calendar: Calendars.gregorian, zone: Zones.americaNewYork, locale: Locales.english) let rRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian) let dateInNY = "2017-01-01 00:00:00".toDate(region: rNY) let dateInRome = dateInNY?.convertTo(region: rRome)! print(dateInRome.toString()) // "dom gen 01 06:00:00 +0100 2017\n" // You can also convert single region's attributes let dateInIndia = dateInNY?.convertTo(timezone: Zones.indianChristmas, locale: Locales.nepaliIndia) print("\(dateInIndia!.toString())") // "आइत जनवरी ०१ १२:००:०० +0700 २०१७\n"
8. Date format (Date to String)
The date format is simple. You can specify your own format, locale, or use any provided format.
// Date Formatting let london = Region(calendar: .gregorian, zone: .europeLondon, locale: .english) let date = ... // 2017-07-22T18:27:02+02:00 in london region let _ = date.toDotNET() // /Date(1500740822000+0200)/ let _ = date.toISODate() // 2017-07-22T18:27:02+02:00 let _ = date.toFormat("dd MMM yyyy 'at' HH:mm") // "22 July 2017 at 18:27" // You can also easily change locale when formatting a region let _ = date.toFormat("dd MMM", locale: .italian) // "22 Luglio" // Time Interval Formatting as Countdown let interval: TimeInterval = (2.hours.timeInterval) + (34.minutes.timeInterval) + (5.seconds.timeInterval) let _ = interval.toClock() // "2:34:05" // Time Interval Formatting by Components let _ = interval.toString { $0.maximumUnitCount = 4 $0.allowedUnits = [.day, .hour, .minute] $0.collapsesLargestUnit = true $0.unitsStyle = .abbreviated } // "2h 34m"
9. Relative date format (completely customizable!)
Relative formatting is new in SwiftDate; it supports more than 120 languages, two different styles (. default,. twitter), nine special cases (. long,. Long Convenient,. short,. short Time,. short Convenient,. narrow,. tiny,. quantify) and all of them can be tailored to your needs. Customized. Extensible formats allow you to provide your own transformations and rules to override default behavior.
// Twitter Style let _ = (Date() - 3.minutes).toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.english) // "3m" let _ = (Date() - 6.minutes).toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.italian) // "6 min fa" // Default Style let _ = (now2 - 5.hours).toRelative(style: RelativeFormatter.defaultStyle(), locale: Locales.english) // "5 hours ago" let y = (now2 - 40.minutes).toRelative(style: RelativeFormatter.defaultStyle(), locale: Locales.italian) // "45 minuti fa"
10. Codable support
Both DateIn Region and Region fully support the new Swift Codable protocol. This means that you can safely code/decode them:
// Encoding/Decoding a Region let region = Region(calendar: Calendars.gregorian, zone: Zones.europeOslo, locale: Locales.english) let encodedJSON = try JSONEncoder().encode(region) let decodedRegion = try JSONDecoder().decode(Region.self, from: encodedJSON) // Encoding/Decoding a DateInRegion let date = DateInRegion("2015-09-24T13:20:55", region: region) let encodedDate = try JSONEncoder().encode(date) let decodedDate = try JSONDecoder().decode(DateInRegion.self, from: encodedDate)
11. Time period
SwiftDate integrates Matthew York's DextTools module to support time periods.
See the documentation“ Time slot Part.