4 ms·
I agree. I really like how the `time` crate[0] in the rust world handles this[1]. with your example: > format_description!("[year]/[month]/[day]") 0: https:/
by AtroxDev 5y ago
I agree. I really like how the `time` crate[0] in the rust world handles this[1].
with your example:
> format_description!("[year]/[month]/[day]")
0: https://crates.io/crates/time https://crates.io/crates/time
1: https://time-rs.github.io/book/api/format-description.html https://time-rs.github.io/book/api/format-description.html
- ape4 5y agoThis is easier to read but not descriptive enough since there are different kinds year, month, day. Year can be 2 digits, 4 digits, regular or week year. Month can have leading zero or not, long name, short, name. Day could be Julian, leading zero or not, day of the week, etc
- steerablesafe 5y ago+1 for strongly typed and compile-time checked, but I'm still not a fan of a sub-language within a string literal. The language already has syntax to structure things, why make a separate language within strings?
- chrismorgan 5y ago> The language already has syntax to structure things I don’t think the language has anything suitable for these purposes. What did you have in mind?
- steerablesafe 5y agoI don't know about Rust. Several people responded that Java already has a builder interface for creating a format string. That is possibly more type erased than the Rust macro equivalent. In C++ I would use variadic templates, as I originally proposed in my root comment: `format(year(), '/', ...)`.
- chrismorgan 5y agoThe format_description! macro uses the same syntax as the format_description::parse method. If you want to support user-provided formatting strings (which you do), then you need such a method already, and once you’ve got that, why do the macro differently? That components have parameters makes the non-literal approach even less compelling: take this which can produce the likes of “2:34:56pm”: format_description!("[hour padding:none repr:12]:[minute]:[second][period case:lower]") For reference, that is equivalent to this: use time::format_description::{FormatItem, component::Component, modifier::{Hour, Minute, Second, Period, Padding}}; [ FormatItem::Component(Component::Hour(Hour { padding: Padding::None, is_12_hour_clock: false })), FormatItem::Literal(b":"), FormatItem::Component(Component::Minute(Minute { padding: Padding::Zero })), FormatItem::Literal(b":"), FormatItem::Component(Component::Second(Second { padding: Padding::Zero })), FormatItem::Component(Component::Period(Period { is_uppercase: false, case_sensitive: true })), ] You could easily provide a prettier DSL so that you could write something like this: use time::format_description::shorthand::{HOUR, MINUTE, SECOND, PERIOD, literal}; [ HOUR.padding_none().repr_12(), literal(":"), MINUTE, ":".into(), // even this if you wanted SECOND, PERIOD.case_lower(), ] This wouldn’t be awful in the absence of the parse method, but really, once you have that, the format_description macro is just what you want: compact, checked at compile time, and matching a runtime equivalent which can take user-provided format strings. (Now there are two or three changes I’d prefer to make to format_description’s syntax: I’d use = instead of :, the two being generally very similar but : far more regularly occurring in literal parts, so that the different = would make it scan better; and I think that escaping opening square brackets by doubling them but not requiring doubling for closing square brackets was a particularly bad idea; and I’m mildly inclined to prefer {} to []. So I might end up with "{hour padding=none repr=12}:{minute}:{second}{period case=lower}".)
- russtrotter 5y agoIn the context of the original article addressing Java 8, in the java.time.format package, there's a DateTimeFormatterBuilder that removes the sub-language element of the issue. With those builder methods, you can construct the fields in the order you want, with whatever precision, with padding, etc.