// // Copyright Amazon.com Inc. or its affiliates. // All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // import Foundation import XCTest @testable import Amplify let pst = TimeZone(secondsFromGMT: -28_800)! class TemporalTests: XCTestCase { // MARK: - DateTime /// - Given: a `DateTime` string /// - When: /// - the input format is `yyyy-MM-dd'T'HH:mm'Z'` /// - Then: /// - it should be parsed correctly in a `DateTime` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testShortDateTimeParsing() { do { let datetime = try Temporal.DateTime(iso8601String: "2020-01-20T08:00:00Z") XCTAssertEqual(datetime.iso8601String, "2020-01-20T08:00:00.000Z") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-20T00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20T08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-20T00:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20T08:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-20T00:00:00-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20T08:00:00Z") XCTAssertEqual( datetime.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-20T00:00:00.000-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20T08:00:00.000Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `DateTime` string /// - When: /// - the input format is `yyyy-MM-dd'T'HH:mm:ss'Z'` /// - Then: /// - it should be parsed correctly in a `DateTime` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testMediumDateTimeParsing() { do { let datetime = try Temporal.DateTime(iso8601String: "2020-01-20T08:00:00Z") XCTAssertEqual(datetime.iso8601String, "2020-01-20T08:00:00.000Z") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-20T00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20T08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-20T00:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20T08:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-20T00:00:00-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20T08:00:00Z") XCTAssertEqual( datetime.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-20T00:00:00.000-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20T08:00:00.000Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `DateTime` string /// - When: /// - the input format is `yyyy-MM-dd'T'HH:mm:ss.SSSS` /// - Then: /// - it should be parsed correctly in a `DateTime` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testLongDateTimeParsing() { do { let datetime = try Temporal.DateTime(iso8601String: "2020-01-20T08:00:00Z") XCTAssertEqual(datetime.iso8601String, "2020-01-20T08:00:00.000Z") XCTAssertEqual( datetime.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-20T00:00") XCTAssertEqual( datetime.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20T08:00") XCTAssertEqual( datetime.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-20T00:00:00") XCTAssertEqual( datetime.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20T08:00:00") XCTAssertEqual( datetime.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-20T00:00:00-08:00") XCTAssertEqual( datetime.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20T08:00:00Z") XCTAssertEqual( datetime.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-20T00:00:00.000-08:00") XCTAssertEqual( datetime.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20T08:00:00.000Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `DateTime` string /// - When: /// - the input format is `yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ` /// - Then: /// - it should be parsed correctly in a `DateTime` instance /// - it should use the provided `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testFullDateTimeParsingOnUTC() { do { let datetime = try Temporal.DateTime(iso8601String: "2020-01-20T08:00:00.180Z") XCTAssertEqual(datetime.iso8601String, "2020-01-20T08:00:00.180Z") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-20T00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20T08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-20T00:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20T08:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-20T00:00:00-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20T08:00:00Z") XCTAssertEqual( datetime.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-20T00:00:00.180-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20T08:00:00.180Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `DateTime` string /// - When: /// - the input format is `yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ` /// - Then: /// - it should be parsed correctly in a `DateTime` instance /// - it should use the provided `pst` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testFullDateTimeParsingOnPST() { do { let datetime = try Temporal.DateTime(iso8601String: "2020-01-20T08:00:00.180-08:00") XCTAssertEqual(datetime.iso8601String, "2020-01-20T16:00:00.180Z") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-20T08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20T16:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-20T08:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20T16:00:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-20T08:00:00-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20T16:00:00Z") XCTAssertEqual( datetime.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-20T08:00:00.180-08:00") XCTAssertEqual(datetime.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20T16:00:00.180Z") } catch { XCTFail(error.localizedDescription) } } // MARK: - Date /// - Given: a `Date` string /// - When: /// - the input format is `yyyy-MM-dd` /// - Then: /// - it should be parsed correctly in a `Date` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testShortDateParsing() { do { let date = try Temporal.Date(iso8601String: "2020-01-20") XCTAssertEqual(date.iso8601String, "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-19") XCTAssertEqual(date.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20") XCTAssertEqual(date.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-19-08:00") XCTAssertEqual(date.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-19-08:00") XCTAssertEqual(date.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-19-08:00") XCTAssertEqual(date.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `Date` string /// - When: /// - the input format is `yyyy-MM-ddZZZZZ` /// - Then: /// - it should be parsed correctly in a `Date` instance /// - it should use the provided `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testFullDateParsingOnUTC() { do { let date = try Temporal.Date(iso8601String: "2020-01-20Z") print("===============") print(date) print("===============") XCTAssertEqual(date.iso8601String, "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .short, timeZone: pst), "2020-01-19") XCTAssertEqual(date.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20") XCTAssertEqual(date.iso8601FormattedString(format: .medium, timeZone: pst), "2020-01-19-08:00") XCTAssertEqual(date.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .long, timeZone: pst), "2020-01-19-08:00") XCTAssertEqual(date.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .full, timeZone: pst), "2020-01-19-08:00") XCTAssertEqual(date.iso8601FormattedString(format: .full, timeZone: .utc), "2020-01-20Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `Date` string /// - When: /// - the input format is `yyyy-MM-ddZZZZZ` /// - Then: /// - it should be parsed correctly in a `Date` instance /// - it should use the provided `pst` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testFullDateParsingOnPST() { do { let date = try Temporal.Date(iso8601String: "2020-01-20-08:00") XCTAssertEqual(date.iso8601String, "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .short, timeZone: .utc), "2020-01-20") XCTAssertEqual(date.iso8601FormattedString(format: .medium, timeZone: .utc), "2020-01-20Z") XCTAssertEqual(date.iso8601FormattedString(format: .long, timeZone: .utc), "2020-01-20Z") } catch { XCTFail(error.localizedDescription) } } // MARK: - Time /// - Given: a `Time` string /// - When: /// - the input format is `HH:mm` /// - Then: /// - it should be parsed correctly in a `Time` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testShortTimeParsing() { do { let time = try Temporal.Time(iso8601String: "08:00") XCTAssertEqual(time.iso8601String, "08:00:00.000Z") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: pst), "00:00") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: .utc), "08:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: pst), "00:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: .utc), "08:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: pst), "00:00:00.000") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: .utc), "08:00:00.000") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: pst), "00:00:00.000-08:00") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: .utc), "08:00:00.000Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `Time` string /// - When: /// - the input format is `HH:mm:ss` /// - Then: /// - it should be parsed correctly in a `Time` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testMediumTimeParsing() { do { let time = try Temporal.Time(iso8601String: "08:00:00") XCTAssertEqual(time.iso8601String, "08:00:00.000Z") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: pst), "00:00") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: .utc), "08:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: pst), "00:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: .utc), "08:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: pst), "00:00:00.000") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: .utc), "08:00:00.000") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: pst), "00:00:00.000-08:00") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: .utc), "08:00:00.000Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `Time` string /// - When: /// - the input format is `HH:mm:ss.SSSS` /// - Then: /// - it should be parsed correctly in a `Time` instance /// - it should use the `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testLongTimeParsing() { do { let time = try Temporal.Time(iso8601String: "08:00:00.180Z") XCTAssertEqual(time.iso8601String, "08:00:00.180Z") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: pst), "00:00") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: .utc), "08:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: pst), "00:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: .utc), "08:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: pst), "00:00:00.180") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: .utc), "08:00:00.180") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: pst), "00:00:00.180-08:00") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: .utc), "08:00:00.180Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `Time` string /// - When: /// - the input format is `HH:mm:ss.SSSZZZZZ` /// - Then: /// - it should be parsed correctly in a `Time` instance /// - it should use the provided `utc` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testFullTimeParsingOnUTC() { do { let time = try Temporal.Time(iso8601String: "08:00:00.180Z") XCTAssertEqual(time.iso8601String, "08:00:00.180Z") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: pst), "00:00") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: .utc), "08:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: pst), "00:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: .utc), "08:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: pst), "00:00:00.180") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: .utc), "08:00:00.180") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: pst), "00:00:00.180-08:00") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: .utc), "08:00:00.180Z") } catch { XCTFail(error.localizedDescription) } } /// - Given: a `Time` string /// - When: /// - the input format is `HH:mm:ss.SSSZZZZZ` /// - Then: /// - it should be parsed correctly in a `Time` instance /// - it should use the provided `pst` TimeZone /// - it should output the correctly formatted string for each `TemporalFormat` func testFullTimeParsingOnPST() { do { let time = try Temporal.Time(iso8601String: "08:00:00.180-08:00") XCTAssertEqual(time.iso8601String, "16:00:00.180Z") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: pst), "08:00") XCTAssertEqual(time.iso8601FormattedString(format: .short, timeZone: .utc), "16:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: pst), "08:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .medium, timeZone: .utc), "16:00:00") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: pst), "08:00:00.180") XCTAssertEqual(time.iso8601FormattedString(format: .long, timeZone: .utc), "16:00:00.180") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: pst), "08:00:00.180-08:00") XCTAssertEqual(time.iso8601FormattedString(format: .full, timeZone: .utc), "16:00:00.180Z") } catch { XCTFail(error.localizedDescription) } } }