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