Skip to content

Commit 5caf0b3

Browse files
author
Reed Es
committed
Add support for medium-length abbreviations for time #1
1 parent 5dda0d6 commit 5caf0b3

File tree

5 files changed

+158
-20
lines changed

5 files changed

+158
-20
lines changed

README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,19 @@ By default, values will show up to one fractional decimal point of the value, ro
8787

8888
### Suffixes
8989

90-
The suffix will depend on the style, of which there is currently `.short` (default) and `.full`.
91-
92-
| short | full | value |
93-
| ------ | ------------------- | ---------- |
94-
| s | second | 1 |
95-
| m | minute | 60 |
96-
| h | hour | 3,600 |
97-
| d | day | 86,400 |
98-
| y | year | d × 365.25 |
99-
| c | century | y × 100 |
100-
| ky | millennium | y × 1000 |
90+
The suffix will depend on the style, of which there is currently `.short` (default), `.medium`, and `.full`.
91+
92+
| short | medium | full | value |
93+
| ------ | ------ | ------------------- | ---------- |
94+
| s | sec | second | 1 |
95+
| m | min | minute | 60 |
96+
| h | hr | hour | 3,600 |
97+
| d | day | day | 86,400 |
98+
| y | yr | year | d × 365.25 |
99+
| c | cent | century | y × 100 |
100+
| ky | ky | millennium | y × 1000 |
101+
102+
Note that `.medium` and `.full` include plural forms.
101103

102104
## See Also
103105

Sources/TimeCompactor+Scale.swift

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ extension TimeCompactor {
4747
}
4848
}
4949

50-
var abbreviation: String {
50+
// shortest possible, with no plural form
51+
var shortAbbreviation: String {
5152
switch self {
5253
case .second:
5354
return "s"
@@ -66,7 +67,46 @@ extension TimeCompactor {
6667
}
6768
}
6869

69-
var singular: String {
70+
// usually longer than short, at most 4-5 chars, and may require plural form
71+
var mediumSingular: String {
72+
switch self {
73+
case .second:
74+
return "sec"
75+
case .minute:
76+
return "min"
77+
case .hour:
78+
return "hr"
79+
case .day:
80+
return "day"
81+
case .year:
82+
return "yr"
83+
case .century:
84+
return "cent"
85+
case .millenium:
86+
return "ky"
87+
}
88+
}
89+
90+
var mediumPlural: String {
91+
switch self {
92+
case .second:
93+
return "secs"
94+
case .minute:
95+
return "mins"
96+
case .hour:
97+
return "hrs"
98+
case .day:
99+
return "days"
100+
case .year:
101+
return "yrs"
102+
case .century:
103+
return "cents"
104+
case .millenium:
105+
return "kys"
106+
}
107+
}
108+
109+
var fullSingular: String {
70110
switch self {
71111
case .second:
72112
return "second"
@@ -85,7 +125,7 @@ extension TimeCompactor {
85125
}
86126
}
87127

88-
var plural: String {
128+
var fullPlural: String {
89129
switch self {
90130
case .second:
91131
return "seconds"

Sources/TimeCompactor+Style.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import Foundation
2020

2121
extension TimeCompactor {
2222
public enum Style {
23-
case short
24-
case full
23+
case short // s, m, h, ...
24+
case medium // sec, min, hr, ...
25+
case full // second(s), minute(s), hour(s), ...
2526
}
2627
}

Sources/TimeCompactor.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,15 @@ public class TimeCompactor: NumberFormatter {
7676

7777
switch style {
7878
case .short:
79-
return "\(prefix)\(scaleSymbol.abbreviation)"
80-
case .full:
81-
let isPlural = prefix != "1"
82-
let unit = isPlural ? scaleSymbol.plural : scaleSymbol.singular
79+
return "\(prefix)\(scaleSymbol.shortAbbreviation)"
80+
case .medium, .full:
81+
let unit: String = {
82+
if prefix != "1" {
83+
return style == .medium ? scaleSymbol.mediumPlural : scaleSymbol.fullPlural
84+
} else {
85+
return style == .medium ? scaleSymbol.mediumSingular : scaleSymbol.fullSingular
86+
}
87+
}()
8388
return "\(prefix) \(unit)"
8489
}
8590
}

Tests/TimeCompactorTests.swift

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,29 @@ class TimeCompactorTests: XCTestCase {
4747
XCTAssertEqual("-12.0s", c.string(from: -12.050))
4848
}
4949

50+
func testWholeNumberMedium() {
51+
let c = TimeCompactor(ifZero: nil, style: .medium, roundSmallToWhole: true)
52+
53+
XCTAssertEqual("59 secs", c.string(from: 59))
54+
XCTAssertEqual("59 secs", c.string(from: 59.499))
55+
XCTAssertEqual("1 min", c.string(from: 59.500))
56+
XCTAssertEqual("1 min", c.string(from: 59.899))
57+
XCTAssertEqual("1 min", c.string(from: 59.9))
58+
XCTAssertEqual("1 min", c.string(from: 60))
59+
XCTAssertEqual("1 min", c.string(from: 61))
60+
XCTAssertEqual("1 min", c.string(from: 89.499))
61+
XCTAssertEqual("1 min", c.string(from: 89.999))
62+
XCTAssertEqual("2 mins", c.string(from: 90))
63+
64+
XCTAssertEqual("1 sec", c.string(from: 1))
65+
XCTAssertEqual("1 sec", c.string(from: 1.49))
66+
XCTAssertEqual("2 secs", c.string(from: 1.50))
67+
68+
XCTAssertEqual("1 hr", c.string(from: 3600))
69+
XCTAssertEqual("1 hr", c.string(from: 5399)) // <1.5 hours
70+
XCTAssertEqual("2 hrs", c.string(from: 5400)) // 1.5 hours
71+
}
72+
5073
func testWholeNumberFull() {
5174
let c = TimeCompactor(ifZero: nil, style: .full, roundSmallToWhole: true)
5275

@@ -93,6 +116,24 @@ class TimeCompactorTests: XCTestCase {
93116
XCTAssertEqual("2h", c.string(from: 5400)) // 1.5 hours
94117
}
95118

119+
func testPluralMedium() {
120+
let c = TimeCompactor(ifZero: nil, style: .medium)
121+
122+
XCTAssertEqual("1.0 secs", c.string(from: 1))
123+
XCTAssertEqual("1.1 secs", c.string(from: 1.09))
124+
125+
XCTAssertEqual("59.0 secs", c.string(from: 59))
126+
XCTAssertEqual("59.9 secs", c.string(from: 59.94))
127+
XCTAssertEqual("1.0 mins", c.string(from: 59.95))
128+
XCTAssertEqual("1.0 mins", c.string(from: 60))
129+
XCTAssertEqual("1.0 mins", c.string(from: 61))
130+
XCTAssertEqual("1.5 mins", c.string(from: 89))
131+
132+
XCTAssertEqual("1.0 hrs", c.string(from: 3600))
133+
XCTAssertEqual("1.5 hrs", c.string(from: 5400))
134+
XCTAssertEqual("2.0 hrs", c.string(from: 7200))
135+
}
136+
96137
func testPluralFull() {
97138
let c = TimeCompactor(ifZero: nil, style: .full)
98139

@@ -167,6 +208,55 @@ class TimeCompactorTests: XCTestCase {
167208
XCTAssertEqual("3818ky", c.string(from: 120_500_000_000_000))
168209
}
169210

211+
func testMedium() {
212+
let c = TimeCompactor(ifZero: nil, style: .medium)
213+
214+
XCTAssertEqual("-3818 kys", c.string(from: -120_500_000_000_000))
215+
XCTAssertEqual("-3.8 kys", c.string(from: -120_500_000_000))
216+
XCTAssertEqual("-3.3 cents", c.string(from: -10_500_000_000))
217+
XCTAssertEqual("-3.8 yrs", c.string(from: -120_500_000))
218+
XCTAssertEqual("-1.4 days", c.string(from: -120_500))
219+
XCTAssertEqual("-3.3 hrs", c.string(from: -12050))
220+
XCTAssertEqual("-2.0 mins", c.string(from: -120.50))
221+
XCTAssertEqual("-12.0 secs", c.string(from: -12.050))
222+
223+
XCTAssertEqual("-1.5 secs", c.string(from: -1.5))
224+
XCTAssertEqual("-1.5 secs", c.string(from: -1.49))
225+
XCTAssertEqual("-1.2 secs", c.string(from: -1.250))
226+
227+
XCTAssertEqual("-0.3 secs", c.string(from: -0.251))
228+
XCTAssertEqual("-0.2 secs", c.string(from: -0.250))
229+
XCTAssertEqual("-0.1 secs", c.string(from: -0.051))
230+
XCTAssertEqual("0.0 secs", c.string(from: -0.050))
231+
XCTAssertEqual("0.0 secs", c.string(from: 0.000))
232+
XCTAssertEqual("0.0 secs", c.string(from: 0.050))
233+
XCTAssertEqual("0.1 secs", c.string(from: 0.051))
234+
XCTAssertEqual("0.2 secs", c.string(from: 0.250))
235+
XCTAssertEqual("0.3 secs", c.string(from: 0.251))
236+
XCTAssertEqual("0.5 secs", c.string(from: 0.499))
237+
XCTAssertEqual("0.5 secs", c.string(from: 0.500))
238+
239+
XCTAssertEqual("0.5 secs", c.string(from: 0.501))
240+
XCTAssertEqual("1.5 secs", c.string(from: 1.49))
241+
XCTAssertEqual("1.5 secs", c.string(from: 1.5))
242+
243+
XCTAssertEqual("12.0 secs", c.string(from: 12.050))
244+
XCTAssertEqual("12.1 secs", c.string(from: 12.051))
245+
246+
XCTAssertEqual("2.0 mins", c.string(from: 120.50))
247+
XCTAssertEqual("2.0 mins", c.string(from: 120.51))
248+
249+
XCTAssertEqual("3.3 hrs", c.string(from: 12050))
250+
251+
XCTAssertEqual("1.4 days", c.string(from: 120_500))
252+
253+
XCTAssertEqual("3.8 yrs", c.string(from: 120_500_000))
254+
255+
XCTAssertEqual("3.8 kys", c.string(from: 120_500_000_000))
256+
257+
XCTAssertEqual("3818 kys", c.string(from: 120_500_000_000_000))
258+
}
259+
170260
func testFull() {
171261
let c = TimeCompactor(ifZero: nil, style: .full)
172262

0 commit comments

Comments
 (0)