Hacker News new | past | comments | ask | show | jobs | submit login

She raises a very valid criticism. The Java SimpleDateFormat has a similar gotcha concerning %k vs %h ('What do you mean, my program only works in the morning'?)

I don't think her solution is right, however:

  A better fix is to get people away from using format strings altogether. 
What do you propose instead?

  have one person get it right, [...]  then ban all other attempts to use the strings directly
Thats basically part of an in-house library for something simple. In my experience, contractors either flat-out refuse to use it ('reinventing the square wheel, har har har'), or don't read the docs and rewrite it using the API. Then they extract common code from their application together with some half-baked framework, declare it a new in-house library. so when the next contractor comes, he has one more reason to ignore the well thought out library. In-house libraries work fine for complex problems, but large collections of small utilities get rewritten by everyone.

No. Learn the details of your programming language, libraries and frameworks. Even their gotchas. Read blogs, listen to coworkers, learn the idioms.

As a result, you don't store this knowledge in your current corner of some random company. You store it in the ecosystem of the language. It will influence future languages, and slowly the gotchas either disappear or become an near-universal standards.

And I guess that's exactly what this blog post helped to accomplish. Thanks, Rachel ;-)




> What do you propose instead?

What if the format codes were just a bit less cryptic? Short words, for each field, optionally qualified to select unusual variants

  %{year}-%{month}-%{dayOfMonth} %{hour}-%{min}-%{sec} %{tz:name}
Year is four digits, unless you ask for %{year:2digit}. If you want the crazy week-year, that's %{year:byweek}. Where things could plausibly be textual or numeric, the default is numeric. So %{month} is the month number, and %{month:name} is the month name; %{tz} is the timezone offset, and %{tz:name} is its symbolic name (a can of worms, i know). %{dayOfMonth} and %{dayOfWeek} are both a bit verbose because neither one is more obviously %{day} (so that goes unused), but you can abbreviate them to %{dom} and %{dow}. %{hour} is 24-hour, but you can have %{hour:12h}.

> No. Learn the details of your programming language, libraries and frameworks. Even their gotchas.

Yes, but also, let's reduce gotchas in the design of our programming languages, libraries, and frameworks. It's pathetic that we're still using strftime as our default option in 2018.


Making things horribly verbose (and thus prone to typos, introducing extra complexity in implementation, etc.) is a poor excuse for actually learning how something works so you can use it effectively and efficiently. The most common cases of strftime() are highly mnemonic, so much that seeing "%G %m %d" instead of the more common and correct "%Y %m %d" should make you wonder if it was really intended.

but also, let's reduce gotchas in the design

%Y being the correct format to use most of the time is not a "gotcha". If the roles of %G and %Y were reversed I would agree.


> What do you propose instead?

Specifically predefined formats and/or format skeletons. It's absolutely necessary when you want cross-cultural datetimes anyway, because not only are the formats and words different so are potentially the separators/intercalary bits

Javascript's Intl.DatetimeFormat only supports skeletons: you specify which fields you want and in which "width" and it'll get the closest actual datetime format with those fields for the specified locale.

Python's Babel has "named" formats (literally pass "short", "medium", "long" or "full" as the format string to format_date/format_datetime and it'll use the corresponing CLDR format for the locale) and skeletons (format_skeleton & pass in the fields/width you want in LDML specification).

And iso parsing/formatting should be an OOTB primitive of the library, not something you have to hand-roll like a savage.


strftime has had this forever (my man page implies since C89), it's %c. of course, man pages being man pages, the recommendation to actually use it is neither at the top, nor the bottom, but hidden in the BUGS section.

date parsing is available in strptime. you have to write "%Y-%m-%d %T" (since for some reason only strftime supports %F), but that's not too bad. the major pain is handling locales in a thread-safe manner, which is unnecessarily painful in C.


> strftime has had this forever (my man page implies since C89), it's %c. of course

%c neither lets you specify an overall width nor lets you specify which fields you actually want. Want the shortest possible representation because you don't have much room? Too bad. Want quarters because you actually need them? Fuck you. %c is useless, it's one of the reasons why developers have to resort to hand-rolled formats.


Neither does your suggestion of predefined formats. May want to flesh that out a bit if you had something different in mind.


Skeletons give vastly more control than %c, and still retain safety. There's no comparison. And yes, pre-defined formats do give you more control than %c - you can make as many as you like.


> Neither does your suggestion of predefined formats.

That's exactly what predefined formats provide, what with not being a single specific format. I literally quoted Babel's 4 predefined formats which are only differentiated by their "width".

And skeletons very much let you specify both overall width and field selection (to an extent).


  What do you propose instead?
Java provides a set of predefined date formatters in the standard library [1] - like 'ISO_LOCAL_DATE_TIME' and 'RFC_1123_DATE_TIME'

Of course, they don't cover every possibility - if you want milliseconds, you've got to roll your own :)

[1] https://docs.oracle.com/javase/8/docs/api/java/time/format/D...


Very true. Another example is the jquey UI date picker which stores nice defaults in the i18n files.

I would classify these as storing the knowledge in the ecosystem.


toString on a java.time.instant gives it in ISO format without even needing to bother with formatter objects.


Another solution would be to have the docs explicitly warm against it.

Something like, "The ISO 8601 week-based year (see NOTES) with century as a decimal number. Warning: most people want %Y rather than %G; do not use unless you want week-based years. ..."


No interface redesign or documentation improvement will prevent all "brain-o" situations. Which is what happened to Rachel here. Nothing wrong with the document; but sometimes you stare at something completely simple (be it code and documentation) and somehow misunderstand it. Later you go back and can't figure out how you got tripped up. It's impossible to predict where this will happen to whom.

Blaming the order of the documentation is grasping at straws.

"This thing that tripped me up for an inexplicable reason wouldn't have done that if the documentation for the thing I wanted to use had appeared first in the document".


Can we please stop using pre blocks for quotations?!


I would propose that when you create a library, you think of other programmers like web designers think of end users. In addition to simplicity of the API, efficiency of the code, and proper encapsulation, you think, "How can I prevent users of my library from making mistakes?"

It's not an accusation that the author of strftime didn't have this mindset. Rather, it's to say that we should be more mindful of studies on human behaviors against programming APIs.


The author of strftime had no idea it would be diddled with some crazy ISO C bullshit that will take up nearly every letter in the alphabet. Please, let us not drag the strftime author into this; that author provided a simple, mostly clean formatting mechanism with mostly mnemonic codes: save for a few gotchas to watch out for like %m versus %M.


So your proposal is basically the status quo? Personally I don’t think the status quo has much value compared to her solution. Having a few blessed date formats and an escape hatch is a better way. (That’s how we do it where I work. There is basically a “format time for logging” function that everything uses. And it works just fine.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: