Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java LocalTime read converter and write converter problem #3991

Open
ghost opened this issue Mar 11, 2022 · 4 comments
Open

Java LocalTime read converter and write converter problem #3991

ghost opened this issue Mar 11, 2022 · 4 comments
Assignees
Labels
status: waiting-for-triage An issue we've not yet triaged

Comments

@ghost
Copy link

ghost commented Mar 11, 2022

Hello

I have saved some time series data in a field type LocalTime.

When a LocalTime type field saved into MongoDB collection, it is saved as in MongoDB data type "date"
which is in the form of ISO Date. However, the date part and the time part are the compulsory of MongoDB data type "date"
so when LocalTime is saved, rubbish date part is included. Now the write converter put the rubbish date part is creation date
of the object.

For example, when "14:21:12" LocalTime is saved, MongoDB collection data is saved by the form "2022-03-01 14:21:12".

so far, there is no problem.

But when find by LocalTime for a field,
there is a problem.
If the spring application is running on different date to the creation of the MongoDB date field which the time information saved,
the MongoDB query generated with different date to the stored MongoDB date, so finding the time part of the date can't be matched which it should be founded.

For example,
on the date 2022-03-01
document -> { editDate: 2022-03-01 14:21:12 }

on the date 2022-03-02 finding the above document,
if I find "14:21:12", finding query is generated as "{editDate: ISODate('2022-03-02 14:21:12')}",
so the document can't be founded properly

Spring Data MongoDB should create a query "{editDate: ISODate('%%%%-%%-%% 14:21:12')}".
% means one digit number 0 to 9

Thank you.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 11, 2022
@ghost
Copy link
Author

ghost commented Mar 11, 2022

I write custom LocalTime converter classes to make "find" query correctly

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.TimeZone;
import org.springframework.core.convert.converter.Converter;

public class LocalTimeWriteConverter implements Converter<LocalTime, Date> {

  @Override
  public Date convert(LocalTime localTime) {
    LocalDateTime ldt = LocalDateTime.of(1970, 1, 1,
      localTime.getHour(), localTime.getMinute(), localTime.getSecond());
    ZonedDateTime zdt = ldt.atZone(TimeZone.getDefault().toZoneId());
    return Date.from(zdt.toInstant());
  }
}
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.TimeZone;
import org.springframework.core.convert.converter.Converter;


public class LocalTimeReadConverter implements Converter<Date, LocalTime> {

  @Override
  public LocalTime convert(Date date) {
    ZonedDateTime zdt = date.toInstant().atZone(TimeZone.getDefault().toZoneId());
    return LocalTime.of(zdt.getHour(), zdt.getMinute(), zdt.getSecond());
  }
}

@christophstrobl
Copy link
Member

Have you already tried using the driver native time codec? It can be enabled via MongoConverterConfigurationAdapter.useNativeDriverJavaTimeCodecs().

If you have the time, it would be great it you could provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.

@ghost
Copy link
Author

ghost commented Mar 11, 2022

Have you already tried using the driver native time codec? It can be enabled via MongoConverterConfigurationAdapter.useNativeDriverJavaTimeCodecs().

If you have the time, it would be great it you could provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.

I have tried to use the default LocalTime converter.

The problem is LocalTime is saved with current date. which the date should be fixed like LocalDate's time.
It caused a problem when I find the date by time only.

@sxhinzvc sxhinzvc self-assigned this Aug 23, 2023
@sxhinzvc
Copy link
Contributor

Using the native java.time codecs by setting MongoConverterConfigurationAdapter.useNativeDriverJavaTimeCodecs() fixes the date to the Java epoch 1970-01-01 and thereby avoids the problem you were seeing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants