https://kotlinlang.org logo
#random
Title
# random
c

Colton Idle

10/16/2023, 5:15 PM
Just need a sanity check. I need to save the last time I fetched something from the server and persist it and then display to the user, formatted. The format should end up showing them what time it was in their current time zone. Should I just grab System.currentTimeMillis() or Instant.now() or something else? Any once I have that instance it should be pretty trivial to format it using the device locale right? I feel like this is straightforward but time scares me. 😂
r

reactormonk

10/16/2023, 5:35 PM
ISO time is usually a good way to go - time is complicated.
UTC over the wire / db, parse & adjust as required. There's a ridiculous amount of things that can go wrong with milis.
e

ephemient

10/16/2023, 5:48 PM
it kind of depends on what you want to do
System.currentTimeMillis()
is not monotonic and may not always have a consistent delta to server time
there are a variety of other clocks (see java.time.Clock, android.os.SystemClock) with different properties
formatting requires platform APIs but is mostly straightforward, with the exception that on Android, the desugared java.time APIs don't have access to all the same locale data across all Android versions
👍 1
c

Colton Idle

10/16/2023, 7:27 PM
So I'm doing val date = Date(System.currentMillis()) val format = SimpleDateFormat("yyyy.MM.dd HH:mm") format.format(date) and it works. It gives me my time. I was expecting it to give me the time set to UTC. Wonder why I didn't have to give it a time zone.
e

ephemient

10/16/2023, 7:30 PM
because it defaults to SDF defaults to Calendar.getInstance() which defaults to Locale.getDefault() and TimeZone.getDefault()
🤯 1
t

Ties

10/17/2023, 7:44 AM
If dealing with timezones, I would suggest the Instant.now() and use the new time api
👍 2
r

Rob Elliot

10/17/2023, 4:39 PM
Likewise, you should use
java.time.format.DateTimeFormatter
in preference to
java.text.SimpleDateFormat
unless you have some very good reason to prefer the latter.
Also, if you habitually get hold of the current time like this:
Copy code
class MyClass(
  private val clock: Clock = Clock.systemUTC()
) {
  ...
  val now = clock.instant()
  ...
}
you will save yourself a bunch of refactoring when you need to properly test some time dependent code 😉
e

ephemient

10/17/2023, 4:56 PM
absolutely yes, on JVM and new enough Android. on multiplatform you'll have to use something like https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-time-source/ or roll your own
on old Android (which includes new Android if you're using desugaring to target old Android), you should use java.time, but be careful about formatting. https://issuetracker.google.com/issues/157926127 https://issuetracker.google.com/issues/160113376 https://issuetracker.google.com/issues/300128109 etc.
c

Colton Idle

10/18/2023, 4:19 PM
I wonder why I should use DateTimeFormatter over SDF?
r

reactormonk

10/18/2023, 4:19 PM
Because java.time is the new non-screwy Java time API
r

Rob Elliot

10/18/2023, 4:22 PM
I mean, there's stuff on this all over the internet, but quickly: •
SimpleDateFormat
works on
Date
, which is a notoriously badly designed class, whereas
DateTimeFormatter
uses
Instant
which is immutable and sane •
SimpleDateFormat
is not threadsafe, and anyone who worked for very long on the JVM more than a decade ago will have at some point found someone thinking "may as well make this format a static constant" and only found out when it failed under heavy load
c

Colton Idle

10/18/2023, 8:03 PM
Gotcha. I didn't realize that SDF was piled into that entire package that should be avoided. I thought the formatting lived outside of that. But that makes sense. thanks all for teaching!
k

Klitos Kyriacou

10/19/2023, 3:07 PM
SimpleDateFormat
is not threadsafe, and anyone who worked for very long on the JVM more than a decade ago will have at some point found someone thinking "may as well make this format a static constant" and only found out when it failed under heavy load
Yep, that was me, 10 years ago!
c

Colton Idle

10/19/2023, 4:57 PM
i wish i could just have a denylist of packages that i should never use. 😅
e

ephemient

10/19/2023, 5:03 PM
can't, the old datetime api is in
java.util.*
and
java.text.*
along with other many classes you still need
👍 1
also you might still need to interoperate with them sometimes… particularly on android, if you need to format in ways that don't work in the desugared java.time, but have workarounds in the old api or in
android.icu.*
👍 1
2 Views