Alexandru Gheorghe
11/21/2024, 2:50 PM.toInstant(TimeZone.UTC) I'm converting it to UTC. I noticed that the time is kept the same. I was expecting it to change to a time in UTC timezone. This creates a disparity between the user creating data in their timezone and expecting it to show up with the same time (when converted back from UTC into system's timezone) however this is not the case as the time is not adjusted. Am I missing something?Stylianos Gakis
11/21/2024, 2:58 PMMichael Krussel
11/21/2024, 2:59 PMLocalDateTime has no timezone, so toInstant will just create an Instant based on that time in the UTC timezone.
You probably need to convert the local time into a zoned time in the users timezone and then convert that to UTC. Or pass the user's time zone into the toInstant time.Michael Krussel
11/21/2024, 3:00 PMLocalDateTimes exist in all time zones and sometimes they may exist at multiple instants in some timezones.Casey Brooks
11/21/2024, 4:25 PMCasey Brooks
11/21/2024, 4:27 PMAlexandru Gheorghe
11/21/2024, 4:30 PMMichael Krussel
11/21/2024, 5:26 PMtoInstant to be the user's timezone. The local times have no timezone, so there can be no timezone conversion. Instant does have a timezone, so the timezone passed to toInstant will indicate how to convert.Alexandru Gheorghe
11/21/2024, 5:41 PMval pickedDateTime = LocalDateTime(
year,
month,
day,
hour,
minute
)
val utcDateFormattedTimestamp =
pickedDateTime.toInstant(TimeZone.UTC)
val utcDateTimestamp = utcDateFormattedTimestamp
.toEpochMilliseconds()
I'd have expected utcDateFormattedTimestamp to be converted to UTC (with time included). Isn't this enough?Michael Krussel
11/21/2024, 5:43 PMpickedDataTime has no timezone, so converting it to an instant with timezone UTC will create an instant whose time is the same string as pickedDateTime in the UTC timezone. If you are trying to make the time change, you need to call toInstant with the timezone you are trying to convert from.Alexandru Gheorghe
11/21/2024, 5:48 PMtoInstant on what? Please bare with me as I'm trying to get my head around kotlinx datetimeMichael Krussel
11/21/2024, 5:49 PMpackedDataTime like you are, you are just using the wrong timezone. You should be passing in the timezone that pickedDataTime is for not UTC.Michael Krussel
11/21/2024, 5:51 PMAlexandru Gheorghe
11/21/2024, 5:54 PM.toInstant(TimeZone.currentSystemDefault()) and then convert to UTC using toInstant ?Michael Krussel
11/21/2024, 5:55 PMInstant's don't have a timezone. They are just the time since the epoch. So there's no need to call toInstant again since you already have an Instant after the first call. Look at the sample code in the documentation for the function.Alexandru Gheorghe
11/21/2024, 5:57 PMMichael Krussel
11/21/2024, 5:59 PMtoInstant. pickedDateTime.toInstant(TimeZone.UTC) says convert pickedDataTime to an instant assuming the time specified there is in UTC timezone.Oliver.O
11/21/2024, 11:06 PMimport kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
fun main() {
// This datetime has no time zone, it cannot specify a point in time without interpretation.
val zoneLessDateTime = LocalDateTime(year = 2024, monthNumber = 11, dayOfMonth = 21, hour = 18, minute = 41)
// This is the timezone we choose to interpret our zoneLessDateTime.
val localTimeZone = TimeZone.currentSystemDefault()
// Combining the zoneLessDateTime with the time zone makes it an instant, an actual point in time.
val instant = zoneLessDateTime.toInstant(localTimeZone)
println("zone-less: $zoneLessDateTime")
println("instant: $instant")
println("instant in the local time zone: ${instant.toLocalDateTime(localTimeZone)} $localTimeZone")
}
Which produces the following output in my timezone:
zone-less: 2024-11-21T18:41
instant: 2024-11-21T17:41:00Z
instant in the local time zone: 2024-11-21T18:41 Europe/Berlin
The misunderstanding above is: pickedDateTime.toInstant(TimeZone.UTC) does not convert between time zones. Since your pickedDateTime never had any time zone, you were basically saying "make pickedDateTime an instant by interpreting it to be in UTC".Alexandru Gheorghe
11/22/2024, 5:47 AMtimeInTimeZoneA.toInstant(TimeZone.UTC) and have the time be correctly transitioned to represent datetime in UTC as transformed from timezone A.
There's https://github.com/Kotlin/kotlinx-datetime/discussions/237 but even this uses instantOliver.O
11/22/2024, 9:06 AMZonedDateTime, which would represent your timeInTimeZoneA. Currently, the time zone is always a separate entity, which has to be applied when converting to or from a user-readable form (LocalDateTime).Dmitry Khalanskiy [JB]
11/22/2024, 9:55 AMZonedDateTime is not provided, as most of its needs are already fulfilled by Instant. The discussion you've linked to is about the introduction of a data type for some rare special occasions.
If you're getting date and time separately and know which time zone they are in, then this is exactly what @Oliver.O’s example shows: given a LocalDateTime (the wall-clock representation that a normal person sees), you receive an Instant (the actual moment in time when something happened). If you then want to find out what a person in the UTC time zone would see, you can do this:
val localDateTimeInZoneA = LocalDate(2024, 11, 22)
.atTime(10, 56)
val instant = localDateTimeInZoneA.toInstant(
TimeZone.of("Europe/Berlin"))
val localDateTimeInUtc = instant.toLocalDateTime(
TimeZone.UTC)