Dmitry Khalanskiy [JB]
06/01/2023, 1:27 PMDateTimeFormatter
and Swift's `DateFormatter`: yyyy-MM-dd'T'HH:mm:ssxxx
. The localization functionality will be removed, and some common warts (for example, yyyy
vs YYYY
vs uuuu
) will be fixed.
• A brand new format that splits the format string into date, time, and UTC offset sections. The format above would look like ld<yyyy-mm-dd>'T'lt<hh:mm:ss>uo<+hh:mm>
, where <
and >
separate sections, and ld
, lt
, and uo
are the section names, where ld
means `l`ocal `d`ate, lt
means `l`ocal `t`ime, and uo
means `U`TC `o`ffset. This helps keep the letters in the format intuitive and not worry about MM
vs mm
.
◦ Also, a conversion function from the DateTimeFormatter
format will be provided to simplify migration.
Both approaches have their benefits. Those familiar with Java's DateTimeFormatter
syntax may not want to migrate to and learn some new format, while everyone else may be against remembering what xxx
means and what the difference is between HH
and hh
.
Please tell us which benefits are more important to you!
1️⃣ I strongly prefer to see formats like yyyy-MM-dd'T'HH:mm:ssxxx
(with the problematic parts of the API fixed) in my codebase.
2️⃣ I somewhat prefer formats like yyyy-MM-dd'T'HH:mm:ssxxx
.
3️⃣ I somewhat prefer that the strings for date formats be rethought from the ground up.
4️⃣ I strongly want the strings for date formats to be rethought from the ground up (and if I encounter a format like yyyy-MM-dd
, I'll use the conversion function).
5️⃣ What format strings? I just want a concise builder API for the formats.
We want as many votes as possible!
Please also ask your friends and colleagues. If they don't want to register in the Kotlin Slack, it's okay if you tell us their vote in the comments 🧵Dmitry Khalanskiy [JB]
06/01/2023, 1:27 PMkevin.cianfarini
06/01/2023, 1:31 PMThe localization functionality will be removed,I assume this is the case because the general lack of localization capabilities in Kotlin without the JVM? Or are there other reasons this decision was made.
kevin.cianfarini
06/01/2023, 1:34 PMJavaFormatStyle
which respects localization, right? Or are you referring to other warts.Dmitry Khalanskiy [JB]
06/01/2023, 1:37 PMMMMM dd, yyyy
would change the localization of the MMMM
field, but in some locales, this whole field order is just incorrect. The modern locale-aware APIs deal with sets of fields, like "month name, and also a day, and also a year" and let the runtime decide on the correct form for the given locale. Details: https://github.com/Kotlin/kotlinx-datetime/discussions/253kevin.cianfarini
06/01/2023, 1:37 PMkevin.cianfarini
06/01/2023, 1:37 PMDmitry Khalanskiy [JB]
06/01/2023, 1:39 PMYou mean Java'sJavaFormatStyle
FormatStyle
? Actually, we may support something like this at a later point, but the question, for now, is purely about the format strings: whether to keep them Java-like (options 1️⃣ and 2️⃣) or introduce new ones (options 3️⃣ and 4️⃣).kevin.cianfarini
06/01/2023, 1:40 PMFormatStyle
. 🤦 The place I use it in my codebase I had an import alias and forgot its true name.kevin.cianfarini
06/01/2023, 1:41 PMDesmond van der Meer
06/01/2023, 1:50 PMkenkyee
06/01/2023, 1:56 PMDmitry Khalanskiy [JB]
06/01/2023, 1:58 PMparse
and toString
functions, this is about parsing and formatting in custom formats. If a string like 2023-02-03 23:15
arrives from somewhere, ISO 8601 won't be of help!CLOVIS
06/01/2023, 1:58 PMmkrussel
06/01/2023, 2:01 PMDmitry Khalanskiy [JB]
06/01/2023, 2:02 PMlocalTime.format { hour(2).char(':').minute(2).char(':').second(2) }
or, using separate lines and naming all parameters,
localTime.format {
hour(minDigits = 2)
char(':')
minute(minDigits = 2)
char(':')
second(minDigits = 2)
}
CLOVIS
06/01/2023, 2:03 PMDmitry Khalanskiy [JB]
06/01/2023, 2:04 PMgetBestDateTimePattern
will certainly be needed. There's a separate discussion about it: https://github.com/Kotlin/kotlinx-datetime/discussions/253kevin.cianfarini
06/01/2023, 2:21 PMbut when the locale support arrives,👀
mkrussel
06/01/2023, 2:24 PMkevin.cianfarini
06/01/2023, 2:25 PMmkrussel
06/01/2023, 2:31 PMDmitry Khalanskiy [JB]
06/01/2023, 2:32 PMCLOVIS
06/01/2023, 2:35 PMDmitry Khalanskiy [JB]
06/01/2023, 2:38 PMAlso, a conversion function from theSo, no doubt Java's format will be available in some form, the question is, is it the central way to build formats that is supposed to stay in the codebase, or is it just some tiny extension function in theformat will be provided to simplify migration.DateTimeFormatter
kotlinx.datetime.format.migration
package for those who actually need it.CLOVIS
06/01/2023, 2:40 PMtylerwilson
06/01/2023, 2:44 PMkevin.cianfarini
06/01/2023, 2:44 PMDmitry Khalanskiy [JB]
06/01/2023, 2:49 PMyyyy-MM-dd'T'HH:mm:ssxxx
(and its equivalent ld<yyyy-mm-dd>'T'lt<hh:mm:ss>uo<+hh:mm>
) both take a single line of code, whereas with a DSL, you'd have trouble packing it into even two lines. And during our research, we've seen people go to great lengths to keep using string-based API: for example, using [.S][.SS][.SSS][.SSSS][.SSSSS][.SSSSSS][.SSSSSSS][.SSSSSSSS][.SSSSSSSSS]
to parse a fractional second of arbitrary length instead of using a builder with appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
. So, clearly, there's a demand for conciseness, which is why we thought that format strings would be a welcome addition!Dmitry Khalanskiy [JB]
06/01/2023, 2:50 PMno need to look up what random sequences of characters means, no conflict with existing stackoverflow posts with the java time format…Also solved by introducing a more intuitive format!
kevin.cianfarini
06/01/2023, 2:53 PMusingDo you have any idea whether this is because people don’t know about the “better” approach versus doing the stingy one?to parse a fractional second of arbitrary length[.S][.SS][.SSS][.SSSS][.SSSSS][.SSSSSS][.SSSSSSS][.SSSSSSSS][.SSSSSSSSS]
Dmitry Khalanskiy [JB]
06/01/2023, 2:56 PMkevin.cianfarini
06/01/2023, 3:07 PM@DelicateDateTimeApi
or something like that?kevin.cianfarini
06/01/2023, 3:11 PMDmitry Khalanskiy [JB]
06/01/2023, 3:12 PM@DelicateDateTimeApi
isn't viable. There's no point in trying to decide anything now.Paul Woitaschek
06/02/2023, 5:16 AMDmitry Khalanskiy [JB]
06/02/2023, 9:04 AMPaul Woitaschek
06/02/2023, 9:05 AMPaul Woitaschek
06/02/2023, 9:07 AMMikhail Gostev
06/06/2023, 8:19 AMFormatStyle
) and give programmer an ability to choose between them:
• Iso8601
— Java format
• Kotlinx
— new format by kotlinx-datetime
• ... (some other formats in the future)
• <default format style>
It will apply to multiplatform programming, because devs from different platforms could prefer different format styles.
It will also allow oldschool devs to use JavaFormat
It will also allow new wave devs to use precise format.Dmitry Khalanskiy [JB]
06/06/2023, 8:27 AMstrftime
strings, one wants Go-style strings, someone else loves Java's DateTimeFormatter
, etc. Initially, each one works on their component separately, and bam! The codebase has five different string format styles. When someone needs to look into a component written by another person, now they need to learn a new format for format strings. As a result, literally everyone is irritated. Now generalize this to Stack Overflow answers, blog posts, etc, where different people use would different format strings. This kind of community fragmentation is significantly detrimental.
Of course, we need to provide some migration functions for compatibility, but there still needs to be at most one idiomatic way to write datetime formats as strings. Possibly none at all.Mikhail Gostev
06/06/2023, 8:37 AMfor
vs while
). It doesn't mean we need to force exactly one way to do things.
I think it's a problem of library positioning. If kotlinx-datetime wants to move toward giving some de-facto standards (like kotlinx-coroutines does), so it is reasonable to choose one format style and force exact opinion.
But in date/time domain I suppose everything was already invented. So for me it seems more clever way is to structure different ways of formatting into one library and give dev possibility to choose.florent
06/06/2023, 8:38 AMRFC 3339
and java ISO 8601
so to me as long as the new format is compatible with both, I am ok with. I don't want to have to build custom parser everywhereCLOVIS
06/06/2023, 8:40 AMDmitry Khalanskiy [JB]
06/06/2023, 8:41 AMIn programming we have many different ways to solve one problem (e.g.... and as a result, everyone has to learn about both types of loops. Now imagine a programming language that introduced another ten types of loops to accommodate all preferences. That's what we would be doing if we introduced many formats as equals, except format strings are trickier than loops.vsfor
).while
Mikhail Gostev
06/06/2023, 8:53 AMfor
and while
are usable. Different cases require different approaches. For kotlinx-datetime different format styles could fit developers from different platforms.
As a developer that is not familiar with Java world (and with ISO standards) I could expect from multiplatform date/time library for-one-thing that one of popular formats I am familiar with is supported.
Personally I would prefer one format as maximum like now (for configs) and also a DSL that would allow to format dates and parse them (if I want to do things in source code).elizarov
06/06/2023, 8:54 AMCLOVIS
06/06/2023, 8:58 AMDateTimeFormatter
) be an option? This way, there is a clear default—the DSL is the only multiplatform option—while still being compatible with whatever each platform's developers expect.
Of course, the risk is libraries that start as Java-only become harder to migrate to multiplatform later on. I have no idea how complicated converting between existing formatting utilities is, but I'd be willing to assume it's not easier than reimplementing their spec.Dmitry Khalanskiy [JB]
06/06/2023, 9:05 AMWould having a DSL + conversion methods for each platform (e.g. on the
JVM, some kind of wrapper to be able to use existing instances ofYes.) be an option?DateTimeFormatter
Of course, the risk is libraries that start as Java-only become harder to migrate to multiplatform later on.Someone who uses
java.time.DateTimeFormatter
in their code probably knows that this code is not going to run on other platforms, so they are aware of the compromise.CLOVIS
06/06/2023, 9:09 AMmcpiroman
06/06/2023, 10:14 AMWould having a DSL + conversion methods for each platform (e.g. on the JVM, some kind of wrapper to be able to use existing instances ofIdeally (a converter from) platform specific formats (like from`DateTimeFormatter`) should be available on all other platforms as well - for example if one is converting their kotlin code to multiplatform, or maybe reads the formats from config or some external sources etc.) be an option?DateTimeFormatter
CLOVIS
06/06/2023, 10:18 AMmcpiroman
06/06/2023, 10:24 AMjessewilson
06/06/2023, 11:39 AMJon Bailey
06/06/2023, 11:41 AMJon Bailey
06/06/2023, 11:43 AMribesg
06/06/2023, 11:50 AMeygraber
06/06/2023, 12:33 PMDmitry Khalanskiy [JB]
06/06/2023, 12:37 PMFor example, if I see a StackOverflow answer for how to configure DateTimeFormatter to interop with some API, that format string should work with KotlinIt will, don't worry. The question is, will it be the main format, or will it work through a conversion function.
ISO 8601It defines a specific format, not a way to create custom formats, and in this discussion, we're interested in exactly the custom formats. If you can use ISO 8601, then
parse
and format
functions in kotlinx-datetime
already work as you expect.
My question may be stupid but what's the usage of offset dates?Some use cases are mentioned in https://github.com/Kotlin/kotlinx-datetime/issues/90 : some API endpoints use datetimes with an offset to encode both an
Instant
and a LocalDateTime
. For example, a timetable: we're interested in both what the local time is when a plane arrives (so we know whether the shops are closed) and the actual instant when it happens (so we know whether we'll be in time for some event).florent
06/06/2023, 3:33 PMCasey Brooks
06/06/2023, 4:06 PMflorent
06/06/2023, 4:12 PMribesg
06/06/2023, 4:12 PMCasey Brooks
06/06/2023, 4:22 PMDmitry Khalanskiy [JB]
06/06/2023, 5:22 PMOther targets probably don’t need such strong compatibility guarantees, as they’re likely not using Java-style format strings anywayBut they do. For example, it's the standard datetime parsing/formatting mechanism in Objective-C/Swift: https://developer.apple.com/documentation/foundation/nsdateformatter
DSL doesn't provide compile time safetyAre we talking about the same thing?
localTime.format { hour(); char(':'); minute() }
is an example of using a DSL, and there's certainly the type safety of not being able to use day()
when formatting times. Not sure what you mean.
Offsets need to die and I worry seeing them being this important here.I don't understand your point at all, sorry. The fact is, offsets are already widely used in the API endpoints. Regardless of whether offsets need to die (and you're probably thinking about calculations with offsets, which is a separate problem from data exchange), people need to parse and format dates using them today, it's non-negotiable. For example, in the list of commonly used Java format strings we collected (https://github.com/dkhalanskyjb/journal/blob/main/Datetime/FormattingWiki/patterns.csv), the 32nd most popular format uses an offset. As does the 41st. So, offsets really are quite important, if you have to interact with anything at all that already uses offsets today, and there are a lot of such places: https://grep.app/search?q=yyyy-MM-dd%27T%27HH%3Amm%3AssZ
but I don't get why it's in the poll for "what should be the main format".The reason is, something like
yyyy-MM-dd
is such a simple thing that it's hard to get that wrong, no matter which string format is used. The moment the format becomes important is when it stops being so trivial and you can accidentally get it wrong.
there will be a lot of folks passing Java-style strings to the format function expecting them to workWe tried our best to avoid this exact problem. The fixes we're talking about are things like interpreting
YYYY-MM-dd
as yyyy-MM-dd
, since, clearly, no one could have actually meant the first one.dewildte
06/06/2023, 8:27 PMHaving both DSL and a string format is an option. They, indeed, might better fit different use-cases.
— Roman ElizarovIs really what I want, both. Only 1 way of doing things sounds like a nice ideal. But I am not convinced reality works like that. Adaptability is generally that which endures the best.
Priya Sindkar
06/06/2023, 8:34 PMdewildte
06/06/2023, 8:34 PMCLOVIS
06/07/2023, 7:33 AMgive us a library that uses ML to slightly incorrectly parse any kind of date you can imagine into an ADT of Instant or Date or Time or DateTimeThere, fixed it for you
jessewilson
06/07/2023, 10:23 AMOCT
as if it were SimpleDateFormat’s MMM
, and 00
as if it were SimpleDateFormat’s HH
.Dmitry Khalanskiy [JB]
06/07/2023, 10:26 AMjessewilson
06/07/2023, 10:30 AMjessewilson
06/07/2023, 10:31 AMMark Lanett
06/07/2023, 4:30 PMCLOVIS
06/07/2023, 6:48 PMPeter
06/08/2023, 6:28 AMSam Stone
06/30/2023, 2:43 AMYYYY
and yyyy
is, etc.
As a dev, every time I come across a format string that I have to write or modify, I have to dig through the abstraction layers and helper functions from String.format
until I get to the javadoc with the format string spec to remind myself what something means or how to do something. Having a builder would circumvent that.Sam Stone
06/30/2023, 10:04 PMif(trafficLight.isGreen) car.drive() else car.stop()
. Assembly was an abstraction above Machine Code, but it wasn’t much better (they sure thought it was at the time). Rethinking format strings would be going from MC to Assembly - why not jump straight to Kotlin (literally)?Sam Stone
07/27/2023, 4:53 PM