kotlinx-datetime icon indicating copy to clipboard operation
kotlinx-datetime copied to clipboard

set hours of LocalDateTime

Open periva101 opened this issue 3 years ago • 6 comments

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 }

periva101 avatar Aug 21 '22 08:08 periva101

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 avatar Aug 23 '22 07:08 svenjacobs

@svenjacobs thank you , they have to provide extension funs , on the instant for these use cases

periva101 avatar Aug 24 '22 04:08 periva101

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 avatar Aug 24 '22 09:08 svenjacobs

@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.

novotnyfra avatar Sep 05 '22 10:09 novotnyfra

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

svenjacobs avatar Sep 05 '22 10:09 svenjacobs

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?

dkhalanskyjb avatar Sep 06 '22 13:09 dkhalanskyjb

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()

xanscale avatar Mar 02 '23 17:03 xanscale

Why do you need that? What's your high-level goal?

dkhalanskyjb avatar Mar 27 '23 10:03 dkhalanskyjb

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 avatar Mar 27 '23 11:03 xanscale

@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 avatar Mar 27 '23 18:03 ilya-g

@ilya-g I suppose that withSecond, withMinute, etc is more generic

xanscale avatar Mar 27 '23 19:03 xanscale

Closing in favor of #325

dkhalanskyjb avatar Dec 01 '23 13:12 dkhalanskyjb