Query on Date only with Spring Boot Data JPA / Java 8 Instant? - java

I have a Spring boot 1.4.x application that uses the starter jpa in combination with H2/Postgresql. I have an entity that stores a date as an Instant (with Instant.now(), based on Java 8: What's the difference between Instant and LocalDateTime? answer), and the associated table stores this field as a timestamp.
For the storing to work I had to setup a converter that converts Instant's to sql.Timestamps & vice versa, which seems to work (Timestamp.from(instant) and timestamp.toInstant())
My question is if there is a straightforward way to query by Date only using this instant using JPA repository, eg.
List<Orders> findBySaleTime(.... day)
Or am I forced to find a way to convert the day to two instants & do an in between query?

There are two approaches:
1st one:
List<Orders> findBySaleTimeBetween(DateTime start, DateTime end);
2nd one:
List<Orders> findBySaleTime(DateTime date);
It's worth trying to save dates rounded as much as possible, so if you only need day, set hours and minutes to certain values for all the entities.

public List<SaleOrder> findByDate(String date) {
Instant startOfDay = Instant.parse(date).truncatedTo(ChronoUnit.DAYS);
Instant endOfDay = startOfDay.plus(Duration.ofDays(1));
return saleOrderRepository.findBySaleTimeAfterAndSaleTimeBefore(startOfDay, endOfDay);
}
Where the date is an UTC date passed from the client, seems to be the most straightforward to do this with java 8 dates. (Credits to Liste & Yawkat on freenode #java for help/pointers)

Related

How to get the day (ex: Monday) from a time Instant in FreeMarker

So I got this Instant date in Java: "2018-05-19T22:00:00Z".
How can I get the day of the week? like monday..
I was trying this but it doesn't work:
${date?string["EEEE"]}
Thanks
Freemarker does not work with Instant, so you would need to convert that to string in Java (something like "2018-05-19T22:00:00Z") and then convert the string doing the following:
<#setting locale="en_US">
${"2018-05-19T22:00:00Z"?datetime.iso?string["EEEE"]}
First convert the string to datetime in iso format, and then back again to string with the pattern of your choosing.
By changing the locale setting, you may get the day of the week in different languages.
I think that the best way to work in Freemarker is to always have strings or integers variables.
At this point FreeMarker does not support Java 8 time, see the contribute page:
What should I contribute?
Usually, contributors come because they want to fix/improve a certain thing. But if you just want to help in general, here are some topics ...
Support for Java 8 date/time API-s (this is actually certainly a difficult one). Note that there's a 3rd party solution for this, https://github.com/amedia/freemarker-java-8, but it's not as seamless as a native solution could be.
...
So you could check out the third party solution.
See also:
Java.time (Java 8) support in Freemarker
${date?string["EEEE"]} works fine as long as date is a java.util.Date object.
You can test it in this way:
<#assign date = .now>
${date?string["EEEE"]}
I guess that it doesn't work because your date is a String, in this case you should parse it in Java (server-side) and expose a java.util.Date variable to the template.
I would advise you to use new Date Time API defined in Java 8.Using Date Time API you can fetch all data related to Date and Time easily.
Java 8 has defined a separate Enum for handling days of the week named – DayOfWeek (java.time.DayOfWeek)
java.time.DayOfWeek is an Enum which defines 7 constants representing the seven days of the week – MONDAY(int value=1), TUESDAY(2), WEDNESDAY(3)… till SUNDAY(7).
import java.time.*;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester = new Java8Tester();
java8tester.testLocalDateTime();
}
public void testLocalDateTime() {
// Get the current date and time
LocalDateTime currentTime = LocalDateTime.parse("2018-05-19T22:00:00");
System.out.println("Current DateTime: " + currentTime);
DayOfWeek dayOfWeek = currentTime.getDayOfWeek();
System.out.println(currentTime + " was a " + dayOfWeek);
}
}

How to make sure mongo stores the date as is without converting to UTC? [duplicate]

Using Spring Boot 1.5.4.RELEASE and Mongo driver 3.4.2.
I want to store LocalDate in mongo DB, but I am facing a weird problem:
LocalDate startDate = LocalDate.now();
LocalDate endDate = LocalDate.of(2020,12,01);
System.out.println("---- StartDate : ---"+startDate);
System.out.println("-----End Date : ----"+endDate);
repository.save(new Person("Mehraj","Malik", startDate, endDate));
Output on console:
---- StartDate : ---2017-08-26
-----End Date : ----2020-12-01
But In MongoDb it is storing incorrect dates.
Following is the json from MongoDb:
"startDate" : ISODate("2017-08-25T18:30:00.000Z"),
"endDate" :ISODate("2020-11-30T18:30:00.000Z")
Also, I have noticed that the stored time is also incorrect according to Indian time.
Why the dates are correct on console but not in MongoDB and how to resolve this problem?
The mongo-java client for a date object returns as instance of
java.util.Date.
The problem could possibly be that while you save the startDate and the endDate value, its toString() method would probably use the JVM's default time zone to update the value.
The doc here states that The official BSON specification refers to the BSON Date type as the UTC datetime. and that could be the reason your LocalDateTime attributes were converted to the UTC time zone prior to being saved to the DB.
Also to avoid such confusion would suggest using the bson type timestamp to update date fields.
In the MongoDB Java Driver 3.7 release : http://mongodb.github.io/mongo-java-driver/3.7/whats-new/ we can see that the driver now support LocalDate :
JSR-310 Instant, LocalDate & LocalDateTime support
Support for Instant, LocalDate and LocalDateTime has been added to the driver.

Always save date to today's date in database using jhipster

I have created one entity in jhipster using jhipster-jdl.jh file which is as shown below:
entity EmployeeLeave{
appliedDate LocalDate required,
fromDate LocalDate required,
toDate LocalDate required,
status String
}
From these fields i want appliedDate as today's date in database(MySql).
I have tried this from Angular side in jhipster code but none helps well.
Is there any way so that when creating a record for employeeLeave there should be always appliedDate equals to today's date.
Preferably i want solution from Angular side. Other solutions are also welcomed.
Technologies:
Database: Mysql,
Spring-boot,
Angular 4,
Jhipster.
You can initialize your date inside your class :
public class EmployeeLeave{
LocaleDate yourDate = LocaleDate.now();
//other fields
}
So, appliedDate will always be today's date. I am using Java 8 but the idea is here.
LocaleDate.now() is server time. If server is in another time zone than user, may insert incorrect date.
Isn't better to define date in .controller.js like:
var now = new Date();
vm.employeeLeave.appliedDate=now;
vm.isSaving = true;
EmployeeLeave.update(vm.employeeLeave, onSaveSuccess, onSaveError);
?

DateTime withTimeAtStartOfDay with timezone

could somebody help or give me some hint with following problem. I have trouble with creating Timestamp in Java. In my db i have timestamp stored in UTC time for example 2016-10-20 23:30:00.000000 and my timezone is Europe/Prague so time is +1 Hour. And if i want to select records from 2016-10-21 i have to select also records from 2016-10-20 23:00:00.000000 if i want to have correct results. I am using Postgresql and JOOQ.
public DateTime getDateTimeWithZone() {
return new DateTime().withZone(MyFormatter.getDateTimeZone());
}
This code is in service class Localization service.
Then in controller i create joda time Interval.
Interval range = new Interval(localizationService.getDateTimeWithZone().withTimeAtStartOfDay(), localizationService.getDateTimeWithZone().withTimeAtStartOfDay().plusDays(1));
This gives me
2016-10-21T00:00:00.000+01:00/2016-10-22T00:00:00.000+01:00
and then in method for selecting records from db via JOOQ i use this construction
Timestamp start = new Timestamp(dtRange.getStartMillis());
Timestamp end = new Timestamp(dtRange.getEndMillis());
and result is
start = 2016-10-21 00:00:00.0
end = 2016-10-22 00:00:00.0
but i need to have start and end one hour back
Also i tried to modify method getDateTimeWithZone() with UTC time
public DateTime getDateTimeWithZone() {
return new DateTime().withZone(DateTimeZone.UTC);
}
range is the same. I think problem is with .withTimeAtStartOfDay() but in this case i need to have .withTimeAtStartOfDay() return 2016-10-20 23:00:00.0000. Is there any way how to do it with joda time or new java.time or write some own implementation od DateTime and override .withTimeAtStartOfDay() to return shifted DateTime. I will appreciate any help.

Hibernate Envers Timestamp from revision date

I'm using MySQL and Hibernate Envers to log audity info, it saves a timestamp in a numeric format, how can i convert this timestamp to date in MySQL, not in Java?
Thanks!
UPDATE -
You can use FROM_UNIXTIME() in-built function.
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_from-unixtime
Simply taking it into Date object, it should work -
Date date = resultSet.getTimestamp("timestamp");
I guess this timestamp includes milliseconds, so you can simply divide this value by 1000 :
FROM_UNIXTIME(hr.`TIMESTAMP`/1000)
Formatted:
DATE(FROM_UNIXTIME(hr.`TIMESTAMP`/1000))
OR
DATE_FORMAT(FROM_UNIXTIME(hr.`TIMESTAMP`/1000) ,'%Y-%m-%d %H:%i:%s')

Categories