I would like to create not Date but simple quantities of time (i.e. durations) whose units are either days, weeks or months, then format them nicely as "1 day", "7 days", "3 weeks", "1 month", etc.
However both Duration and Measurement<UnitDuration> initializers do not accept these units.
// Type 'Duration' has no member 'days'
let duration: Duration = .days(7)
// Type 'UnitDuration' has no member 'days'
let measurement: Measurement<UnitDuration> = .init(value: 7, unit: .days)
I tried to extend UnitDuration but it does not allow to automatically format units to plural.
extension UnitDuration {
static let days = UnitDuration(
symbol: "days",
converter: UnitConverterLinear(coefficient: 60 * 60 * 24)
)
}
let measurement: Measurement<UnitDuration> = .init(value: 1, unit: .days)
measurement.formatted(.measurement(width: .wide, usage: .asProvided)) // "1 days" :(
The aim is to get something like this :
let onDay: Duration = .days(1)
let eightWeeks: Duration = .weeks(8)
oneDay.formatted() // "1 day"
eightWeeks.formatted() // "8 weeks"
As Fabio says, you could use a DateComponentsFormatter:
formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.weekOfMonth]
let components = DateComponents(weekOfMonth: 13)
if let string = formatter.string(from: components) {
print(string)
} else {
print("Unable to convert components to a String")
}
That code outputs "13 weeks" as expected.
You can also request multiple different units, e.g. weeks, days, hours, and minutes, and the DateComponentsFormatter will compose a description of the time interval using multiple units. Example:
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.second, .hour, .day, .weekOfMonth]
let components = DateComponents(day: 2, hour: 3, weekOfMonth: 54 )
if let string = formatter.string(from: components) {
print(string)
} else {
print("Unable to convert components to a String")
}
That outputs "54 weeks, 2 days, 3 hours".
DateComponentsFormatter also has a func string(from: TimeInterval) function that will take an arbitrary number of seconds and express it in terms of the units you ask for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With