Postgres convert date time difference into HH:MM:SS - java

Ex:
startTime-EndTime
Diff is 0 years 0 months 5 days 20 hours 6 minutes 30 seconds. I want to convert this into HH:MM:SS format : 120:06:30.

tl;dr
Duration // Represent a span-of-time in terms of total number of whole seconds plus a fractional second in nanos.
.between( // Calculate elapsed time.
myResultSet.getObject( … , OffsetDateTime.class ) , // Start
myResultSet.getObject( … , OffsetDateTime.class ) , // Stop
) // Returns a `Duration` object.
.toString() // Generate text in standard ISO 8601 format of `PnYnMnDTnHnMnS`.
java.time
Doing it on the Java side is simple with a column of a data type akin to the SQL-standard TIMESTAMP WITH TIME ZONE and driver compliant with JDBC 4.2 or later (for support of the modern java.time classes).
OffsetDateTime
Retrieve your moments as OffsetDateTime objects, per JDBC 4.2 spec.
OffsetDateTime start = myResultSet.getObject( … , OffsetDateTime.class ) ;
OffsetDateTime stop = myResultSet.getObject( … , OffsetDateTime.class ) ;
Duration
Calculate elapsed time as a Duration object.
Duration d = Duration.between( start , stop ) ;
ISO 8601
Generate a standard ISO 8601 string of the format PnYnMnDTnHnMnS where the P marks the beginning (probably stands for “period” – no standardized terms in date-time handling unfortunately), and the T separates years-months-days from hours-minutes-seconds. So an hour and a half would be PT1H30M. Your example of 5 days 20hours 6minutes 30 seconds would be P5DT20H6M30S.
The java.time classes use the ISO 8601 format by default. So you generate text by simply calling toString. No need to specify a formatting pattern.
String output = d.toString() ;
P5DT20H6M30S
To parse, call parse.
Duration d = Duration.parse( "P5DT20H6M30S" ) ;
Note that Duration counts days as 24-hour chunks of time, without regard for the calendar. If you want calendar-based dates, use Period class. If you want both concepts together, use PeriodDuration class from the ThreeTen-Extra, but think twice as mixing the two concepts is usually unwise and impractical.
I strongly advise you not represent a span-of-time using the clock notation as shown in your Question. Doing so is ambiguous, error-prone with people misinterpreting the text, as I have personally seen happen in business scenarios. The standard format is much wiser.
Duration::to…Part
But if you insist on the clock-formatting, create a string by calling the to…Part methods on Duration.
String output = d.toDaysPart() + ":" + d.toHoursPart() + ":" + d.toMinutesPart() + ":" + d.toSecondsPart() + "." + d.toNanosPart() ;
toHours versus toHoursPart
If want all the days reported as hours, get total number of hours across entire span-of-time by calling toHours rather than toHoursPart. Then get the parts of minutes and seconds.
Duration d = Duration.between( start , stop ) ;
String output = d.toHours() + ":" + d.toMinutesPart() + ":" + d.toSecondsPart() ;
120:06:30
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

This can be achieved using postgresql.
To compute the difference between two timestamps as a number of seconds, use :
EXTRACT(EPOCH FROM (startTime - endTime))
Then you tun this value back to a timestamp with function TO_TIMESTAMP, and format this as a time using function TO_CHAR.
The hour part is tricky as you want to display values greater than 24 (which, as you would expect, is the maximum allowed in postgres): you need to use a little arithmetics to compute it.
SELECT CONCAT(
EXTRACT(EPOCH FROM (startTime - endTime))/60/60,
':',
TO_CHAR(TO_TIMESTAMP(
EXTRACT(EPOCH FROM (startTime - endTime))
), 'MI:SS')
)
FROM my_table

Related

Add some hours/mins to current datetime and get the future datetime

I need to get the get the future timestamp value for a particular time. I will have to add a string value to the current datetime timestamp and get the future timestamp value.
I am fetching current timestamp as below:
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
I have a string value as "02:00:00", so basically I need to add 2 hrs to this time and get the future timestamp value that needs to be inserted.
For example if current timestamp is: 2019-04-29 16:59:21.43
and String is "02:00:00".
I need output as 2019-04-29 18:59:21.43.
Can someone please help
You can do something like this
Instant now = Instant.now();
Duration diff = Duration.between(
LocalTime.MIN,
LocalTime.parse("02:00:00")
);
Instant res = now.plus(diff);
System.out.println("res = " + Timestamp.from(res));
You can use the MySQL function TIMESTAMP to add a given time string to your timestamp value:
TIMESTAMP(expr), TIMESTAMP(expr1,expr2)
With a single argument, this function returns the date or datetime
expression expr as a datetime value. With two arguments, it adds the
time expression expr2 to the date or datetime expression expr1 and
returns the result as a datetime value.
mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
-> '2004-01-01 00:00:00'
Reference
tl;dr
Insert a moment two hours from now.
myPreparedStatement // Use a `PreparedStatement` to exchange data with your database, to avoid SQL-injection risk. Use JDBC 4.2 or later for *java.time* support.
.setObject( // Fill a placeholder `?` in your SQL statement.
… , // Specify which placeholder.
OffsetDateTime // Use `OffsetDateTime` to specify a moment in JDBC 4.2. Optionally, your JDBC might support `Instant` or `ZonedDateTime` types, while support for `OffsetDateTime` is required.
.now( // Capture the current moment.
ZoneOffset.UTC // Set the offset-from-UTC to zero. We do not need to account for any time zone in this particular business scenario.
) // Returns an `OffsetDateTime` object.
.plus( // Adds a span-of-time to the moment held in the `OffsetDateTime` object.
Duration.parse( "PT2H" ) // Specify the span-of-time using standard ISO 8601 format for a duration.
) // Per Immutable Objects pattern, returns a new `OffsetDateTime` rather than changing ("mutating") the original.
)
Details
I have a string value as "02:00:00", so basically I need to add 2 hrs to this time and get the future timestamp value that needs to be inserted
That is a poor way to communicate a span-of-time unattached to the timeline.
The standard way is PnYnMnDTnHnMnS where the P marks the beginning, and the T separates the years-months-days from the hours-minutes-seconds. So 2 hours is PT2H.
To parse such a string, use Duration class for hours-minutes-seconds (or Period for years-months-days).
String input = "PT2H" ;
Duration d = Duration.parse( input ) ;
You can generate such a string.
String output = Duration.ofHours( 2 ).toString() ; // Yields "PT2H" string.
Capture the current moment in UTC.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
Add a duration of two hours using standard ISO 8601 notation.
Duration d = Duration.parse( "PT2H" ) ;
ZonedDateTime odtLater = odt.plus( d ) ; // Add 2 hours to the current moment.
Submit that to your database using JDBC 4.2 or later.
myPreparedStatement.setObject( … , odtLater ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I like to consider my timestamps as unsigned ints. It becomes quite silple to modify them : in your case, try to get an uint representation and just add 2 * 3600 * 1000 to the timestamp, then format it tonthe output you want.

Getting different values for Timestamp.valueOf

I am trying to get the timestamp value for 2018-09-04 13:43:32.922000 by doing
Timestamp.valueOf("2018-09-04 13:43:32.922000")
my expected output is 2018-09-04 13:43:32.922
but I am getting 2018-09-04 01:13:32.922
It might be due to different timezone because my team in India got the exact result but I am here in California gets the different result.
Suggest the changes that can solve this problem.
tl;dr
myPreparedStatement.setObject(
Instant
.parse(
"2018-09-04 13:43:32.922000"
.replace( " " , "T" )
.concat( "Z" )
)
.atZone(
ZoneOffset.UTC
)
)
java.time
Suggest the changes that can solve this problem.
Never use java.sql.Timestamp.
Among the many flaws of that class is that the method you call is not documented to explain its behavior while parsing. It appears your JVM’s current default time zone is being silently applied with some adjustment. But the issue is moot.
That terribly-designed class was supplanted years ago by the modern java.time classes with the adoption of JSR 310, specifically Instant and OffsetDateTime.
Change your input string to standard ISO 8601 format by replacing the SPACE in the middle with a T.
String input = "2018-09-04 13:43:32.922000".replace( " " , "T" ) ;
Was your input intended to represent a moment in UTC, an offset of zero? If so, append a Z (pronounced Zulu).
String input = "2018-09-04 13:43:32.922000".replace( " " , "T" ).concat( "Z" ) ;
The Instant class represents a moment in UTC, always in UTC by definition.
Instant instant = Instant.parse( input ) ;
Your JDBC driver may optionally accept a Instant object.
myPreparedStatement.setObject( instant ) ;
If your JDBC driver does not support Instant, use OffsetDateTime. Support is required in JDBC 4.2 and later.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( odt ) ;
Notice how your JVM’s current default time zone at runtime is irrelevant, with no impact on the code above.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I do not think the issue is due to different time zones. Its just that the output that you are getting is in 24 hour format and that needs to be converted to 12 hour format. Please refer How to convert 24 hr format time in to 12 hr Format? to convert the time to 12 hour format.

Java Spring MySQL String Timezone column between two milliseconds

I got a stored Timezone date as String on a MySQL Column with the next format:
2018-07-23T20:54:37.242Z --> start_date
What I want to do is a Between two milliseconds(or dates) like this:
SELECT * FROM activity_entity WHERE start_date BETWEEN 1532322000000 AND 1532408399000
Else, I'm using Java Spring Repository as backend where I send the parameters like this:
Date since = new Date(accessRepPOSTInDto.getSince()); //1532322000000 gives Mon Jul 23 00:00:00 CDT 2018
Date to = new Date(accessRepPOSTInDto.getTo());//1532408399000 gives Mon Jul 23 23:59:59 CDT 2018
#Query(value = "SELECT * FROM activity_entity WHERE start_date BETWEEN :since AND :too , nativeQuery = true)
ActivityEntity findBetweenDates(#Param("since") Date since, #Param("too") Date too);
Doing this returns null;
I thought MySQL can automatically format the two dates and the String column to do the Between but it looks like it doesn't.
Any help will be really grateful. Regards.
In your native query, you need to explicitly cast the value of your varchar column to the proper date/timestamp to be evaluated by the between operator. This is how your native query should look like:
SELECT * FROM activity_entity WHERE STR_TO_DATE(start_date, '%Y-%c-%eT%H:%i:%s.%fZ') BETWEEN :since AND :too
tl;dr
SQL:
SELECT * FROM tbl WHERE event >= ? AND event < ? ; -- Using Half-Open approach where beginning is *inclusive* while the ending is *exclusive*.
Java:
myPreparedStatement.setString( 1 , Instant.ofEpochMilli( 1_532_322_000_000L ).toString() ) ;
myPreparedStatement.setString( 2 , Instant.ofEpochMilli( 1_532_408_399_000L ).toString() ) ;
ISO 8601
2018-07-23T20:54:37.242Z
Text in this format is abiding by the ISO 8601 standard. That standard is the best way to represent date-time values as text. But in a database you should be using a purpose-built data type, defining a column of type akin to the SQL-standard TIMESTAMP WITH TIME ZONE. Search Stack Overflow for much more info.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
Instant instant = Instant.parse( "2018-07-23T20:54:37.242Z" ) ;
Count-from-epoch
You can convert your count of milliseconds since the epoch reference of first moment of 1970 in UTC using the Instant class.
Instant start = Instant.ofEpochMilli( 1_532_322_000_000L ) ;
Instant stop = Instant.ofEpochMilli( 1_532_408_399_000L ) ;
Generate strings in standard ISO 8601 format used in your database column.
String startStr = start.toString() ;
String stopStr = stop.toString() ;
Avoid legacy date-time classes
The old date-time classes that were bundled with the earliest versions of Java are bloody awful. Never use them. They have been supplanted entirely by the java.time classes.
Half-Open
What I want to do is a Between
The BETWEEN command in SQL should generally not be used with date-time values. That command is fully “closed” meaning both the beginning and the ending are inclusive.
Instead, for date-time work, it is generally best to define a span-of-time as Half-Open. In this approach the beginning is inclusive while the ending is exclusive. For example, students dismissed for lunch break from noon to 1 PM are expected back in their seats before the clock strikes 1 and the bell rings. Another example, a week starts on a Monday and runs up to, but does not include, the following Monday.
In SQL code, this means a query uses >=, AND, and <.
SELECT *
FROM tbl
WHERE event >= ?
AND event < ?
;
Since ISO 8601 format with the Z is chronological when sorted alphabetically, you can make this work with your ISO 8601 strings.
myPreparedStatement.setString( 1 , startStr ) ;
myPreparedStatement.setString( 2 , stopStr ) ;
If you had used a TIMESTAMP WITH TIME ZONE column type as discussed above, you would simply pass the Instant objects.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;
If you really must use fully-closed approach, adjust the query operators >=, AND, and <=. Or call BETWEEN.
I am not a Spring user, cannot help you there.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Java: transform Long Timestamp + int offset to readable format

I'm trying to convert a Long timestamp with an offset (int) into a more readable format. So for example I have 1514564669355 as a timestamp with offset equal to 360. How should I go about transforming this into the equivalent date format using java?
In this case the timestamp would be stored in UTC, so with the offset I'm looking to converting it to whatever timezone it needs. Thanks for any help/tips.
Your Question is not clear.
Perhaps you mean you have a value in UTC and want to adjust it to an offset of 360 minutes ahead of UTC. (A poor way to communicate a moment in time.)
Or perhaps you meant the given value is already ahead of UTC. (An even worse way to communicate a moment in time.)
Starting with UTC
First parse your input number. We will assume that number is a count of milliseconds since the first moment of 1970 UTC, 1970-01-01T00:00Z.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.ofEpochMilli( 1_514_564_669_355L ) ;
instant.toString(): 2017-12-29T16:24:29.355Z
An offset-from-UTC is a number of hours, minutes, and seconds ahead of, or behind, UTC.
Perhaps your Question’s mention of an offset of 360 is meant to be 360 minutes, or 6 hours ahead of UTC.
The ZoneOffset class cannot be instantiated from a number of minutes over 59. So we convert from 360 minutes to a total number of seconds.
int seconds = ( int ) TimeUnit.MINUTES.toSeconds( 360L ) ; // Convert minutes to seconds.
ZoneOffset offset = ZoneOffset.ofTotalSeconds( seconds ); // Determine offset-from-UTC.
offset.toString(): +06:00
Adjust our Instant in UTC to this offset, yielding a OffsetDateTime object. Same moment, same point on the timeline, different wall-clock time. So the time-of-day is seen as 10 PM rather than as 4 PM since ( 16 + 6 ) = 22.
OffsetDateTime odt = instant.atOffset( offset );
odt.toString(): 2017-12-29T22:24:29.355+06:00
Starting with offset
Perhaps you meant the moment being communicated is a count of milliseconds from UTC but then the number of milliseconds in 360 minutes has already been added or subtracted.
By the way, this is a very bad way to exchange date-time values. Educate the supplier of your data about the ISO 8601 standard.
Let's undo that addition/subtraction of an offset, to get back to UTC.
long millisInOffset = TimeUnit.MINUTES.toMillis( 360L ); // Convert minutes to milliseconds.
long millisSinceEpoch = ( 1_514_564_669_355L - millisInOffset );
Instant instant = Instant.ofEpochMilli( millisSinceEpoch );
instant.toString(): 2017-12-29T10:24:29.355Z
See that value in the offset sent to us.
int seconds = ( int ) TimeUnit.MILLISECONDS.toSeconds( millisInOffset );
ZoneOffset offset = ZoneOffset.ofTotalSeconds( seconds );
OffsetDateTime odt = instant.atOffset( offset );
System.out.println( odt );
2017-12-29T16:24:29.355+06:00
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

How to get all milliseconds of a day?

I store a number of rows in DB with the timestamp of that moment in milliseconds.
Now if I need to retrieve all rows of a given day, like today, how do I correctly create the starting and ending milliseconds of that day?
I know about SimpleDateFormat and Calendar.getInstance() briefly, but would I need to do string manipulation (which I want to avoid) to get todays date only, add the hours part and then convert it back into milliseconds, or is there a better way to do it?
Since you didn't provide any code in your question, please allow me to give you a general answer in response..
What you're looking for are two date/times, today and tomorrow, both specified a "0 hours, 0 minutes, 0 seconds".
today <= date AND date < tomorrow
Note the two different comparisons.
The simplest technique would be to use DateFormat:
String input = "Sat Feb 17 2013";
Date date = new SimpleDateFormat("EEE MMM dd yyyy", Locale.ENGLISH).parse(input);
long milliseconds = date.getTime();
String input1="Sun Feb 18 2013"
Date inputNextDay = new SimpleDateFormat("EEE MMM dd yyyy", Locale.ENGLISH).parse(input);
long millisecondsForNextDay=inputNextDay.getTime();
To get the rows that fall on a particular day, just find rows having milliseconds value of timestamp between milliseconds and millisecondsForNextDay:
if(rowsTimestampSeconds>milliseconds && rowsTimestampSeconds<millisecondsForNextDay){
//get the row
}
You can use the GregorianCalendar class to do this without any strings.
Calendar calendar = new GregorianCalendar(year, month, day);
long start_of_day_millis = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_MONTH, 1);
long next_day_millis = calendar.getTimeInMillis();
The reason to use calendar.add(Calendar.DAY_OF_MONTH); instead of just adding (24*60*60*1000) to the first millisecond value is to account for leaps. Beyond the commonly known leap year, there are occurrences of leap seconds. See this link: http://www.timeanddate.com/time/leapseconds.html
Make sure that your expression is inclusive of start_of_day_millis (greater than or equal) and exlusive of next_day_millis (lesser than).
i.e: if(test_time >= start_of_day_millis && test_time < next_day_millis)
Update:
If you want today's date you can omit all the parameters in the calendar constructor and just call new GregorianCalendar(), but you will need to ensure that the hour, minute, second and millisecond fields are being zeroed out with calls to calendar.set(Calendar._FIELD_NAME_, 0); afterwards, before you use the calendar, because it would be initialized to the exact moment the object is created.
You should be using a date-time type for your database column to store date-time data rather than an integer of milliseconds. The SQL standard defines a few date-time types. But support for date-time varies widely, with Postgres being one of the best.
Since you tagged Java, read this Question and my Answer to learn about using Java to pinpoint the first moment of today and tomorrow. The Half-Open approach used there is common in date-time work. Half-Open means a span of time where the beginning is inclusive while the ending is exclusive. For SQL, it means not using the BETWEEN operator.
java.time
The java.time framework is built into Java 8 and later, and back-ported to Java 6 & 7 and to Android. Read my other Answer for details.
Get the first moments of today and tomorrow. Be aware that time zone is crucial in determining dates and the meaning of “today”. For any given moment, the date varies around the world by time zone. A new day begins earlier in the east. For example, a few moments after midnight in Paris is still “yesterday” in Montréal.
Instant instant = Instant.now();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );
Some day we may see JDBC drivers updated to directly handle java.time types. Indeed, JDBC 4.2 compliant drivers may work if you call getObject and setObject on your ResultSet and PreparedStatement respectively. But if not, fallback to using the java.sql types. Notice the new methods added to these old classes including java.sql.Timestamp. The from method takes an Instant which we can extract from our ZonedDateTime objects.
java.sql.Timestamp tsStart = java.sql.Timestamp.from( zdtStart.toInstant() );
java.sql.Timestamp tsStop = java.sql.Timestamp.from( zdtTomorrowStart.toInstant() );
Now set these two variables are arguments on your PreparedStatement. Notice the comparison operators, testing for possible values that start on first moment of the day (>=) and running up to but not including the first moment of the next day (<).
String sql =
"SELECT * FROM event_" +
"WHERE when_ >= ? " +
"AND when_ < ? " +
";" ;
…
pstmt.setTimestamp( 1 , tsStart );
pstmt.setTimestamp( 2 , tsStop );
If you do indeed store integers instead of using date-time types, and you are storing milliseconds as a count from the epoch reference date-time of first moment of 1970 in UTC, then you can extract a number from each Instant. Remember that the java.time classes use a finer resolution of nanoseconds as do some databases such as H2 Database, and some databases such as Postgres capture date-time with a resolution of microseconds. So truncating to milliseconds may mean a loss of data.
long millisStart = tsStart.toInstant().toEpochMilli();
long millisStop = tsStop.toInstant().toEpochMilli();
Call setLong on your PreparedStatement.
pstmt.setLong( 1 , millisStart );
pstmt.setLong( 2 , millisStop );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Categories