Skip to content

Commit 9797923

Browse files
authored
Update date formatter (#40)
- Replace PreciseDateFormatter implementation with PreciseISO8601DateFormatter - Increase minimum target versions - Increase Swift version - Format code
1 parent f1240a5 commit 9797923

32 files changed

Lines changed: 801 additions & 613 deletions

.github/workflows/ci.yml

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
name: Build
1+
name: CI
22

3-
on:
4-
push:
3+
on: push
54

65
jobs:
7-
build:
8-
name: Build and Test
9-
runs-on: macos-latest
10-
6+
test:
7+
runs-on: macos-12
8+
119
steps:
12-
- uses: actions/checkout@v2
13-
- name: Build
14-
run: swift build -v
15-
- name: Run tests
16-
run: swift test -v
10+
- uses: actions/checkout@v3
11+
- name: Select Xcode 14
12+
run: sudo xcode-select -s /Applications/Xcode_14.1.app
13+
- name: Test
14+
run: swift test

.swift-version

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
5.7.0
2+

.swiftformat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--funcattributes prev-line
2+
--minversion 0.47.2
3+
--maxwidth 96
4+
--typeattributes prev-line
5+
--wraparguments before-first
6+
--wrapparameters before-first
7+
--wrapcollections before-first

Package.resolved

Lines changed: 29 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,49 @@
1-
// swift-tools-version:5.3
1+
// swift-tools-version:5.7
22
import PackageDescription
33

44
let package = Package(
55
name: "SQLite",
66
platforms: [
7-
.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v5),
7+
.macOS(.v11), .iOS(.v14), .tvOS(.v14), .watchOS(.v7),
88
],
99
products: [
1010
.library(
1111
name: "SQLite",
12-
targets: ["SQLite"]),
12+
targets: ["SQLite"]
13+
),
1314
],
1415
dependencies: [
1516
.package(
16-
name: "CombineExtensions",
1717
url: "https://github.com/shareup/combine-extensions.git",
18-
from: "4.0.0"
18+
from: "5.0.0"
19+
),
20+
.package(
21+
url: "https://github.com/shareup/precise-iso-8601-date-formatter.git",
22+
from: "1.0.2"
1923
),
2024
.package(
21-
name: "Synchronized",
2225
url: "https://github.com/shareup/synchronized.git",
23-
from: "3.0.0"
26+
from: "4.0.0"
2427
),
2528
],
2629
targets: [
2730
.target(
2831
name: "SQLite",
29-
dependencies: ["Synchronized"]),
32+
dependencies: [
33+
.product(
34+
name: "PreciseISO8601DateFormatter",
35+
package: "precise-iso-8601-date-formatter"
36+
),
37+
.product(name: "Synchronized", package: "synchronized"),
38+
]
39+
),
3040
.testTarget(
3141
name: "SQLiteTests",
3242
dependencies: [
33-
"CombineExtensions",
34-
.product(name: "CombineTestExtensions", package: "CombineExtensions"),
43+
.product(name: "CombineExtensions", package: "combine-extensions"),
44+
.product(name: "CombineTestExtensions", package: "combine-extensions"),
3545
"SQLite",
36-
]),
46+
]
47+
),
3748
]
3849
)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ To use SQLite with the Swift Package Manager, add a dependency to your Package.s
1717
```swift
1818
let package = Package(
1919
dependencies: [
20-
.package(url: "https://github.com/shareup/sqlite.git", .upToNextMajor(from: "16.0.0"))
20+
.package(url: "https://github.com/shareup/sqlite.git", .upToNextMajor(from: "18.0.0"))
2121
]
2222
)
2323
```

Sources/SQLite/Hook.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ func updateHookWrapper(
1616
databaseName: UnsafePointer<Int8>?,
1717
tableName: UnsafePointer<Int8>?,
1818
rowid: sqlite3_int64
19-
) -> Void {
20-
guard let context = context else { return }
19+
) {
20+
guard let context else { return }
2121
let hook = Unmanaged<Hook>.fromOpaque(context).takeUnretainedValue()
2222
hook.update?(context, operationType, databaseName, tableName, rowid)
2323
}
2424

2525
func commitHookWrapper(context: UnsafeMutableRawPointer?) -> Int32 {
26-
guard let context = context else { return 0 }
26+
guard let context else { return 0 }
2727
let hook = Unmanaged<Hook>.fromOpaque(context).takeUnretainedValue()
2828
hook.commit?()
2929
return 0
3030
}
3131

3232
func rollbackHookWrapper(context: UnsafeMutableRawPointer?) {
33-
guard let context = context else { return }
33+
guard let context else { return }
3434
let hook = Unmanaged<Hook>.fromOpaque(context).takeUnretainedValue()
3535
hook.rollback?()
3636
}
Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,37 @@
11
import Foundation
2+
import PreciseISO8601DateFormatter
23

3-
// `ISO8601DateFormatter` does not maintain nanosecond precision, which makes it
4+
// `ISO8601DateFormatter` does not maintain microsecond precision, which makes it
45
// nearly impossible to equate encodable objects that include `Date` properties.
5-
// `DateFormatter` maintains nanosecond precision by storing the exact
6-
// bit pattern of `Date.timeIntervalSinceReferenceDate`, which is the type's
7-
// underlying primitive. https://developer.apple.com/documentation/foundation/nsdate
8-
public struct PreciseDateFormatter {
6+
// `DateFormatter` maintains microsecond precision.
7+
public enum PreciseDateFormatter {
98
public static func string(from date: Date) -> String {
10-
let bitPattern = date.timeIntervalSinceReferenceDate.bitPattern
11-
return String(bitPattern)
9+
formatter.string(from: date)
1210
}
1311

1412
public static func date(from string: String) -> Date? {
15-
guard let bitPattern = UInt64(string) else { return nil }
16-
let double = Double(bitPattern: bitPattern)
17-
return Date(timeIntervalSinceReferenceDate: double)
13+
formatter.date(from: string)
1814
}
1915
}
2016

21-
extension KeyedDecodingContainer {
22-
public func decodePreciseDate(forKey key: K) throws -> Date {
23-
let asString = try self.decode(String.self, forKey: key)
17+
public extension KeyedDecodingContainer {
18+
func decodePreciseDate(forKey key: K) throws -> Date {
19+
let asString = try decode(String.self, forKey: key)
2420
guard let date = PreciseDateFormatter.date(from: asString) else {
2521
let context = DecodingError.Context(
26-
codingPath: self.codingPath,
22+
codingPath: codingPath,
2723
debugDescription: "Could not parse '\(asString)' into Date."
2824
)
2925
throw Swift.DecodingError.typeMismatch(Date.self, context)
3026
}
3127
return date
3228
}
3329

34-
public func decodePreciseDateIfPresent(forKey key: K) throws -> Date? {
35-
guard let asString = try self.decodeIfPresent(String.self, forKey: key) else { return nil }
30+
func decodePreciseDateIfPresent(forKey key: K) throws -> Date? {
31+
guard let asString = try decodeIfPresent(String.self, forKey: key) else { return nil }
3632
guard let date = PreciseDateFormatter.date(from: asString) else {
3733
let context = DecodingError.Context(
38-
codingPath: self.codingPath,
34+
codingPath: codingPath,
3935
debugDescription: "Could not parse '\(asString)' into Date."
4036
)
4137
throw Swift.DecodingError.typeMismatch(Date.self, context)
@@ -44,13 +40,15 @@ extension KeyedDecodingContainer {
4440
}
4541
}
4642

47-
extension KeyedEncodingContainer {
48-
public mutating func encode(preciseDate: Date, forKey key: K) throws {
49-
try self.encode(PreciseDateFormatter.string(from: preciseDate), forKey: key)
43+
public extension KeyedEncodingContainer {
44+
mutating func encode(preciseDate: Date, forKey key: K) throws {
45+
try encode(PreciseDateFormatter.string(from: preciseDate), forKey: key)
5046
}
5147

52-
public mutating func encodeIfPresent(preciseDate: Date?, forKey key: K) throws {
53-
guard let preciseDate = preciseDate else { return }
54-
try self.encodeIfPresent(PreciseDateFormatter.string(from: preciseDate), forKey: key)
48+
mutating func encodeIfPresent(preciseDate: Date?, forKey key: K) throws {
49+
guard let preciseDate else { return }
50+
try encodeIfPresent(PreciseDateFormatter.string(from: preciseDate), forKey: key)
5551
}
5652
}
53+
54+
private let formatter = PreciseISO8601DateFormatter()

0 commit comments

Comments
 (0)