How to pass an Instant start, end date as #RequestParam - spring

How can I pass an Instant startDate, endDate as a #RequestParam Instant startDate, Instant endDate with pattern yyyy-MM-dd so the request will looks like localhost:port/api/entity=startDate=2019-10-10?endDate=2019-10-15 any ideas how to perform it?
#RequestParam("from") #DateTimeFormat(iso = ISO.DATE) Instant startDate,
#RequestParam("to") #DateTimeFormat(iso = ISO.DATE) Instant endDate)
it does not help I'm getting Failed to convert value of type 'java.lang.String' to required type 'java.time.Instant' even tried with pattern. Also the problem is that when I've entity created at yyyy-MM-dd HH:mm:ss how can I ignore the seconds so when I pass date and hours only it will display the result.

Replace DateTimeFormat.ISO.DATE by DateTimeFormat.ISO.DATE_TIME.
The format that Instant takes : yyyy-MM-dd'T'HH:mm:ss.SSSXXX
The code below :
#GetMapping("/getlist")
public void method(#RequestParam("from") #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant startDate,
#RequestParam("to") #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant endDate)) {
// code
}
This should work.

Your date strings conform to ISO 8601 format for a date. Therefore, you should use LocalDate as the type i.e.
RequestParam("from") #DateTimeFormat(iso = ISO.DATE) LocalDate startDate,
#RequestParam("to") #DateTimeFormat(iso = ISO.DATE) LocalDate endDate)
Here is an overview of the java.time types.

If you want to have a proper DateTime format to provide the capability of handling timezone for you, I suggest you use the following pattern:
#DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX") Date myDate
It's a common ISO DATE_TIME Format and you can easily convert it to Instant afterward.
e.g. "2000-10-31T01:30:00.000-05:00"

You can use yyyy-MM-dd HH:mm:ss the date format that your want.
#RequestParam("from") #DateTimeFormat(iso = "yyyy-MM-dd HH:mm:ss")
Instant startDate,
#RequestParam("to") #DateTimeFormat(iso = "yyyy-MM-dd HH:mm:ss")
Instant endDate)

Related

How to convert LocalDateTime to OffsetDateTime?

How to convert LocalDateTime to OffsetDateTime?
private OffsetDateTime getEntryDate(Payment payment) {
return Optional.ofNullable(payment)
.map(Payment::getEntryDate)
.map(SHOULD RETURN OffsetDateTime)
.orElse(null);
}
Payment::getEntryDate will return LocalDateTime
There are many ways to convert LocalDateTime to OffsetDateTime. Some of them are listed below:
1. Using LocalDateTime#atOffset​(ZoneOffset offset):
LocalDateTime ldt = LocalDateTime.now();
ZoneOffset offset = ZoneOffset.UTC;
OffsetDateTime odt = ldt.atOffset(offset);
2. Using LocalDateTime#atZone​(ZoneId zone) => ZonedDateTime#toOffsetDateTime():
LocalDateTime ldt = LocalDateTime.now();
// Change the ZoneId as required e.g. ZoneId.of("Europe/London")
ZoneId zoneId = ZoneId.systemDefault();
OffsetDateTime odt = ldt.atZone(zoneId).toOffsetDateTime();
3. Using OffsetDateTime#of​(LocalDateTime dateTime, ZoneOffset offset):
LocalDateTime ldt = LocalDateTime.now();
ZoneOffset offset = ZoneOffset.UTC;
OffsetDateTime odt = OffsetDateTime.of(ldt, offset);
4. ZonedDateTime#of​(LocalDateTime localDateTime, ZoneId zone) => ZonedDateTime#toOffsetDateTime():
LocalDateTime ldt = LocalDateTime.now();
// Change the ZoneId as required e.g. ZoneId.of("Europe/London")
ZoneId zoneId = ZoneId.systemDefault();
OffsetDateTime odt = ZonedDateTime.of(ldt, zoneId).toOffsetDateTime();
Notes:
In all the solutions given above, replace the sample ZoneOffset as required e.g. ZoneOffset offset = ZoneOffset.of("+02:00").
In all the solutions given above, replace the sample LocalDateTime as required e.g. LocalDateTime ldt = LocalDateTime.of(2021, 3, 14, 10, 20).
You need to obtain the ZoneOffset to use when creating your OffsetDateTime. One approach is to use a ZoneId for your location:
final ZoneId zone = ZoneId.of("Europe/Paris");
LocalDateTime localDateTime = LocalDateTime.now();
ZoneOffset zoneOffSet = zone.getRules().getOffset(localDateTime);
OffsetDateTime offsetDateTime = localDateTime.atOffset(zoneOffSet);
System.out.println(offsetDateTime); // 2019-08-08T09:54:10.761+02:00
How about:
OffsetDateTime convertToOffsetDateTime(LocalDateTime ldt) {
ZoneOffset offset = OffsetDateTime.now().getOffset();
OffsetDateTime offsetDateTime = ldt.atOffset(offset);
return offsetDateTime;
}
An OffsetDateTime is just a date time with an offset from UTC.
So if you have a fixed offset (e.g. +02 from UTC), you can convert the localDateTime like this :
OffsetDateTime.of(localDateTime, ZoneOffset.of("+2"));
OffsetDateTime.of(localDateTime, ZoneOffset.of("+02"));
OffsetDateTime.of(localDateTime, ZoneOffset.of("+02:00"));
Most of the time you want to have the offset of a specific timezone, in this case it would be preferable to use a ZonedDateTime because for most timezone the offset is not the same in summer/winter and ZonedDateTime will automatically handle it for you.
If you absolutely want an OffsetDateTime with an offset from a specific timezone, you can write :
localDateTime.atZone(ZoneId.of("Europe/Paris")).toOffsetDateTime();
Here is my solution:
public Instant toInstant(LocalDate date) {
return date
.atStartOfDay()
.toInstant(ZoneOffset.UTC);
}
public OffsetDateTime toOffsetDateTime(LocalDate date) {
return OffsetDateTime.ofInstant(
toInstant(date),
ZoneOffset.UTC
);
}
If you want to convert a specific LocalDateTime to an OffsetDateTime this might help you:
final LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime = " + localDateTime);
final ZoneOffset offset = ZoneOffset.ofHours(3);
final OffsetDateTime offsetDateTimeRef = OffsetDateTime.now(offset);
System.out.println("offsetDateTimeRef = " + offsetDateTimeRef);
final OffsetDateTime offsetDateTimeFromLocalDateTime = OffsetDateTime.ofInstant(localDateTime.toInstant(ZoneId.systemDefault().getRules().getOffset(localDateTime)), offset);
System.out.println("offsetDateTimeFromLocalDateTime = " + offsetDateTimeFromLocalDateTime);
Output:
localDateTime = 2022-11-11T23:58:34.260550200
offsetDateTimeRef = 2022-11-12T01:58:34.262501700+03:00
offsetDateTimeFromLocalDateTime = 2022-11-12T01:58:34.260550200+03:00

spring jpa auditing with localdate

I want to get a monthly list, weekly list according to created date but JPA doesn't support LocalDate.
My Code like this:
UserDao:
List<User> findByCreatedAtBetween(LocalDate start, LocalDate end);
UserEntity:
#Column(nullable = false, updatable = false)
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private LocalDate createdAt;
#Column(nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private LocalDate updatedAt;
But createdAt and updatedAt only supports java.util.Date. Why doesn't it support java.time.LocalDate?
As you found out LocalDate is currently not supported by Spring Data Envers, or actually in Spring Data Commons where the relevant code resides.
The reason for this is that these timestamp fields are intended to, well, be time stamps, i.e. specify points in time. LocalDate doesn't do that. The problem is not so much the lack of accuracy, but that LocalDate and its sibling LocalDateTime do not define an ordering. It is perfectly possible that something that happened on the Jan 1st, 1970 happened after something else that happened on Jan 2nd, 1970. For more detail refer to the JavaDoc or to http://blog.schauderhaft.de/2018/03/14/dont-use-localdatetime/
Note that LocalDateTime is supported, but mostly because that was implemented before we did realize that it is the wrong type to use for this purpose.
I highly recommend using Instant as the type for this kind of fields.

LocalDateTime to java.sql.Date in java 8?

How to convert LocalDateTime to java.sql.Date in java-8?
My search on internet mostly give me Timestamp related code or LocalDate to java.sql.Date. I'm looking for LocalDateTime to java.sql.Date.
There is no direct correlation between LocalDateTime and java.sql.Date, since former is-a timestamp, and latter is-a Date.
There is, however, a relation between LocalDate and java.sql.Date, and conversion can be done like this:
LocalDate date = //your local date
java.sql.Date sqlDate = java.sql.Date.valueOf(date)
Which for any given LocalDateTime gives you the following code:
LocalDateTime dateTime = // your ldt
java.sql.Date sqlDate = java.sql.Date.valueOf(dateTime.toLocalDate());
#M. Prokhorov's answer is correct, I just want to add a few points.
A java.sql.Date keeps only the day, month and year values. The time values (hour, minute, seconds and milliseconds) are all set to zero. So, when converting a LocalDateTime to a java.sql.Date, these fields are lost.
If you're doing a one-way conversion and don't mind losing those fields, then it's ok to do it:
LocalDateTime dt = // LocalDateTime value
// convert to Date (time information is lost)
java.sql.Date date = java.sql.Date.valueOf(dt.toLocalDate());
But if you want to restore the original LocalDateTime later, it's better to save the time fields separetely, so you can recover it:
LocalDateTime dt = // your LocalDateTime
// save time information (hour, minute, seconds, fraction of seconds)
LocalTime savedTime = dt.toLocalTime();
// convert to Date (time information is lost)
java.sql.Date date = java.sql.Date.valueOf(dt.toLocalDate());
// retrieve back the LocalDate (only day/month/year)
LocalDate localDate = date.toLocalDate();
// retrieve the LocalDateTime, with the original time values
LocalDateTime ldt = localDate.atTime(savedTime);
It is possible to convert from LocalDateTime to java.sql.date while retaining the time part without havng to make assumptions about the time-zone by using java.util.Date as an intermediary:
LocalDateTime dateValue = // your LocalDateTime
java.util.Date utilDate;
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss";
DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern(dateFormat);
SimpleDateFormat sdf1 = new SimpleDateFormat(dateFormat);
try {
utilDate = sdf1.parse(dateValue.format(dtf1));
} catch (ParseException e) {
utilDate = null; // handle the exception
}
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

Spring mvc ZonedDateTime conversion to UTC

I woudl ike to convert all java8 ZonedDateTimes into UTC time zone on the server side of the application. I am successfully binding the Java 8 jsr310 date data types into a spring RestController using the #DateTimeFormat.
#RequestMapping(value = "rest/test-date", method = RequestMethod.GET)
public TestCollection findPrivilegesByRoleList(
#RequestParam(value = "local-date", defaultValue = "2015-05-10") #DateTimeFormat(iso = ISO.DATE) LocalDate requestParamDate,
#RequestParam(value = "local-date-time", defaultValue = "2015-05-16T15:55:56") #DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime requestParamLocalDateTime,
#RequestParam(value = "zoned-date-time", defaultValue = "2015-05-18T11:55:56-04:00") #DateTimeFormat(iso = ISO.DATE_TIME) ZonedDateTime requestParamZonedDateTime
)
For the ZonedDateTime class, I would like to shift all input ZonedDateTimes to UTC time, so the server side is always working in UTC timezone. Following best practice #3 - Store it in UTC
http://apiux.com/2013/03/20/5-laws-api-dates-and-times/#comments
For JSON deserialization, I have a custom deserializer for ZonedDateTime that shifts any timezone into UTC.
....
//Parse string into a zoned date time with the specified timezone offset - EST, CET, EDT, PST, ect.
ZonedDateTime zonedDateTimewithTimeZone = ZonedDateTime.parse(string, formatter);
//Shift the date time to UTC Time
return zonedDateTimewithTimeZone.withZoneSameInstant(ZoneId.of("UTC"));
What is the best way to do the conversion in the controller binding? I understand this may be forcing multiple responsibilities into the same class, however I want to avoid adding the
ZonedDateTime.withZoneSameInstant
call for every date in every controller.
Thanks

how to avoid rejected value [] issue in spring form submission

i have two dates in form submission in Spring 3 + Hibernate.
#Column(name = "FinStartDate")
private Date finStartDate;
#Column(name = "FinEndDate")
private Date finEndDate;
I'm display/hide dates on the basis of some criteria. When the dates are hidden and submit the form, the following errors
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'register' on field 'obj.finEndDate': rejected value []; codes [typeMismatch]
How to avoid the issue.
#JsonDeserialize(using = LocalDateDeserializer.class)
#JsonSerialize(using = LocalDateSerializer.class)
#DateTimeFormat(pattern = "dd.MM.yyyy")
private Date finEndDate;
Maybe, you should use serializer/deserializer.
I think that you miss a formatter to convert the date String to a Date object.
You can try to annotate your field
#DateTimeFormat(pattern = "yyyy-MM-dd")
or to declare a initbinder in your controller like :
#InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, false));
}
Or you can declare a formatter in you mvc configuration file that will format every Date object your application is binding to.
Add #DateTimeFormat annotation for following way. If not working update date format. (MM-dd-yyyy, dd-MM-yyyy)
#Column(name = "FinEndDate")
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date finEndDate;

Resources