Skip to content

Commit 339d7d2

Browse files
committed
Simplify date formatters
1 parent f219042 commit 339d7d2

4 files changed

Lines changed: 58 additions & 44 deletions

File tree

NaiveDate.playground/Contents.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import NaiveDate
1111
let date = NaiveDate("2017-11-01")!
1212
Calendar.current.date(from: date)
1313

14-
NaiveDateFormatter(dateStyle: .short).string(from: date)
14+
NaiveDateFormatter(dateStyle: .medium).string(from: date)
1515

1616

1717
/*:
@@ -34,4 +34,4 @@ NaiveDateFormatter(timeStyle: .short).string(from: time)
3434
let dateTime = NaiveDateTime("2017-11-01T15:30:00")!
3535
Calendar.current.date(from: dateTime)
3636

37-
NaiveDateFormatter(dateStyle: .short, timeStyle: .short).string(from: dateTime)
37+
NaiveDateFormatter(dateStyle: .medium, timeStyle: .short).string(from: dateTime)

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ Format dates without having to worry about time zones:
4848
```swift
4949
let date = NaiveDate("2017-11-01")!
5050
NaiveDateFormatter(dateStyle: .short).string(from: date)
51-
// prints "11/1/17"
51+
// prints "Nov 1, 2017"
5252

5353
let time = NaiveTime("15:00")!
5454
NaiveDateFormatter(timeStyle: .short).string(from: time)
5555
// prints "3:00 PM"
5656

5757
let dateTime = NaiveDateTime("2017-11-01T15:30:00")!
5858
NaiveDateFormatter(dateStyle: .short, timeStyle: .short).string(from: dateTime)
59-
// prints "11/1/17, 3:30 PM"
59+
// prints "Nov 1, 2017 at 3:30 PM"
6060
```
6161

6262
### Convert

Sources/NaiveDateFormatter.swift

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,36 @@ import Foundation
99

1010
/// Formatting without time zones.
1111
public final class NaiveDateFormatter {
12-
private var formatter = DateFormatter()
13-
private let converter = NaiveDateTimeConverter()
12+
private let formatter = DateFormatter()
1413

15-
public init(locale: Locale = Locale.current, format: String) {
16-
formatter.locale = locale
17-
formatter.timeZone = converter.timeZone // important! UTC to UTC
18-
formatter.dateFormat = format
14+
public init(_ closure: (_ formatter: DateFormatter) -> Void) {
15+
closure(formatter)
16+
self.formatter.timeZone = TimeZone._utc // important! UTC to UTC
1917
}
2018

21-
public init(locale: Locale = Locale.current, dateStyle: DateFormatter.Style = .none, timeStyle: DateFormatter.Style = .none) {
22-
formatter.locale = locale
23-
formatter.timeZone = converter.timeZone // important! UTC to UTC
24-
formatter.dateStyle = dateStyle
25-
formatter.timeStyle = timeStyle
19+
public convenience init(format: String) {
20+
self.init {
21+
$0.dateFormat = format
22+
}
2623
}
2724

28-
public func string(from date: NaiveDate) -> String? {
29-
return converter.date(from: date).map { formatter.string(from: $0) }
25+
public convenience init(dateStyle: DateFormatter.Style = .none, timeStyle: DateFormatter.Style = .none) {
26+
self.init {
27+
$0.dateStyle = dateStyle
28+
$0.timeStyle = timeStyle
29+
}
3030
}
3131

32-
public func string(from time: NaiveTime) -> String? {
33-
return converter.date(from: time).map { formatter.string(from: $0) }
32+
public func string(from value: NaiveDate) -> String? {
33+
return formatter.calendar._utcDate(from: value).map { formatter.string(from: $0) }
3434
}
3535

36-
public func string(from dateTime: NaiveDateTime) -> String? {
37-
return converter.date(from: dateTime).map { formatter.string(from: $0) }
36+
public func string(from value: NaiveTime) -> String? {
37+
return formatter.calendar._utcDate(from: value).map { formatter.string(from: $0) }
38+
}
39+
40+
public func string(from value: NaiveDateTime) -> String? {
41+
return formatter.calendar._utcDate(from: value).map { formatter.string(from: $0) }
3842
}
3943
}
4044

@@ -44,48 +48,52 @@ public final class NaiveDateFormatter {
4448
/// Formatting without time zones.
4549
public final class NaiveDateRangeFormatter {
4650
private let formatter = DateIntervalFormatter()
47-
private let converter = NaiveDateTimeConverter()
4851

49-
public init(locale: Locale = Locale.current, format: String) {
50-
formatter.locale = locale
51-
formatter.timeZone = converter.timeZone // important! UTC to UTC
52-
formatter.dateTemplate = format
52+
public init(_ closure: (_ formatter: DateIntervalFormatter) -> Void) {
53+
closure(formatter)
54+
self.formatter.timeZone = TimeZone._utc // important! UTC to UTC
5355
}
5456

55-
public init(locale: Locale = Locale.current, dateStyle: DateIntervalFormatter.Style = .none, timeStyle: DateIntervalFormatter.Style = .none) {
56-
formatter.locale = locale
57-
formatter.timeZone = converter.timeZone // important! UTC to UTC
58-
formatter.dateStyle = dateStyle
59-
formatter.timeStyle = timeStyle
57+
public convenience init(format: String) {
58+
self.init {
59+
$0.dateTemplate = format
60+
}
61+
}
62+
63+
public convenience init(dateStyle: DateIntervalFormatter.Style = .none, timeStyle: DateIntervalFormatter.Style = .none) {
64+
self.init {
65+
$0.dateStyle = dateStyle
66+
$0.timeStyle = timeStyle
67+
}
6068
}
6169

6270
public func string(from start: NaiveDate, to end: NaiveDate) -> String? {
63-
return converter.dateRange(from: start, to: end).map { formatter.string(from: $0, to: $1) }
71+
return formatter.calendar._utcDateRange(from: start, to: end).map { formatter.string(from: $0, to: $1) }
6472
}
6573

6674
public func string(from start: NaiveTime, to end: NaiveTime) -> String? {
67-
return converter.dateRange(from: start, to: end).map { formatter.string(from: $0, to: $1) }
75+
return formatter.calendar._utcDateRange(from: start, to: end).map { formatter.string(from: $0, to: $1) }
6876
}
6977

7078
public func string(from start: NaiveDateTime, to end: NaiveDateTime) -> String? {
71-
return converter.dateRange(from: start, to: end).map { formatter.string(from: $0, to: $1) }
79+
return formatter.calendar._utcDateRange(from: start, to: end).map { formatter.string(from: $0, to: $1) }
7280
}
7381
}
7482

7583

7684
// MARK: - Private -
7785

78-
/// Converts `Naive*` to `Date` in UTC.
79-
private final class NaiveDateTimeConverter {
80-
private let calendar = Calendar.current
81-
let timeZone = TimeZone(secondsFromGMT: 0)!
86+
private extension TimeZone {
87+
static let _utc = TimeZone(secondsFromGMT: 0)!
88+
}
8289

83-
func date<T: _DateComponentsConvertible>(from date: T) -> Date? {
84-
return calendar._date(from: date, in: timeZone)
90+
private extension Calendar {
91+
func _utcDate<T: _DateComponentsConvertible>(from date: T) -> Date? {
92+
return self._date(from: date, in: TimeZone._utc)
8593
}
8694

87-
func dateRange<T: _DateComponentsConvertible>(from start: T, to end: T) -> (Date, Date)? {
88-
guard let start = date(from: start), let end = date(from: end) else { return nil }
95+
func _utcDateRange<T: _DateComponentsConvertible>(from start: T, to end: T) -> (Date, Date)? {
96+
guard let start = _date(from: start), let end = _date(from: end) else { return nil }
8997
return (start, end)
9098
}
9199
}

Tests/NaiveDateFormatterTest.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ import NaiveDate
88

99
class NaiveDateFormatterTest: XCTestCase {
1010
func testNaiveTimeFormatter_enUS() {
11-
let formatter = NaiveDateFormatter(locale: Locale(identifier: "en_US"), dateStyle: .none, timeStyle: .short)
11+
let formatter = NaiveDateFormatter {
12+
$0.locale = Locale(identifier: "en_US")
13+
$0.timeStyle = .short
14+
}
1215

1316
XCTAssertEqual(formatter.string(from: NaiveTime("16:10")!), "4:10 PM")
1417
XCTAssertEqual(formatter.string(from: NaiveTime("16:10:15")!), "4:10 PM")
1518
}
1619

1720
func testNaiveTimeFormatter_enGB() {
18-
let formatter = NaiveDateFormatter(locale: Locale(identifier: "en_GB"), dateStyle: .none, timeStyle: .short)
21+
let formatter = NaiveDateFormatter {
22+
$0.locale = Locale(identifier: "en_GB")
23+
$0.timeStyle = .short
24+
}
1925

2026
XCTAssertEqual(formatter.string(from: NaiveTime("16:10")!), "16:10")
2127
XCTAssertEqual(formatter.string(from: NaiveTime("16:10:15")!), "16:10")

0 commit comments

Comments
 (0)