576 lines
21 KiB
Swift
576 lines
21 KiB
Swift
//
|
|
// SwiftDate
|
|
// Parse, validate, manipulate, and display dates, time and timezones in Swift
|
|
//
|
|
// Created by Daniele Margutti
|
|
// - Web: https://www.danielemargutti.com
|
|
// - Twitter: https://twitter.com/danielemargutti
|
|
// - Mail: hello@danielemargutti.com
|
|
//
|
|
// Copyright © 2019 Daniele Margutti. Licensed under MIT License.
|
|
//
|
|
|
|
import SwiftDate
|
|
import XCTest
|
|
|
|
class TestFormatters: XCTestCase {
|
|
|
|
public func datesList() -> [String: [String: String]] {
|
|
return [
|
|
"2017-07-22T18:27:02+02:00": [
|
|
|
|
"dotnet": "/Date(1500740822000+0200)/",
|
|
"rss": "Sat, 22 Jul 2017 18:27:02 +0200",
|
|
"rss_alt": "22 Jul 2017 18:27:02 +0200",
|
|
"sql": "2017-07-22T18:27:02.000+02",
|
|
"iso": "2017-07-22T18:27:02+02:00"
|
|
],
|
|
"2017-02-03T06:30:12+01:00": [
|
|
|
|
"dotnet": "/Date(1486099812000+0100)/",
|
|
"rss": "Fri, 3 Feb 2017 06:30:12 +0100",
|
|
"rss_alt": "3 Feb 2017 06:30:12 +0100",
|
|
"sql": "2017-02-03T06:30:12.000+01",
|
|
"iso": "2017-02-03T06:30:12+01:00"
|
|
],
|
|
"2016-03-31T10:57:44+02:00": [
|
|
|
|
"dotnet": "/Date(1459414664000+0200)/",
|
|
"rss": "Thu, 31 Mar 2016 10:57:44 +0200",
|
|
"rss_alt": "31 Mar 2016 10:57:44 +0200",
|
|
"sql": "2016-03-31T10:57:44.000+02",
|
|
"iso": "2016-03-31T10:57:44+02:00"
|
|
],
|
|
"2016-07-23T17:05:31+02:00": [
|
|
|
|
"dotnet": "/Date(1469286331000+0200)/",
|
|
"rss": "Sat, 23 Jul 2016 17:05:31 +0200",
|
|
"rss_alt": "23 Jul 2016 17:05:31 +0200",
|
|
"sql": "2016-07-23T17:05:31.000+02",
|
|
"iso": "2016-07-23T17:05:31+02:00"
|
|
],
|
|
"2017-05-15T11:26:36+02:00": [
|
|
|
|
"dotnet": "/Date(1494840396000+0200)/",
|
|
"rss": "Mon, 15 May 2017 11:26:36 +0200",
|
|
"rss_alt": "15 May 2017 11:26:36 +0200",
|
|
"sql": "2017-05-15T11:26:36.000+02",
|
|
"iso": "2017-05-15T11:26:36+02:00"
|
|
],
|
|
"2018-03-27T20:50:37+02:00": [
|
|
|
|
"dotnet": "/Date(1522176637000+0200)/",
|
|
"rss": "Tue, 27 Mar 2018 20:50:37 +0200",
|
|
"rss_alt": "27 Mar 2018 20:50:37 +0200",
|
|
"sql": "2018-03-27T20:50:37.000+02",
|
|
"iso": "2018-03-27T20:50:37+02:00"
|
|
],
|
|
"2018-02-16T14:52:52+01:00": [
|
|
|
|
"dotnet": "/Date(1518789172000+0100)/",
|
|
"rss": "Fri, 16 Feb 2018 14:52:52 +0100",
|
|
"rss_alt": "16 Feb 2018 14:52:52 +0100",
|
|
"sql": "2018-02-16T14:52:52.000+01",
|
|
"iso": "2018-02-16T14:52:52+01:00"
|
|
],
|
|
"2016-01-10T16:55:35+01:00": [
|
|
|
|
"dotnet": "/Date(1452441335000+0100)/",
|
|
"rss": "Sun, 10 Jan 2016 16:55:35 +0100",
|
|
"rss_alt": "10 Jan 2016 16:55:35 +0100",
|
|
"sql": "2016-01-10T16:55:35.000+01",
|
|
"iso": "2016-01-10T16:55:35+01:00"
|
|
],
|
|
"2017-05-02T23:53:44+02:00": [
|
|
|
|
"dotnet": "/Date(1493762024000+0200)/",
|
|
"rss": "Tue, 2 May 2017 23:53:44 +0200",
|
|
"rss_alt": "2 May 2017 23:53:44 +0200",
|
|
"sql": "2017-05-02T23:53:44.000+02",
|
|
"iso": "2017-05-02T23:53:44+02:00"
|
|
],
|
|
"2017-05-13T20:05:38+02:00": [
|
|
|
|
"dotnet": "/Date(1494698738000+0200)/",
|
|
"rss": "Sat, 13 May 2017 20:05:38 +0200",
|
|
"rss_alt": "13 May 2017 20:05:38 +0200",
|
|
"sql": "2017-05-13T20:05:38.000+02",
|
|
"iso": "2017-05-13T20:05:38+02:00"
|
|
],
|
|
"2017-10-04T17:25:36+02:00": [
|
|
|
|
"dotnet": "/Date(1507130736000+0200)/",
|
|
"rss": "Wed, 4 Oct 2017 17:25:36 +0200",
|
|
"rss_alt": "4 Oct 2017 17:25:36 +0200",
|
|
"sql": "2017-10-04T17:25:36.000+02",
|
|
"iso": "2017-10-04T17:25:36+02:00"
|
|
],
|
|
"2016-04-14T11:58:58+02:00": [
|
|
|
|
"dotnet": "/Date(1460627938000+0200)/",
|
|
"rss": "Thu, 14 Apr 2016 11:58:58 +0200",
|
|
"rss_alt": "14 Apr 2016 11:58:58 +0200",
|
|
"sql": "2016-04-14T11:58:58.000+02",
|
|
"iso": "2016-04-14T11:58:58+02:00"
|
|
],
|
|
"2016-10-03T13:15:37+02:00": [
|
|
|
|
"dotnet": "/Date(1475493337000+0200)/",
|
|
"rss": "Mon, 3 Oct 2016 13:15:37 +0200",
|
|
"rss_alt": "3 Oct 2016 13:15:37 +0200",
|
|
"sql": "2016-10-03T13:15:37.000+02",
|
|
"iso": "2016-10-03T13:15:37+02:00"
|
|
],
|
|
"2015-08-23T16:28:34+02:00": [
|
|
|
|
"dotnet": "/Date(1440340114000+0200)/",
|
|
"rss": "Sun, 23 Aug 2015 16:28:34 +0200",
|
|
"rss_alt": "23 Aug 2015 16:28:34 +0200",
|
|
"sql": "2015-08-23T16:28:34.000+02",
|
|
"iso": "2015-08-23T16:28:34+02:00"
|
|
],
|
|
"2016-09-04T19:52:29+02:00": [
|
|
|
|
"dotnet": "/Date(1473011549000+0200)/",
|
|
"rss": "Sun, 4 Sep 2016 19:52:29 +0200",
|
|
"rss_alt": "4 Sep 2016 19:52:29 +0200",
|
|
"sql": "2016-09-04T19:52:29.000+02",
|
|
"iso": "2016-09-04T19:52:29+02:00"
|
|
],
|
|
"2016-05-09T14:09:55+02:00": [
|
|
|
|
"dotnet": "/Date(1462795795000+0200)/",
|
|
"rss": "Mon, 9 May 2016 14:09:55 +0200",
|
|
"rss_alt": "9 May 2016 14:09:55 +0200",
|
|
"sql": "2016-05-09T14:09:55.000+02",
|
|
"iso": "2016-05-09T14:09:55+02:00"
|
|
],
|
|
"2016-05-11T02:58:47+02:00": [
|
|
|
|
"dotnet": "/Date(1462928327000+0200)/",
|
|
"rss": "Wed, 11 May 2016 02:58:47 +0200",
|
|
"rss_alt": "11 May 2016 02:58:47 +0200",
|
|
"sql": "2016-05-11T02:58:47.000+02",
|
|
"iso": "2016-05-11T02:58:47+02:00"
|
|
],
|
|
"2017-04-08T01:49:29+02:00": [
|
|
|
|
"dotnet": "/Date(1491608969000+0200)/",
|
|
"rss": "Sat, 8 Apr 2017 01:49:29 +0200",
|
|
"rss_alt": "8 Apr 2017 01:49:29 +0200",
|
|
"sql": "2017-04-08T01:49:29.000+02",
|
|
"iso": "2017-04-08T01:49:29+02:00"
|
|
],
|
|
"2017-03-14T04:06:47+01:00": [
|
|
|
|
"dotnet": "/Date(1489460807000+0100)/",
|
|
"rss": "Tue, 14 Mar 2017 04:06:47 +0100",
|
|
"rss_alt": "14 Mar 2017 04:06:47 +0100",
|
|
"sql": "2017-03-14T04:06:47.000+01",
|
|
"iso": "2017-03-14T04:06:47+01:00"
|
|
],
|
|
"2016-05-31T14:31:50+02:00": [
|
|
|
|
"dotnet": "/Date(1464697910000+0200)/",
|
|
"rss": "Tue, 31 May 2016 14:31:50 +0200",
|
|
"rss_alt": "31 May 2016 14:31:50 +0200",
|
|
"sql": "2016-05-31T14:31:50.000+02",
|
|
"iso": "2016-05-31T14:31:50+02:00"
|
|
],
|
|
"2015-09-22T08:28:16+02:00": [
|
|
|
|
"dotnet": "/Date(1442903296000+0200)/",
|
|
"rss": "Tue, 22 Sep 2015 08:28:16 +0200",
|
|
"rss_alt": "22 Sep 2015 08:28:16 +0200",
|
|
"sql": "2015-09-22T08:28:16.000+02",
|
|
"iso": "2015-09-22T08:28:16+02:00"
|
|
],
|
|
"2016-08-11T06:53:56+02:00": [
|
|
|
|
"dotnet": "/Date(1470891236000+0200)/",
|
|
"rss": "Thu, 11 Aug 2016 06:53:56 +0200",
|
|
"rss_alt": "11 Aug 2016 06:53:56 +0200",
|
|
"sql": "2016-08-11T06:53:56.000+02",
|
|
"iso": "2016-08-11T06:53:56+02:00"
|
|
],
|
|
"2018-03-27T19:49:32+02:00": [
|
|
|
|
"dotnet": "/Date(1522172972000+0200)/",
|
|
"rss": "Tue, 27 Mar 2018 19:49:32 +0200",
|
|
"rss_alt": "27 Mar 2018 19:49:32 +0200",
|
|
"sql": "2018-03-27T19:49:32.000+02",
|
|
"iso": "2018-03-27T19:49:32+02:00"
|
|
],
|
|
"2017-03-04T21:04:51+01:00": [
|
|
|
|
"dotnet": "/Date(1488657891000+0100)/",
|
|
"rss": "Sat, 4 Mar 2017 21:04:51 +0100",
|
|
"rss_alt": "4 Mar 2017 21:04:51 +0100",
|
|
"sql": "2017-03-04T21:04:51.000+01",
|
|
"iso": "2017-03-04T21:04:51+01:00"
|
|
],
|
|
"2016-09-19T10:22:17+02:00": [
|
|
|
|
"dotnet": "/Date(1474273337000+0200)/",
|
|
"rss": "Mon, 19 Sep 2016 10:22:17 +0200",
|
|
"rss_alt": "19 Sep 2016 10:22:17 +0200",
|
|
"sql": "2016-09-19T10:22:17.000+02",
|
|
"iso": "2016-09-19T10:22:17+02:00"
|
|
],
|
|
"2016-01-09T08:24:32+01:00": [
|
|
|
|
"dotnet": "/Date(1452324272000+0100)/",
|
|
"rss": "Sat, 9 Jan 2016 08:24:32 +0100",
|
|
"rss_alt": "9 Jan 2016 08:24:32 +0100",
|
|
"sql": "2016-01-09T08:24:32.000+01",
|
|
"iso": "2016-01-09T08:24:32+01:00"
|
|
],
|
|
"2018-05-16T02:33:15+02:00": [
|
|
|
|
"dotnet": "/Date(1526430795000+0200)/",
|
|
"rss": "Wed, 16 May 2018 02:33:15 +0200",
|
|
"rss_alt": "16 May 2018 02:33:15 +0200",
|
|
"sql": "2018-05-16T02:33:15.000+02",
|
|
"iso": "2018-05-16T02:33:15+02:00"
|
|
],
|
|
"2016-11-09T14:42:29+01:00": [
|
|
|
|
"dotnet": "/Date(1478698949000+0100)/",
|
|
"rss": "Wed, 9 Nov 2016 14:42:29 +0100",
|
|
"rss_alt": "9 Nov 2016 14:42:29 +0100",
|
|
"sql": "2016-11-09T14:42:29.000+01",
|
|
"iso": "2016-11-09T14:42:29+01:00"
|
|
],
|
|
"2017-09-18T05:07:13+02:00": [
|
|
|
|
"dotnet": "/Date(1505704033000+0200)/",
|
|
"rss": "Mon, 18 Sep 2017 05:07:13 +0200",
|
|
"rss_alt": "18 Sep 2017 05:07:13 +0200",
|
|
"sql": "2017-09-18T05:07:13.000+02",
|
|
"iso": "2017-09-18T05:07:13+02:00"
|
|
],
|
|
"2016-11-08T19:03:38+01:00": [
|
|
|
|
"dotnet": "/Date(1478628218000+0100)/",
|
|
"rss": "Tue, 8 Nov 2016 19:03:38 +0100",
|
|
"rss_alt": "8 Nov 2016 19:03:38 +0100",
|
|
"sql": "2016-11-08T19:03:38.000+01",
|
|
"iso": "2016-11-08T19:03:38+01:00"
|
|
],
|
|
"2017-08-25T04:33:32+02:00": [
|
|
|
|
"dotnet": "/Date(1503628412000+0200)/",
|
|
"rss": "Fri, 25 Aug 2017 04:33:32 +0200",
|
|
"rss_alt": "25 Aug 2017 04:33:32 +0200",
|
|
"sql": "2017-08-25T04:33:32.000+02",
|
|
"iso": "2017-08-25T04:33:32+02:00"
|
|
],
|
|
"2016-06-07T15:10:47+02:00": [
|
|
|
|
"dotnet": "/Date(1465305047000+0200)/",
|
|
"rss": "Tue, 7 Jun 2016 15:10:47 +0200",
|
|
"rss_alt": "7 Jun 2016 15:10:47 +0200",
|
|
"sql": "2016-06-07T15:10:47.000+02",
|
|
"iso": "2016-06-07T15:10:47+02:00"
|
|
],
|
|
"2016-12-02T14:54:10+01:00": [
|
|
|
|
"dotnet": "/Date(1480686850000+0100)/",
|
|
"rss": "Fri, 2 Dec 2016 14:54:10 +0100",
|
|
"rss_alt": "2 Dec 2016 14:54:10 +0100",
|
|
"sql": "2016-12-02T14:54:10.000+01",
|
|
"iso": "2016-12-02T14:54:10+01:00"
|
|
],
|
|
"2016-02-11T11:48:21+01:00": [
|
|
|
|
"dotnet": "/Date(1455187701000+0100)/",
|
|
"rss": "Thu, 11 Feb 2016 11:48:21 +0100",
|
|
"rss_alt": "11 Feb 2016 11:48:21 +0100",
|
|
"sql": "2016-02-11T11:48:21.000+01",
|
|
"iso": "2016-02-11T11:48:21+01:00"
|
|
],
|
|
"2018-01-23T17:44:12+01:00": [
|
|
|
|
"dotnet": "/Date(1516725852000+0100)/",
|
|
"rss": "Tue, 23 Jan 2018 17:44:12 +0100",
|
|
"rss_alt": "23 Jan 2018 17:44:12 +0100",
|
|
"sql": "2018-01-23T17:44:12.000+01",
|
|
"iso": "2018-01-23T17:44:12+01:00"
|
|
],
|
|
"2016-05-09T22:11:28+02:00": [
|
|
|
|
"dotnet": "/Date(1462824688000+0200)/",
|
|
"rss": "Mon, 9 May 2016 22:11:28 +0200",
|
|
"rss_alt": "9 May 2016 22:11:28 +0200",
|
|
"sql": "2016-05-09T22:11:28.000+02",
|
|
"iso": "2016-05-09T22:11:28+02:00"
|
|
],
|
|
"2015-06-27T04:15:55+02:00": [
|
|
|
|
"dotnet": "/Date(1435371355000+0200)/",
|
|
"rss": "Sat, 27 Jun 2015 04:15:55 +0200",
|
|
"rss_alt": "27 Jun 2015 04:15:55 +0200",
|
|
"sql": "2015-06-27T04:15:55.000+02",
|
|
"iso": "2015-06-27T04:15:55+02:00"
|
|
],
|
|
"2017-08-05T16:04:03+02:00": [
|
|
|
|
"dotnet": "/Date(1501941843000+0200)/",
|
|
"rss": "Sat, 5 Aug 2017 16:04:03 +0200",
|
|
"rss_alt": "5 Aug 2017 16:04:03 +0200",
|
|
"sql": "2017-08-05T16:04:03.000+02",
|
|
"iso": "2017-08-05T16:04:03+02:00"
|
|
],
|
|
"2015-11-19T22:20:40+01:00": [
|
|
|
|
"dotnet": "/Date(1447968040000+0100)/",
|
|
"rss": "Thu, 19 Nov 2015 22:20:40 +0100",
|
|
"rss_alt": "19 Nov 2015 22:20:40 +0100",
|
|
"sql": "2015-11-19T22:20:40.000+01",
|
|
"iso": "2015-11-19T22:20:40+01:00"
|
|
],
|
|
"2017-06-20T14:49:19+02:00": [
|
|
|
|
"dotnet": "/Date(1497962959000+0200)/",
|
|
"rss": "Tue, 20 Jun 2017 14:49:19 +0200",
|
|
"rss_alt": "20 Jun 2017 14:49:19 +0200",
|
|
"sql": "2017-06-20T14:49:19.000+02",
|
|
"iso": "2017-06-20T14:49:19+02:00"
|
|
]
|
|
]
|
|
}
|
|
|
|
/*public func testGenerateSomeRandomDates() {
|
|
var total = ""
|
|
let upperBound = DateInRegion()
|
|
let lowerBound = (upperBound - 3.years)
|
|
let randomDates = DateInRegion.randomDates(count: 40, between: lowerBound, and: upperBound)
|
|
randomDates.forEach {
|
|
let adjustedDateNoMS = $0.toISO().toISODate()!
|
|
total += "\"\($0.toISO())\" : [\n\t"
|
|
total += "\n\t" + "\"dotnet\": \"\(adjustedDateNoMS.toDotNET())\","
|
|
total += "\n\t" + "\"rss\": \"\(adjustedDateNoMS.toRSS(alt: false))\","
|
|
total += "\n\t" + "\"rss_alt\": \"\(adjustedDateNoMS.toRSS(alt: true))\","
|
|
total += "\n\t" + "\"sql\": \"\(adjustedDateNoMS.toSQL())\","
|
|
total += "\n\t" + "\"iso\": \"\(adjustedDateNoMS.toISO())\""
|
|
total += "\n],\n"
|
|
}
|
|
print("\(total)")
|
|
}*/
|
|
|
|
public func testDotNETFormatter() {
|
|
SwiftDate.defaultRegion = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.english)
|
|
datesList().forEach {
|
|
XCTTestFormatterParser(dateStr: $0.key, expected: $0.value["dotnet"]!, type: "dotnet", region: SwiftDate.defaultRegion)
|
|
}
|
|
}
|
|
|
|
public func testRSSFormatter() {
|
|
SwiftDate.defaultRegion = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.english)
|
|
datesList().forEach {
|
|
XCTTestFormatterParser(dateStr: $0.key, expected: $0.value["rss"]!, type: "rss", region: SwiftDate.defaultRegion)
|
|
}
|
|
}
|
|
|
|
public func testRSSAltFormatter() {
|
|
SwiftDate.defaultRegion = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.english)
|
|
datesList().forEach {
|
|
XCTTestFormatterParser(dateStr: $0.key, expected: $0.value["rss_alt"]!, type: "rss_alt", region: SwiftDate.defaultRegion)
|
|
}
|
|
}
|
|
|
|
public func testSQLFormatter() {
|
|
SwiftDate.defaultRegion = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.english)
|
|
datesList().forEach {
|
|
XCTTestFormatterParser(dateStr: $0.key, expected: $0.value["sql"]!, type: "sql", region: SwiftDate.defaultRegion)
|
|
}
|
|
}
|
|
|
|
public func testISOFormatter() {
|
|
SwiftDate.defaultRegion = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.english)
|
|
datesList().forEach {
|
|
XCTTestFormatterParser(dateStr: $0.key, expected: $0.value["iso"]!, type: "iso", region: SwiftDate.defaultRegion)
|
|
}
|
|
}
|
|
|
|
func XCTTestFormatterParser(dateStr: String, expected: String, type: String, region: Region = SwiftDate.defaultRegion) {
|
|
guard let srcDate = dateStr.toDate("yyyy-MM-dd'T'HH:mm:ssZZZZZ", region: SwiftDate.defaultRegion) else {
|
|
XCTFail("Failed to correctly parse date: '\(dateStr)'")
|
|
return
|
|
}
|
|
|
|
let dateAsStr: String = dateToString(date: srcDate, format: type)
|
|
XCTAssert( (dateAsStr == expected),
|
|
"Failed to convert date '\(srcDate.description)' to \(type) format. Expected '\(expected)', got '\(dateAsStr)'")
|
|
|
|
guard let decodedSrcDate = stringToDate(string: dateAsStr, format: type, region: region) else {
|
|
XCTFail("Failed to convert date string to date of type \(type): \(dateAsStr)")
|
|
return
|
|
}
|
|
XCTAssert( (srcDate == decodedSrcDate),
|
|
"Failed to validate formatter. Got '\(decodedSrcDate)' expecting '\(srcDate)'")
|
|
}
|
|
|
|
func dateToString(date srcDate: DateInRegion, format: String) -> String {
|
|
switch format {
|
|
case "dotnet": return srcDate.toDotNET()
|
|
case "rss": return srcDate.toRSS(alt: false)
|
|
case "rss_alt": return srcDate.toRSS(alt: true)
|
|
case "sql": return srcDate.toSQL()
|
|
case "iso": return srcDate.toISO()
|
|
default:
|
|
XCTFail("Unsupported type: \(format)")
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func stringToDate(string: String, format: String, region: Region) -> DateInRegion? {
|
|
switch format {
|
|
case "dotnet": return string.toDotNETDate(region: region)
|
|
case "rss": return string.toRSSDate(alt: false, region: region)
|
|
case "rss_alt": return string.toRSSDate(alt: true, region: region)
|
|
case "sql": return string.toSQLDate(region: region)
|
|
case "iso": return string.toISODate(nil, region: region)
|
|
default:
|
|
XCTFail("Unsupported type: \(format)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func testTZInISOParser() {
|
|
let gmtTimezone = "2017-08-05T16:04:03".toISODate(region: Region.ISO)! // force timezone
|
|
let timezoneInDate = "2017-08-05T16:04:03+02:00".toISODate()! // parse from iso
|
|
XCTAssert(gmtTimezone.region.timeZone.secondsFromGMT() == 0, "ISO Date does not contains timezone (is gmt)")
|
|
XCTAssert(timezoneInDate.region.timeZone.secondsFromGMT() == 7200, "ISO Date does not contains timezone (is gmt)")
|
|
}
|
|
|
|
func testRSSAltLocale() {
|
|
let regionAny = Region(calendar: Calendars.buddhist, zone: Zones.indianMayotte, locale: Locales.italian)
|
|
// region must not use passed locale to perform parsing but only locale as final output
|
|
let date1 = "Tue, 20 Jun 2017 14:49:19 +0200".toRSSDate(alt: false, region: regionAny)
|
|
let date2 = "20 Jun 2017 14:49:19 +0200".toRSSDate(alt: true, region: regionAny)
|
|
XCTAssertNotNil(date1, "Wrong RSS Date region")
|
|
XCTAssertNotNil(date2, "Wrong RSS Alt Date region")
|
|
}
|
|
|
|
func testTimeInterval_Clock() {
|
|
let value = (2.hours + 5.minutes).timeInterval.toClock()
|
|
XCTAssert(value == "02:05:00", "Failed to format clock")
|
|
#if os(Linux)
|
|
let zeroBehavior = DateComponentsFormatter.ZeroFormattingBehavior(rawValue: 14)
|
|
let value2 = (4.minutes + 50.minutes).timeInterval.toClock(zero: zeroBehavior)
|
|
XCTAssert(value2 == "54:00", "Failed to format clock")
|
|
#else
|
|
let value2 = (4.minutes + 50.minutes).timeInterval.toClock(zero: DateComponentsFormatter.ZeroFormattingBehavior.dropAll)
|
|
XCTAssert(value2 == "54", "Failed to format clock")
|
|
#endif
|
|
}
|
|
|
|
func testFormatterCustom() {
|
|
let rome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
|
|
let date = DateInRegion(year: 2015, month: 1, day: 15, hour: 20, minute: 00, second: 5, nanosecond: 0, region: rome)
|
|
let fixedFormat = date.toFormat("MMM dd yyyy", locale: Locales.english)
|
|
let regionFormat = date.toFormat("MMM dd yyyy")
|
|
XCTAssert( fixedFormat == "Jan 15 2015", "Failed to format with fixed locale")
|
|
XCTAssert( regionFormat == "gen 15 2015", "Failed to format with standard locale")
|
|
}
|
|
|
|
func testTimeInterval_FormatterUnits() {
|
|
// for TimeInterval
|
|
let values = (36.hours + 2.days + 1.weeks).timeInterval.toUnits([.day, .hour])
|
|
XCTAssert(values[.hour] == 12 && values[.day] == 10, "Failed to extract day components")
|
|
|
|
let singleValue = (1.days).timeInterval.toUnit(.minute)
|
|
XCTAssert(singleValue == 1440, "Failed to extract single date component")
|
|
}
|
|
|
|
func testTimeInterval_Formatter() {
|
|
let value1 = (2.hours + 5.minutes + 32.seconds).timeInterval.toString(options: {
|
|
$0.unitsStyle = .full
|
|
$0.collapsesLargestUnit = false
|
|
$0.allowsFractionalUnits = true
|
|
$0.locale = Locales.english
|
|
})
|
|
let value2 = (5.hours + 2.days).timeInterval.toString(options: {
|
|
$0.unitsStyle = .abbreviated
|
|
$0.locale = Locales.english
|
|
})
|
|
XCTAssert(value1 == "2 hours, 5 minutes, 32 seconds", "Failed to format interval to string")
|
|
XCTAssert(value2 == "2d 5h", "Failed to format interval to string")
|
|
}
|
|
|
|
func testColloquialFormatter() {
|
|
let ago5Mins = DateInRegion() - 5.minutes
|
|
let r1 = ago5Mins.toRelative(style: RelativeFormatter.defaultStyle(), locale: Locales.italian)
|
|
let r2 = ago5Mins.toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.italian)
|
|
XCTAssert(r1 == "5 minuti fa", "Failed to use colloquial formatter")
|
|
XCTAssert(r2 == "5 min fa", "Failed to use colloquial formatter")
|
|
|
|
let justNow = DateInRegion() - 10.seconds
|
|
let r3 = justNow.toRelative(style: RelativeFormatter.defaultStyle(), locale: Locales.italian)
|
|
XCTAssert(r3 == "ora", "Failed to use colloquial formatter")
|
|
|
|
let justNow2 = DateInRegion() - 2.hours
|
|
let r4 = justNow2.toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.italian)
|
|
XCTAssert(r4 == "2h fa", "Failed to use colloquial formatter")
|
|
|
|
let justNow3 = DateInRegion() - 1.minutes
|
|
let r5 = justNow3.toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.english)
|
|
XCTAssert(r5 == "1 min. ago", "Failed to use colloquial formatter")
|
|
|
|
let justNow4 = DateInRegion() - 51.seconds
|
|
let r6 = justNow4.toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.english)
|
|
XCTAssert(r6 == "1 min. ago", "Failed to use colloquial formatter")
|
|
}
|
|
|
|
func testISOParser() {
|
|
|
|
func testISO(_ src: String, _ exp: String) {
|
|
let output = src.toISODate()?.toISO()
|
|
XCTAssert(output == exp, "Failed to parse ISO '\(src)'")
|
|
}
|
|
|
|
testISO("20060506", "2006-05-06T00:00:00Z") // YYYYMMDD
|
|
testISO("2001-12-14", "2001-12-14T00:00:00Z") // YYYY-MM-DD
|
|
testISO("2001-06", "2001-06-01T00:00:00Z") // YYYY-MM
|
|
testISO("2015", "2015-01-01T00:00:00Z") // YYYY
|
|
//testISO("15", "1518-01-01T00:00:00Z") // YY
|
|
|
|
// Implied century: YY is 00-99
|
|
testISO("150603", "2015-06-03T00:00:00Z") // YYMMDD
|
|
testISO("161201", "2016-12-01T00:00:00Z") // YY-MM-DD
|
|
|
|
// Implied year
|
|
testISO("--1215", "\(Date().year)-12-15T00:00:00Z") // --MMDD
|
|
testISO("--12-15", "\(Date().year)-12-15T00:00:00Z") // --MM-DD
|
|
testISO("--12", "\(Date().year)-12-01T00:00:00Z") // --MM
|
|
|
|
// Implied year and month
|
|
testISO("---15", "\(Date().year)-\(String(format: "%02d", Date().month))-15T00:00:00Z") // ---DD
|
|
|
|
// Ordinal dates: DDD is the number of the day in the year (1-366)
|
|
testISO("2015010", "2015-01-10T00:00:00Z") // YYYYDDD (DDD is the number of the day of the year)
|
|
testISO("2015032", "2015-02-01T00:00:00Z") // YYYY-DDD
|
|
testISO("15-032", "2015-02-01T00:00:00Z") // YY-DDD
|
|
testISO("15032", "2015-02-01T00:00:00Z") // YYDDD
|
|
testISO("-032", "\(Date().year)-02-01T00:00:00Z") // -DDD
|
|
|
|
// Week-based dates: ww is the number of the week, and d is the number (1-7) of the day in the week
|
|
testISO("2018W012", "2018-01-02T00:00:00Z") // yyyyWwwd
|
|
testISO("2018-W01-2", "2018-01-02T00:00:00Z") // yyyy-Www-d
|
|
testISO("2018-W01", "2017-12-31T00:00:00Z") // yyyyWww
|
|
testISO("2018-W01", "2017-12-31T00:00:00Z") // yyyy-Www
|
|
testISO("18-W01", "2017-12-31T00:00:00Z") // yyWwwd
|
|
testISO("18-W01-2", "2018-01-02T00:00:00Z") // yy-Www-d
|
|
testISO("18W01", "2017-12-31T00:00:00Z") // yyWww
|
|
testISO("18-W01", "2017-12-31T00:00:00Z") // yy-Www
|
|
|
|
// Date
|
|
testISO("1970-01-01", "1970-01-01T00:00:00Z")
|
|
testISO("2001", "2001-01-01T00:00:00Z")
|
|
testISO("2001-02-03", "2001-02-03T00:00:00Z")
|
|
testISO("2001-02-03T04:05", "2001-02-03T04:05:00Z")
|
|
testISO("2001-02-03T04:05:06.007-06:30", "2001-02-03T04:05:06-06:30")
|
|
}
|
|
}
|