Convert LocalDate to LocalDateTime

Posted on

Question :

I have the following attributes in my Filter class:

private LocalDate periodoDe;
private LocalDate periodoAte;

However, the object on which the information is the attribute that will be filtered is LocalDateTime , so in my tests, I do not do this:

filtro.setPeriodoDe(LocalDate.of(2018, Month.SEPTEMBER, 17));
filtro.setPeriodoAte(LocalDate.of(2018, Month.SEPTEMBER, 21));

That is, I need to be prepared to receive a LocalDate but I have to convert to a LocalDateTime .


Answer :

LocalDate only has the date (day, month and year) and LocalDateTime has the date and time. To do the conversion, you need to set the time that will be used. Some examples:

LocalDate data = LocalDate.of(2018, Month.SEPTEMBER, 17);
// seta o horário para 10:30
LocalDateTime dt = data.atTime(10, 30);

// seta o horário para 10:30:45
LocalDateTime dt = data.atTime(10, 30, 45);

// seta o horário para 10:30:45.123
LocalDateTime dt = data.atTime(10, 30, 45, 123000000);

The API has nanosecond precision, meaning you can have up to 9 decimal places in a fraction of a second:

// seta o horário para 10:30:45.123456789
LocalDateTime dt = data.atTime(10, 30, 45, 123456789);

In the case of a search filter, it is common for the start date to have the time set to midnight and the end date to 23: 59: 59.999 (to be sure you will consider all day search).

So you could do:

filtro.setPeriodoDe(LocalDate.of(2018, Month.SEPTEMBER, 17).atStartOfDay());
filtro.setPeriodoAte(LocalDate.of(2018, Month.SEPTEMBER, 21).atTime(LocalTime.MAX));

atStartOfDay() you set the time to midnight. E LocalTime.MAX is a constant that is worth 23:59:59.999999999 .

Timezones and DST

Just remembering that LocalDateTime does not have timezone, so it does not take into account daylight saving effects, for example.

In this case, you would need a ZonedDateTime , and for this you would need to set a timezone too:

// seta o horário para 10:30 no timezone America/Sao_Paulo
ZonedDateTime zdt = data.atTime(10, 30).atZone(ZoneId.of("America/Sao_Paulo"));

// seta o horário para início do dia no timezone America/Sao_Paulo
ZonedDateTime zdt = data.atStartOfDay(ZoneId.of("America/Sao_Paulo"));

An example is when daylight saving time begins in Brazil: at midnight the clock is advanced to 01:00. That means that on this day, all times between 00:00 and 00:59 do not exist at this timezone. atStartOfDay(ZoneId) already checks this and sets the time to 01:00, which is the first valid time in this case.

Now to get the end of the day, it’s a bit trickier. When DST ends in Brazil, for example: at midnight the clock is delayed by one hour, back to 23:00. This means that all times between 23:00 and 23:59 there are 2 times on this day (one in daylight saving time and another in “normal” time).

So setting the time for LocalTime.MAX to ZonedDateTime will not always work. The most guaranteed way is to get the start of the next day and subtract 1 nanosecond. Thus, you have the last moment of the day, in timezone, regardless of the changes of summer time that may have.

// seta o horário para o final do dia no timezone America/Sao_Paulo
ZonedDateTime zdt = data
    // início do dia seguinte no timezone
    // menos 1 nanossegundo

The name of the timezone ( America/Sao_Paulo ) is part of the list of timezones defined by IANA . You can get the list of all available using ZoneId.getAvailableZoneIds() . You can also use JVM’s default timezone using ZoneId.systemDefault() .

Of course you would have to change your quest to use ZonedDateTime , but then it’s up to you to consider the effects of daylight saving time or not.


Leave a Reply

Your email address will not be published. Required fields are marked *