I'm trying to get a countdown timer to work, and the way I currently do it in my watchOS 10 app is a complicated load of nonsense to get two Strings that look like "1w 1d" and "12:34:56", i.e. a String that shows components like year, week and day, and another String showing hours, minutes and seconds.
The new Text
formats seen here https://developer.apple.com/wwdc24/10144?time=645 look useful, but I can't get them to return the values I need.
If I use this:
let dateA = Date.now
let dateB = Date.advanced(by: /* value for 8 days, 12 hours, 34 minutes and 56 seconds */)
Text(dateA, format: .offset(to: dateB, allowedFields: [.year, .week, .day], maxFieldCount: 3))
I expect to see "1 week 1 day", but it always comes back as "8 days". I guess it's giving me the most concise result, but I don't want that. I'm not sure anyone would want that.
Imagine you have an event coming up in 3 days 6 hours, do you want to see "in 78 hours" or do you want "in 3 days and 6 hours"? Why must we make the user calculate the days and hours in their head when we have the ability to give them the right information?
While I'm on this, why does the resulting String have to have "in " at the beginning? I don't want that; it's not my use case, but it's forced on me.
I've raised this a hundred times with Apple. I just want to see a String that shows the difference between two dates in a format of my choosing, i.e. "1w 1d", but they never give me what I need, so I have to write extremely complex - and fragile - code that figures this stuff out, and I still can't get that to work properly.
Why can't we just have something like:
Text(from: dateA, to: dateB, format: "%yy %ww %dd") // for "1 year 2 weeks 3 days", show parts with a value > 0
Text(from: dateA, to: dateB, format: "%0yy %0ww %0dd") // for "0 years 2 weeks 3 days", show all parts regardless of value
Text(from: dateA, to: dateB, format: "%y %w %d") // for "1y 2w 3d", show parts with a value > 0
Text(from: dateA, to: dateB, format: "%0y %0w %0d") // for "0y 2w 3d", show all parts regardless of value
@darkpaw The example below should return the format you expect "1 week 1 day":
var futureDate: Date {
Calendar.current.date(byAdding: .day, value: 8, to: .now) ?? .now
}
Text(.now, format: .offset(to: futureDate, allowedFields: [.year, .week, .day], maxFieldCount: 3))