kotlinx-datetime
kotlinx-datetime copied to clipboard
set hours of LocalDateTime
let's say that we have
val nowLocalDateTime = Clock.System.now() .toLocalDateTime(TimeZone.currentSystemDefault())
I want to set the hours after getting the current LocalDateTime to 10 am . in java we used
val pickupCalendar = Calendar.getInstance().apply { add(Calendar.DATE, 2) this[Calendar.HOUR_OF_DAY] = 10 this[Calendar.MINUTE] = 0 }
See Date + time arithmetic for an explanation why this is not possible and how to work around it by using Instant for intermediate steps.
@svenjacobs thank you , they have to provide extension funs , on the instant for these use cases
Instant already provides a few functions and implements the + or - operator, for instance. See the sections Instant arithmetic and Date arithmetic. Everything should be there already. You just need to convert to Instant or LocalDate for intermediate steps.
@svenjacobs the issue is not about arithmetic operation (plus, minus), but setting to specific local value (e.g. set hours to 10AM). It cannot be done with Instant as it is not dependent on zone.
Instant was just an example 😉 It depends on the use case. I was also mentioning LocalDate. It can be done with LocalDate and LocalTime:
val nowDateTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val time = LocalTime(hour = 10, minute = 0)
val newDateTime = nowDateTime.date.atTime(time) // nowDateTime.date returns LocalDate
Yes, this is the way, though one must be wary of manipulating LocalDateTime even this way. For example, what should happen if clocks are moved from 9:30 to 10:30 that day, so the LocalDateTime with time 10:00 does not make sense in that time zone?
That said, we do consider adding such setter-like functions if we manage to make them both flexible and safe. Could you share your use case? Why do you need such code?
For Example actually change second and millisecond of an Instant is just INSANE!
// kotlinx.datetime
val localDateTime: LocalDateTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val localTime: LocalTime = localDateTime.time
val localTime2: LocalTime = LocalTime(localTime.hour, 0, 0, 0)
val newInstant: Instant = localDateTime.date.atTime(localTime2).toInstant(TimeZone.currentSystemDefault())
// java.time
val newJavaInstant: Instant = Instant.now().atZone(ZoneId.systemDefault()).withSecond(0).withNano(0).toInstant()
Why do you need that? What's your high-level goal?
in my case i just need time slots of 1 hour from current time at start of hours, like
from "2023-03-27T11:23:33Z" i need to create
2023-03-27T11:00:00Z 2023-03-27T12:00:00Z 2023-03-27T13:00:00Z 2023-03-27T14:00:00Z
i think if there is "plusHours" there should be also "withHours" or something like that
@xanscale Perhaps a function that truncates date/time to the specified unit would better fit your need?
E.g. Instant.truncateTo(DateTimeUnit, TZ)
@ilya-g I suppose that withSecond, withMinute, etc is more generic
Closing in favor of #325