Files
UUVPN/iOS-SwiftUI-Code/GRDB.swift-6.29.3/Tests/GRDBTests/FoundationDateComponentsTests.swift
T
2025-01-28 12:28:03 +08:00

730 lines
36 KiB
Swift

import XCTest
import GRDB
class FoundationDateComponentsTests : GRDBTestCase {
override func setup(_ dbWriter: some DatabaseWriter) throws {
var migrator = DatabaseMigrator()
migrator.registerMigration("createDates") { db in
try db.execute(sql: """
CREATE TABLE dates (
ID INTEGER PRIMARY KEY,
creationDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP)
""")
}
try migrator.migrate(dbWriter)
}
func testDatabaseDateComponentsFormatHM() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .HM)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "10:11")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.HM)
XCTAssertTrue(databaseDateComponents.dateComponents.year == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.month == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.day == nil)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertTrue(databaseDateComponents.dateComponents.second == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatHMS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .HMS)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "10:11:12")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.HMS)
XCTAssertTrue(databaseDateComponents.dateComponents.year == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.month == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.day == nil)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertEqual(databaseDateComponents.dateComponents.second, dateComponents.second)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatHMSS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .HMSS)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "10:11:12.123")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.HMSS)
XCTAssertTrue(databaseDateComponents.dateComponents.year == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.month == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.day == nil)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertEqual(databaseDateComponents.dateComponents.second, dateComponents.second)
XCTAssertEqual(round(Double(databaseDateComponents.dateComponents.nanosecond!) / 1.0e6), round(Double(dateComponents.nanosecond!) / 1.0e6))
}
}
func testDatabaseDateComponentsFormatYMD() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .YMD)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "1973-09-18")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertTrue(databaseDateComponents.dateComponents.hour == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.minute == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.second == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatYMD_HM() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .YMD_HM)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "1973-09-18 10:11")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HM)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertTrue(databaseDateComponents.dateComponents.second == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatYMD_HMS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .YMD_HMS)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "1973-09-18 10:11:12")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HMS)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertEqual(databaseDateComponents.dateComponents.second, dateComponents.second)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatYMD_HMSS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .YMD_HMSS)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "1973-09-18 10:11:12.123")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HMSS)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertEqual(databaseDateComponents.dateComponents.second, dateComponents.second)
XCTAssertEqual(round(Double(databaseDateComponents.dateComponents.nanosecond!) / 1.0e6), round(Double(dateComponents.nanosecond!) / 1.0e6))
}
}
func testUndefinedDatabaseDateComponentsFormatYMD_HMSS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
let dateComponents = DateComponents()
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: [DatabaseDateComponents(dateComponents, format: .YMD_HMSS)])
let string = try String.fetchOne(db, sql: "SELECT creationDate from dates")!
XCTAssertEqual(string, "0000-01-01 00:00:00.000")
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HMSS)
XCTAssertEqual(databaseDateComponents.dateComponents.year, 0)
XCTAssertEqual(databaseDateComponents.dateComponents.month, 1)
XCTAssertEqual(databaseDateComponents.dateComponents.day, 1)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, 0)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, 0)
XCTAssertEqual(databaseDateComponents.dateComponents.second, 0)
XCTAssertEqual(databaseDateComponents.dateComponents.nanosecond, 0)
}
}
func testDatabaseDateComponentsFormatIso8601YMD_HM() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: ["1973-09-18T10:11"])
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HM)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertTrue(databaseDateComponents.dateComponents.second == nil)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatIso8601YMD_HMS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: ["1973-09-18T10:11:12"])
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HMS)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertEqual(databaseDateComponents.dateComponents.second, dateComponents.second)
XCTAssertTrue(databaseDateComponents.dateComponents.nanosecond == nil)
}
}
func testDatabaseDateComponentsFormatIso8601YMD_HMSS() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var dateComponents = DateComponents()
dateComponents.year = 1973
dateComponents.month = 9
dateComponents.day = 18
dateComponents.hour = 10
dateComponents.minute = 11
dateComponents.second = 12
dateComponents.nanosecond = 123_456_789
try db.execute(sql: "INSERT INTO dates (creationDate) VALUES (?)", arguments: ["1973-09-18T10:11:12.123"])
let databaseDateComponents = try DatabaseDateComponents.fetchOne(db, sql: "SELECT creationDate FROM dates")!
XCTAssertEqual(databaseDateComponents.format, DatabaseDateComponents.Format.YMD_HMSS)
XCTAssertEqual(databaseDateComponents.dateComponents.year, dateComponents.year)
XCTAssertEqual(databaseDateComponents.dateComponents.month, dateComponents.month)
XCTAssertEqual(databaseDateComponents.dateComponents.day, dateComponents.day)
XCTAssertEqual(databaseDateComponents.dateComponents.hour, dateComponents.hour)
XCTAssertEqual(databaseDateComponents.dateComponents.minute, dateComponents.minute)
XCTAssertEqual(databaseDateComponents.dateComponents.second, dateComponents.second)
XCTAssertEqual(round(Double(databaseDateComponents.dateComponents.nanosecond!) / 1.0e6), round(Double(dateComponents.nanosecond!) / 1.0e6))
}
}
func testFormatYMD_HMSIsLexicallyComparableToCURRENT_TIMESTAMP() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
do {
let date = Date().addingTimeInterval(-1)
let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
try db.execute(
sql: "INSERT INTO dates (id, creationDate) VALUES (?,?)",
arguments: [1, DatabaseDateComponents(dateComponents, format: .YMD_HMS)])
}
do {
try db.execute(
sql: "INSERT INTO dates (id) VALUES (?)",
arguments: [2])
}
do {
let date = Date().addingTimeInterval(1)
let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
try db.execute(
sql: "INSERT INTO dates (id, creationDate) VALUES (?,?)",
arguments: [3, DatabaseDateComponents(dateComponents, format: .YMD_HMS)])
}
let ids = try Int.fetchAll(db, sql: "SELECT id FROM dates ORDER BY creationDate")
XCTAssertEqual(ids, [1,2,3])
}
}
func testDatabaseDateComponentsParsing() {
func assertParse(_ string: String, _ dateComponent: DatabaseDateComponents, file: StaticString = #file, line: UInt = #line) {
do {
// Test DatabaseValueConvertible adoption
guard let parsed = DatabaseDateComponents.fromDatabaseValue(string.databaseValue) else {
XCTFail("Could not parse \(String(reflecting: string))", file: file, line: line)
return
}
XCTAssertEqual(parsed.format, dateComponent.format, file: file, line: line)
XCTAssertEqual(parsed.dateComponents, dateComponent.dateComponents, file: file, line: line)
}
do {
// Test StatementColumnConvertible adoption
guard let parsed = try? DatabaseQueue().inDatabase({
try DatabaseDateComponents.fetchOne($0, sql: "SELECT ?", arguments: [string])
}) else {
XCTFail("Could not parse \(String(reflecting: string))", file: file, line: line)
return
}
XCTAssertEqual(parsed.format, dateComponent.format, file: file, line: line)
XCTAssertEqual(parsed.dateComponents, dateComponent.dateComponents, file: file, line: line)
}
}
assertParse(
"0000-01-01",
DatabaseDateComponents(
DateComponents(year: 0, month: 1, day: 1, hour: nil, minute: nil, second: nil, nanosecond: nil),
format: .YMD))
assertParse(
"2018-12-31",
DatabaseDateComponents(
DateComponents(year: 2018, month: 12, day: 31, hour: nil, minute: nil, second: nil, nanosecond: nil),
format: .YMD))
assertParse(
"2018-04-21 00:00",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21 00:00Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21 00:00+00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21 00:00-00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21 00:00+01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 4500),
year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21 00:00-01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: -4500),
year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21T23:59",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .YMD_HM))
assertParse(
"2018-04-21 00:00:00",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: 0, nanosecond: nil),
format: .YMD_HMS))
assertParse(
"2018-04-21T23:59:59",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: nil),
format: .YMD_HMS))
assertParse(
"2018-04-21 00:00:00.0",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: 0, nanosecond: 0),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.9",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 900_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.9Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 900_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21 00:00:00.00",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: 0, nanosecond: 0),
format: .YMD_HMSS))
assertParse(
"2018-04-21 00:00:00.01",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: 0, nanosecond: 10_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.99",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 990_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.99Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 990_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21 00:00:00.000",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: 0, nanosecond: 0),
format: .YMD_HMSS))
assertParse(
"2018-04-21 00:00:00.001",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 0, minute: 0, second: 0, nanosecond: 1_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999+00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999-00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999+01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 4500),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999-01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: -4500),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999123",
DatabaseDateComponents(
DateComponents(year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"2018-04-21T23:59:59.999123Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: 2018, month: 04, day: 21, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .YMD_HMSS))
assertParse(
"00:00",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"23:59",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"23:59Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"23:59+00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"23:59-00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"23:59+01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 4500),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"23:59-01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: -4500),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: nil, nanosecond: nil),
format: .HM))
assertParse(
"00:00:00",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: 0, nanosecond: nil),
format: .HMS))
assertParse(
"23:59:59",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: nil),
format: .HMS))
assertParse(
"00:00:00.0",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: 0, nanosecond: 0),
format: .HMSS))
assertParse(
"23:59:59.9",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 900_000_000),
format: .HMSS))
assertParse(
"23:59:59.9Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 900_000_000),
format: .HMSS))
assertParse(
"00:00:00.00",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: 0, nanosecond: 0),
format: .HMSS))
assertParse(
"00:00:00.01",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: 0, nanosecond: 10_000_000),
format: .HMSS))
assertParse(
"23:59:59.99",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 990_000_000),
format: .HMSS))
assertParse(
"23:59:59.99Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 990_000_000),
format: .HMSS))
assertParse(
"00:00:00.000",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: 0, nanosecond: 0),
format: .HMSS))
assertParse(
"00:00:00.001",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 0, minute: 0, second: 0, nanosecond: 1_000_000),
format: .HMSS))
assertParse(
"23:59:59.999",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999+00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999-00:00",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999+01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 4500),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999-01:15",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: -4500),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999123",
DatabaseDateComponents(
DateComponents(year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
assertParse(
"23:59:59.999123Z",
DatabaseDateComponents(
DateComponents(
timeZone: TimeZone(secondsFromGMT: 0),
year: nil, month: nil, day: nil, hour: 23, minute: 59, second: 59, nanosecond: 999_000_000),
format: .HMSS))
}
func testDatabaseDateComponentsFromUnparsableString() {
let databaseDateComponents = DatabaseDateComponents.fromDatabaseValue("foo".databaseValue)
XCTAssertTrue(databaseDateComponents == nil)
}
func testJSONEncodingOfDatabaseDateComponents() throws {
// Encoding root string is not supported by all system version: use an object
struct Record: Encodable {
var date: DatabaseDateComponents
}
let record = Record(date: DatabaseDateComponents(DateComponents(year: 2018, month: 12, day: 31), format: .YMD))
let jsonData = try JSONEncoder().encode(record)
let json = String(data: jsonData, encoding: .utf8)!
XCTAssertEqual(json, """
{"date":"2018-12-31"}
""")
}
func testJSONDecodingOfDatabaseDateComponents() throws {
// Decoding root string is not supported by all system version: use an object
struct Record: Decodable {
var date: DatabaseDateComponents
}
let json = """
{"date":"2018-12-31"}
"""
let record = try JSONDecoder().decode(Record.self, from: json.data(using: .utf8)!)
XCTAssertEqual(record.date.format, .YMD)
XCTAssertEqual(record.date.dateComponents, DateComponents(year: 2018, month: 12, day: 31))
}
}