Kotlinx-datetime 0.1 has been published

Today we’re excited to announce the first milestone release of the kotlinx-datetime library, version 0.1.

There is a longstanding request for the ability to work with dates in Kotlin. In Kotlin/JVM, you can rely on the java.time.* API, but there’s no such option when developing a multiplatform project.

Though several multiplatform kotlin libraries already exist in this field, we feel that such a fundamental need should be addressed by a kotlinx.* library.

kotlinx-datetime is a multiplatform library for working with dates and times in Kotlin. It supports Kotlin/JVM, Kotlin/JS, and a variety of Kotlin/Native targets.

Our vision is first to provide a minimal API that can cover the most common practical use cases, and then to extend that API to cover more.

You can learn more about what’s in the library and find instructions for setting up a dependency in your project in the README.

This release is a first step on the path to a stable library, so we are particularly looking forward to your feedback.
Feel free to submit issues to GitHub or ask questions here or in Slack (get an invite here).

28 Likes

I always wondered why “local” prefix is needed in the name of each date/time class.

I think this prefix just confuses people. Here’s an example. They make incorrect assumptions about “locality”, e.g. they think LocalDateTime is in local timezone. The funny thing is that people added “local” prefix so that programmers understand it does not contain time zone or any kind of offset.
Here are some interesting thoughts.

Look at Java LocalDateTime description. There is nothing about locality. It says about the absence of time zone and inability to represent an instant on the time-line. If we want name to represent the exact meaning of the class then why don’t we call it DateTimeWithoutTimeZoneNotInstant?

If people do not understand the true meaning of date/time class with prefixes “naive”, “local”, “civil” etc. then why are these prefixes needed? Let’s make it less verbose and save people from wrong assumptions about locality by removing “local” prefix completely.

val now: LocalDateTime = now.toLocalDateTime(TimeZone.currentSystemDefault())
val today: LocalDate = Clock.System.todayAt(TimeZone.currentSystemDefault())

->

val now: DateTime = now.toDateTime(TimeZone.currentSystemDefault())
val today: Date = Clock.System.todayAt(TimeZone.currentSystemDefault())

Alternative proposal - make it backwards:

  • rename LocalDateTime to DateTimeNoTZ / DateTimeNoZone / DateTimeWithoutZone
  • rename hypotetical ZonedDateTime (does it planned?) to DateTime
2 Likes

We may think about dropping the Local prefix. There are currently two considerations against that:

  • Both in Kotlin/JVM and Kotlin/JS, Date would conflict with the platform Date class, which is a totally different thing.
  • DateTime type name IMO would provoke people to use it more instead of an Instant, when they actually need the latter.
6 Likes

I strongly advice to keep the “Local” prefix.
While I think that you are right and the “Local” prefix is not very intuitive (or maybe even the contrary) - it is used in all(?) modern JVM date APIs.

In my opinion following already established convention is more important. Especially when targeting the JVM and Java developers.

6 Likes

I’ve been developing on a product that works with timeseries at its core for over 2 years now. From my experience so far it’s crucial to be absolutely precise and let everybody now whether you talk about a LocalDateTime or an OffsetDateTime or a ZonedDateTime (not just among programmers, also with the business).

Removing the prefix from any of these types will drop context for no reason and open room for errors and misunderstandings. Please keep this. Coming from Java to Kotlin the amount of explicitly written types has dropped massively, so it can’t be an argument for readability of code.

In my opinion people who get confused by this or want it simplified try to avoid the inherent complexity of the topic. I can totally understand that. But the complexity is there and closing your eyes to it won’t make it go away.

7 Likes

Agree with Jschneider. It took years to sort this out in the Java space, and while painful to have to learn Instant/Local/Zoned/Offset, they have purpose and a lot of things need the precision.
Kotlin just directly mapping them would be preferable to trying to rename anything and muddy the waters.
People get tripped up because they think the “Local” in LocalDateTime means their “Location”, and therefore their Timezone, but never did. Its always used the precise meaning of Local “relating to a particular space or place or serving only a small portion of something”. In this case the notion or date and/or time divorced from the underlying Timeline and Zones.

2 Likes

What is the reason that the JVM implementation creates new classes rather than aliasing those from java.time?

3 Likes

I agree with the confusing names. Naming in the Java (and other language) ecosystem is usually bad. Here are some other classes that can be renamed in my opinion:

  • Instant: It is not instantaneous; it represent a period lasting a whole nanosecond. You can execute a couple to dozens of instructions in that “instant”.
  • DateTime: What about Timestamp?

This is a silly reason: We should not improve because developers may have to adjust? I think having a Date & Time API with much clearer names can be a Kotling selling point.

1 Like

This is a great suggestion to consider, especially in a new library which does not need to worry about backwards compatibility.

What if I told you that Instant has a nanosecond precision.

Great question. Especially for JavaScript too, there is a Joda Time port, and there is also a stage 2 temporal proposal: https://github.com/tc39/proposal-temporal which is very similar to Joda.

I’m not even sure that multi-platform is really a thing. Is this a good direction for Kotlin? It’s a stretch to think people want their code to be run on multiple platforms. Perhaps the best direction is to have a Kotlin VM which combines the best of JVM and Node.

I would say that I should have known better :smiley: I will update my earlier reply.

I think this is a good idea. Java date naming is quite unclear at first glance and Kotlin is its own language so should feel free to make its own decisions.

I like the proposal for DateTimeWithoutZone. It’s not much more verbose than Java but more descriptive and does not clash with other platforms.

Also, I think right choice to keep it practical for most real use cases!

1 Like

Multiplatform is a thing, and I’m eagerly awaiting maturity. The most obvious use-case is code sharing between Android, iOS and web apps.

5 Likes

I mean, the hundred cross-platform frameworks we have nowadays would suggest otherwise.

What Kotlin offers is the best of cross-platform and Native without the negatives, I’m waiting for it to mature as well.

3 Likes

It may be a little off topic here but, am I wrong or are you cinterop-ing with C++ libs for the K/N build of kotlinx.datetime?

I did not know cinterop could build stubs for C++! This changes a lot!!

1 Like

I don’t think it interops directly with C++. The native interface uses the C ABI and a C header. Only the implementation of that header is in C++. It has always been possible to implement C headers in C++. It could just as well have been Rust or any other language, that can expose a function to C.

1 Like

Yeah but…

Making wrappers instead of typealiasing java.time types gives us some flexibility in changing the implementation later. Also we’d like to avoid conflict of our API with the member functions that would be visible on type aliases. Of course, we could use inline classes for that, but that would bring some limitations on usage on these types, which we wouldn’t like to impose for now.

2 Likes

To be honest, DateTime-related operations usually aren’t going to be in a tight loop where performance really matters, and if you are in a situation like that, usually you should probably use some clever math instead.

1 Like