Convert Date and Time with different timezones to timestamp - java

got a little problem in Java: I've got two strings, representing a date (for example "2019-11-10") and a time (for example "01:23:45.123"). Converting those into a UTC timestamp is easy enough, but there is one problem:
The date is given in a local timezone, for example "America/New_York", while the time is given in UTC, so the following information...
date = "2019-11-10", time="01:23:45.123" (assuming a local timezone of "America/New_York" for the date part)
...would actually be the UTC time "2019-11-11 01:23:45.123" (since only this would be a New York date of "2019-11-10").
Does the Java Time API or joda time offer any convenient method to do this conversion while keeping also details like DST, etc. in mind? Is there a (relatively) simple way of doing this at all?
Edit:
Perhaps this was a bit unclear. Let me try to explain it from the other side:
Assuming I have a DateTime x (in UTC) of "2019-11-11 01:23:45.123".
Then I can get the date part y (as seen in "America/New_York") by simply converting x into the appropriate timezone and formatting is accordingly -> "2019-11-10".
I can also get the time part z (as seen in UTC) by simply formatting is accordingly - "01:23:45.123".
Now, assuming I've got y and z - How do I get x?
Edit 2:
I just realized, this will never work perfectly. Reason:
UTC "2019-11-04 04:01:00.000" -> US/NY : "2019-11-03 23:01"
UTC "2019-11-03 04:01:00.000" -> US/NY : "2019-11-03 00:01"
So, if I only got the information "date in US/NY" is "2019-11-03" plus "time in UTC" is "04:01:00.000" there are actually two possible solutions and not only one.

You have to adjust the date to be in the New York time zone which can be done by choosing an arbitrary time. Then convert the time to New York by choosing an arbitrary date. The two can then be merged as they have the same zone. And convert back to UTC
LocalDate date = LocalDate.parse("2019-11-10");
LocalTime time = LocalTime.parse("01:23:45.123");
ZoneId zone = ZoneId.of("America/New_York");
ZonedDateTime dateInZone = date.atStartOfDay(zone);
ZonedDateTime timeInZone = time.atOffset(ZoneOffset.UTC).atDate(date).atZoneSameInstant(zone);
ZonedDateTime resultNY = dateInZone.with(timeInZone.toLocalTime());
ZonedDateTime resultUTC = resultNY.withZoneSameInstant(ZoneOffset.UTC)
System.out.println(resultUTC);
// 2019-11-11T01:23:45.123Z

A date cannot have a time zone. (Think about it.)
Perhaps what you mean is the first moment of the day for that date as seen in UTC.
LocalDate ld = LocalDate.parse( "2019-11-10" ) ;
ZonedDateTime zdt = ld.atStartOfDay( ZoneOffset.UTC ) ;
Adjust that moment to be seen in a time zone.
ZoneId z = ZoneId.of( "America/New_York" ) ;
LocalTime lt = LocalTime.parse( "01:23:45.123" ) ;
ZonedDateTime zdt2 = zdt.with( lt ) ;

Related

How to get time and date from UTC to EST without worrying about Daylight Saving Time(DST)

I have one service which requires the data of date and time which I am collecting from my database.
The data in the database is stored according to the UTC time zone.
Now I want to get those data from the data and present it to the user in the time zone whatever the want it to be in or just so the data of time and data as per there systems default time zone.
As right now I have some hard coded thing that makes the changes if the Daylight Saving Time changes
For example I the DST starts it substracts 4 hours(as per EDT) from the data that is in the system and if the DST ends I have to manually change the substracted hour with 5(as per EST) hours and the present it to the user.
I am currently doing it as bellow
Here I m using
Date from java.util.Date
getObtainedDate is for getting data from the database
I have added this minus so that it will substract that amount of time from the date.
Instant ins = attachment.getObtainedDate().toInstant();
ins = ins.minus(5, Chronounit.HOURS); // without DST
Date alteredDate = Date.from(ins);
Instant ins = attachment.getObtainedDate().toInstant();
ins = ins.minus(4, ChronoUnit.HOURS); // during DST
Date alteredDate = Date.from(ins);
I want to get rid of this hard coded thing as I have to manually change the 5 and 4 whenever the DST starts and ends.
Thank you in advance
tl;dr
You said:
some time and dates data from the database and for which the time is stored in UTC timezone
and you said:
from UTC to EST without worrying about Daylight Saving Time (DST)
myResultSet
.getObject( … , OffsetDateTime.class ) // Returns a `OffsetDateTime` object, the appropriate class mapping to the standard SQL type `TIMESTAMP WITH TIME ZONE`.
.atZoneSameInstant( ZoneId.of( "America/New_York" ) ) // Returns a `ZonedDateTime` object.
If handed an object of the terribly flawed legacy class java.util.Date, immediately convert to its modern replacement class java.time.Instant. Use new conversion methods added to the old class.
Instant instant = myJavaUtilDate.toInstant() ;
ZonedDateTime zdt = instant.atZone( ZoneId.systemDefault() ) ;
Details
Your Question is confusing and convoluted. You may be trying too hard.
You said:
time and dates data from the database and for which the time is stored in UTC timezone
If your database stores moments as a date with time with an offset of zero hours-minutes-seconds from UTC, then your database table column must be of a type akin to the standard SQL type TIMESTAMP WITH TIME ZONE. If so, you should retrieve using the Java type OffsetDateTime.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
You said:
when the DST starts the data that I am collecting should start substracting
If you want to see that same moment through the wall-clock time of a particular time zone, apply a ZoneId to get a ZonedDateTime object.
Note that EST is not a real time zone name. Perhaps you meant America/New_York.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
If you want to use the JVM‘s current default time zone:
ZoneId z = ZoneId.systemDefault() ;
You said:
I am currently doing it as bellow
Instant ins = …
Instant represents a moment in UTC, always in UTC. But this class does not map to any standard SQL type. Use OffsetDateTime to exchange a moment (a specific point on the timeline) with your database.
You said:
Date alteredDate = Date.from(ins);
As for either of the Date classes, java.util.Date & java.sql.Date: (a) I don’t know which you intended, and (b) neither should be used. Both Date classes are terribly flawed, and are now legacy, supplanted by the modern java.time classes.
You said:
should start substracting 4 hours from the time as in EST the DST offset is -400 and when it ends it should substract 5 hours
No need for you to do the math. No need for you to track the DST cutover dates.
Do your logging, debugging, data storage, data exchange, and most of your business logic in UTC (an offset of zero).
Apply a time zone only for presentation to the user, and where required by a particular rule in your business logic.
By using ZoneId and ZonedDateTime classes, the DST cutovers and adjustments are handled for you.
I manage to get the time as per the timezone where the system is using this code.
This code also manages to change the offset as per the timezone.
I am here using
Date from java.util.Date
ZonedDateTime from java.time.ZonedDateTime
DateTimeFormatter from java.time.DateTimeFormatter
Instant from java.time.Instant
The code for solving this issue
Date date = attachment.getObtainedDate(); // for getting the date in the system
// Here I m setting the zone to system default
ZoneId zoneId = ZoneId.systemDefault(); // for setting the zoneId as per the location you want
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(date.getTime()).atZone(zoneId);
// for formatting date and time
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm");
String requiredDate = zonedDateTime.format(dtf);
If you want to check the offset for the time zone while debugging for more information, you can add one more line to the code
ZoneOffset offset = zonedDateTime.getOffset();

How to add HH:MM:SS format to the LocalDate in java?

LocalDate beginDate = LocalDate.now()
.with(ChronoField.DAY_OF_WEEK, 1)
.atStartOfDay()
.minusDays(8)
.toLocalDate();
I am getting the previous week begin date using the above code line. However I want to add HH:MM:SS format to this. I have tried different ways to get this. Tried using LocalDateTime instead of Localdate. But could not find atStartOfDay() method for LocalDateTime. Help me to add HH:MM:SS to beginDate variable
tl;dr
LocalDate // Represents a date only, without a time of day, without a time zone or offset.
.now( ZoneId.of( "Asia/Amman" ) ) // Returns a `LocalDate`.
.minusDays( 8 ) // Returns another `LocalDate` object.
.atStartOfDay( ZoneId.of( "Asia/Amman" ) ) // Returns a `ZonedDateTime`.
.toString() // Returns a `String` object, with text in standard ISO 8601 format wisely extended to append the name of time zone in brackets.
See this code run at Ideone.com. Notice that on that date in that zone, the day began at 01:00, not 00:00.
2022-02-22T01:00+03:00[Asia/Amman]
No “format” involved
Date-time objects do not have a “format”. Text has a format. Date-time objects are not text.
LocalDate has no time of day
You said:
add HH:MM:SS format to [a LocalDate object]
A LocalDate represents a date only, without a time of day, without a time zone or offset.
ZonedDateTime
Apparently you want the first moment of the day eight days ago as seen in your locality.
First, specify your desired/expected time zone.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
Or use your JVM‘s current default time zone.
ZoneId z = ZoneId.systemDefault() ;
Capture the current date as seen in that zone.
LocalDate today = LocalDate.now( z ) ;
Go back eight days.
LocalDate eightDaysAgo = today.minusDays( 8 ) ;
If you meant to go back to the previous Monday, use a TemporalAdjuster.
LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ;
Get the first moment of that day. Pass your time zone.
ZonedDateTime zdt = eightDaysAgo.atStartOfDay( z ) ;
The time-of-day may be 00:00:00, but not necessarily. Some days on some dates in some zones start at another time such as 01:00:00.
All of this has been covered many times already on Stack Overflow. Search to learn more.
What you want is a LocalDateTime, which is a LocalDate with a time component (including timezone).
LocalDate does as it says on the tin, it gives you a date, not a date and time.
LocalDateTime
.of(LocalDate.now().with(ChronoField.DAY_OF_WEEK, 1), LocalTime.MIDNIGHT)
.minusWeeks(1)
Gives you start of last week at midnight (local time).
#DateTimeFormat("HH:MM:SS")
#JsonFormat("HH:MM:SS")

Spring Boot Java Time zone Bangkok (GMT+8) or another time zone with GMT+8 with ZonedDateTime using java.sql.Timestamp

Good day, it's not some errors. But can someone explain to me what happened here?
I'am using free sql database with Spring framework so basically my sql database was on the cloud. Then I'm inserted date time value to my database using my local time zone (Indonesia (GMT+8)). But the time zone is not correct with my time zone even I'm already used localdatetime.now()
This was the case :
Set up my localdatetime zone
LocalDateTime ldt = LocalDateTime.now();
Using my system default time zone
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
This is the output (My time zone showing at 22:47)
'2022-10-26 16:05:52'
Using (GMT+8)
ZonedDateTime gmt = zdt.withZoneSameInstant(ZoneId.of("GMT+8"));
This is the output (My time zone showing at 23:10)
''2022-10-26 17:10:30''
Using (GMT+12)
This is the output (My time zone showing at 23:15)
''2022-10-26 21:15:47''
Using (GMT+14) I'm even dont know anymore are this time zone literally correct
This is the output (My time zone showing at 23:20)
''2022-10-26 23:20:47'' This was my time zone (basically, this is the right one)
Using GMT+14 was right according to my own clock, but my time zone (Indonesia, GMT+8). Then I'm checked to my server where my database are located at the cloud, then I found it at Asia Pacific.
This is my lines of code :
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
ZonedDateTime gmt = zdt.withZoneSameInstant(ZoneId.of("GMT+14"));
Timestamp timestamp = Timestamp.valueOf(gmt.toLocalDateTime());
transaction.setDate(timestamp);
transactionServices.saveTransaction(transaction);
So are this happened because where my database are located or because something else? Can someone explain so I can improve my code.
I'am expecting using GMT+8 not GMT+14, I'm affraid this can be a problem when this application is produced.
LocalDateTime.now()
I cannot imagine a scenario where calling LocalDateTime.now is the right thing to do.
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
Skip the LocalDateTime variable ldt. Just ask ZonedDateTime to capture the current moment as seen in your desired time zone.
ZoneId z = ZonedId.systemDefault() ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
ZonedDateTime gmt = zdt.withZoneSameInstant(ZoneId.of("GMT+8"));
For an offset, use the subclass ZoneOffset rather than ZoneID.
ZoneOffset offset = ZoneOffset.of( 8 ) ;
And, this code does not make sense in couple ways. Firstly, if you want to represent a moment as seen through an offset, use OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.now( offset ) ;
Secondly, you should generally 👉 prefer a time zone to a mere offset. When adding or subtracting to move through time, using a mere offset means you will fail to account for changes to the offset used by the people in a particular time zone. For example, you will fail to account for Daylight Saving Time (DST) cut-overs. DST is only one example; politicians frequently change the offset of the time zones under their jurisdiction for various reasons including diplomatic, martial, practical, and fashionable.
A reminder of definitions:
An offset is merely a number of hours, minutes, and seconds ahead of, or behind, UTC.
A time zone is much more. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region as decided by their politicians.
For example, the time zone Australia/Perth currently uses an offset of +08:00.
ZoneId z = ZoneId.of( "Australia/Perth" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
By the way, stick with standard ISO 8601 formats for date-time values. So use +08:00 rather than "GMT+8". And I recommend always (a) including both hours and minutes, and (b) using padding zero for single-digit numbers. I have seen more than one library that expects only such values.
Tripping through time zones
You say your own time zone is in Indonesia. I will presume you mean Asia/Jakarta.
Capture the current moment as seen there.
ZoneId zJakarta = ZoneId.of( "Asia/Jakarta" ) ;
ZonedDateTime zdtJakarta = ZonedDateTime.now( zJakarta ) ;
Adjust to UTC, meaning an offset from UTC of zero hours-minutes-seconds. Simply extract a Instant. An Instant is always in UTC, by definition.
Instant instant = zdt.toInstant() ;
Adjust from UTC to another time zone.
ZoneId zEdmonton = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdtEdmonton = instant.atZone( zEdmonton ) ;
Or skip the Instant class. Move from Indonesia time to Canada time.
ZonedDateTime zdtEdmonton = zdtJakarta.withZoneSameInstant( zEdmonton ) ;
👉 Note that all of these moment objects (zdtJakarta, instant, zdtEdmonton) refer to the very same simultaneous moment. All three represent the same point on the time line, just different wall-clock/wall-calendar time.
Avoid legacy classes
Your code:
Timestamp timestamp = Timestamp.valueOf(gmt.toLocalDateTime());
transaction.setDate(timestamp);
👉 Never use the terribly flawed java.sql.Timestamp. This is one of the bloody awful date-time classes that are now legacy, years ago supplanted by the modern java.time classes.
Do not bother trying to study the behavior of these classes. Unless you want a masterclass in how to not design an object-oriented time-tracking framework.
Sun, Oracle, and the JCP community all gave up on the legacy classes with the adoption of JSR 310. I suggest you do the same.
Database
To write a moment to a database, 👉 use OffsetDateTime. Standard SQL lacks the concept of a ZonedDateTime.
To store a moment, a point on the time line, be sure your database table column is of a type akin to the SQL standard type TIMESTAMP WITH TIME ZONE rather than WITHOUT.
ZonedDateTime zdt = … ;
OffsetDateTime odt = zdt.toOffsetDateTime() ; // Discard time zone, keeping only the offset.
myPreparedStatement.setObject( … , odt ) ;
Retrieve.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime zdt = odt.withOffsetSameInstant( myZoneId ) ;
You said:
So are this happened because where my database are located
Do not write code that depends on the current default time zone of your database session, the server OS, or your JVM. If you write database code as I showed here, you are in control of the time zone adjustments.
Not a moment
Notice that nowhere did I use the LocalDateTime class. That is because your Question is asking about moments, specific points on the time line.
A LocalDateTime contains only a date and a time-of-day. The class purposely lacks the concept of a time zone or offset. Therefore, the values in LocalDateTime objects are inherently ambiguous. If you say "noon on the 23rd of January 2023", I have no idea if you mean noon in Tokyo, noon in Toulouse, or noon in Toledo — three different moments several hours apart.
👉 LocalDateTime cannot represent a moment.
The equivalent type in standard SQL is TIMESTAMP WITHOUT TIME ZONE.
All this and more has been covered many many times already on Stack Overflow. Search to learn more.

Convert LocalDateTime to LocalDateTime with specific Zone in Java

I need to do a LocalDateTime conversion of a UTC date to another LocalDateTime variable considering a specific timezone tz.
During my research I found many solutions, but they all convert the LocalDateTime to another type, like ZonedDateTime.
I need something like that, but LocalDateTime wont work with ZoneId:
LocalDateTime output = input.getInitDate().of(ZoneId.of(tz))
Considering a -3 timezone:
input: 2019-12-03T18:24:07
output: 2019-12-03T15:24:07
Your Question makes no sense.
You need to understand that LocalDateTime holds nothing but a date and a time-of-day. The class purposely lacks any concept of time zone or offset-from-UTC. So LocalDateTime does not represent a moment. The name can be misleading, as a LocalDateTime is not about any particular locality.
If you want to track a moment in UTC, use Instant.
Instant instant = Instant.now() ; // Capture the current moment in UTC. Always in UTC, by definition.
If you want to track a moment as seen in the wall-clock time used by the people of a particular region (a time zone), use ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montevideo" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
LocalDateTime conversion of a UTC date
Do you mean you have particular date and time in mind as seen at the prime meridian? Or as seen in Iceland which uses UTC as their time zone?
LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 0 ) ; // 3 PM.
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
This ldt object means "3 PM on the 23rd of January this year" somewhere, or anywhere. But that LocalDateTime object does not 3 PM in one particular place. We have no idea if the intention here is 3 PM in Tokyo Japan or 3 PM in Toulouse France or 3 PM in Toledo Ohio US. Those would be three different moments, several hours apart. A LocalDateTime represents none of them, or all of them, whichever way you want to see it, but not any one of them.
To determine a moment from a date and a time-of-day, you need the context of a time zone or offset-from-UTC. In other words the third piece of information, in addition to the date and the time-of-day, we need is "as seen in Paris France" or "as seen in Palmer Station in Antarctica". With such a context, we get either ZonedDateTime or OffsetDateTime, respectively.
ZoneId z = ZoneId.of( "Antarctica/Palmer" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ldt , z ) ; // Giving context of time zone to the date-with-time `LocalDateTime` object. Determines a moment.
To see that same moment in UTC (an offset of zero hours-minutes-seconds), extract an Instant.
Instant instant = zdt.toInstant() ; // Adjust from time zone to UTC.
Time zone versus offset-from-UTC
Considering a -3 timezone:
No, -3 is not a time zone, it is an offset.
The -3 is short for -03:00. Practically speaking, I suggest you avoid abbreviating the offset as some libraries expect a full hours-with-minutes including the colon character, and including the leading zero on single-digit hours or minutes.
The -3 or -03:00 means simply "three hours behind UTC".
A time zone is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region. A time zone has a name in the form of Continent/Region such as Africa/Tunis or Europe/Paris.
See the list of time zones on Wikipedia. Sort by offset column. Notice how around three dozen time zones may today be sharing the offset of -03:00 such as America/Montevideo, Atlantic/Stanley, and Antarctica/Palmer.
Always prefer a time zone to a mere offset. When doing date-time math and adding/subracting spans of time, the results may vary by time zone. Time zones may be using different offsets other than -03:00 on other dates in the past and in the future.
You need to convert it first to ZonedDateTime, change the timezone, and then extract LocalDateTime from that:
ZoneId from = ...;
ZoneId to = ...;
LocalDateTime input = ...;
LocalDateTime output = input.atZone(from).withZoneSameInstant(to).toLocalDateTime();
Try this solution:
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC-3"));
System.out.println(utcZoned.toLocalDateTime());
It gives the output:
2020-02-03T20:55:33.313882
2020-02-03T17:55:33.313882

Java - Adding/appending time start time(00:00:00.000) & end time (23.59.59.999) to date

I'm getting start date as "2016-06-01" and end date as "2016-07-01" (in string format) for searching records in MongoDB. Need pointer/guidance to append start time (00:00:00.000) to start date and maximum time(23.59.59.999) to end date as below in Java using java.util.Date or any others which supported by MongoDB.
Example :
Start Date+with time : 2016-06-01T00:00:00.000
End Date+with time : 2016-07-01T23:59:59.999
You could use the DateTimeFormatter.ISO_LOCAL_DATE_TIME for this. Here is an example that might shed some light on what you are trying to do:
DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String startTime = "T00:00:00.000";
String endTime = "T23:59:59.999";
//here I used the LocalDateTime parser to parse the data+startTime/endTime
LocalDateTime startLocalDateTime = LocalDateTime.parse("2016-07-01"+startTime);
LocalDateTime endLocalDateTime = LocalDateTime.parse("2016-07-01"+endTime );
//with the LocalDateTime, you can then to whatever you want
//as an example, I am parsing it using ISO_LOCAL_DATE_TIME :
String strinStartTime= dtf.format(LocalDateTime.parse("2016-07-22"+startTime));
I hope this helps;
tl;dr
ZoneId zoneId = ZoneId.of( "Europe/Paris" ) ;
LocalDate startDate = LocalDate.of( "2016-06-01" ) ;
ZonedDateTime zdt start = startDate.atStartOfDay( zoneId ) ;
ZonedDateTime zdt stop = startDate.plusMonths(1).atStartOfDay( zoneId ) ;
// Perform database search where ( ( x >= start ) AND ( x < stop ) ) . Notice '>=' versus '<' with no 'equals' on the latter.
If you need strings…
String outputStart = start.toInstant().toString() ; // 2016-05-31T22:00:00Z Paris in the summer is two hours ahead of UTC.
String outputStop = stop.toInstant().toString() ; // 2016-06-30T22:00:00Z
Details
The Answer by ishmaelMakitla is good in that it points to using the java.time classes built into Java 8 and later. But it focuses on strings rather than objects. Also it does not discuss the crucial issue of time zone.
The java.time classes include:
LocalDate for a date-only value with no time-of-day and no time zone.
LocalTime for a time-of-day value without a date and without a time zone.
LocalDate startDate = LocalDate.parse( "2016-06-01" ); // Parsing ISO 8601 standard date format.
LocalTime startTime = LocalTime.MIN; // '00:00'.
Both of those classes can be used in factory methods to instantiate LocalDateTime and other classes.
LocalDateTime ldt = LocalDateTime.of( startDate , startTime );
In code above we used LocalTime.MIN to get 00:00. To directly answer your Question, you can also use LocalTime.MAX in the same way to get 23:59:59.999999999. But I do not recommend doing so. Read below about "Half-Open".
Time zone
Time zone is crucial in determining a date and a time. For any given moment the date and the hour-of-day both vary by time zone. A few minutes after midnight in Paris is a new day while still “yesterday” in Montréal.
The Local… types are not actual moments on the timeline. They represent a vague idea about possible moments. As noted above, the first moment of June 1st in Paris is simultaneously May 31st at 6 PM in Montréal. So before performing your database search you need to assign a time zone to your LocalDateTime. Applying a ZoneId produces a ZonedDateTime object.
Perhaps your date-time was intended to be Paris.
ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ldt.atZone( zoneId );
Or perhaps you intended UTC. This all depends on your business rules, the context in which your app operates. For UTC, we use OffsetDateTime as UTC is not a full time zone but rather a mere offset-from-UTC. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
To get a string as asked for in the Question, extract LocalDate and call toString(). But I do not recommend this as it ignores time zone (read on down below).
String output = odt.toLocalDateTime.toString(); // Not likely to be what you really need.
Best practice in databases is to store the date-time in UTC. I don't know about MongoDB. Be sure to read the doc on how your database driver in Java may be affecting/translating the values you specify.
Start of Day
Be aware that a day does not always start at 00:00:00. In some time zones DST or other anomalies means the day may start at some other time such as 01:00.
The java.time classes will make adjustments as needed in some situations. Be sure to read the class doc so you see if the behavior matches your expectations & needs.
You can ask java.time to find the starting time.
ZonedDateTime zdt = LocalDate.of( "2016-06-01" ).atStartOfDay( zoneId );
Half-Open
Your attempt to determine the end of the day is a problem. That last second is infinitely divisible. Traditional Unix-oriented libraries resolve to whole seconds, the old date-time classes in Java resolve to milliseconds, some databases like Postgres may resolve to microseconds, and java.time and other databases such as H2 resolve to nanoseconds. Do not get in the middle of that.
Generally in date-time programming of a span of time, the best practice is "Half-Open". The beginning of the span is inclusive while the ending is exclusive.
So searching for a month of data in Paris zone means searching for records where the date-time is equal to or later than the start and less than (but not including) the stop.
ZoneId zoneId = ZoneId.of( "Europe/Paris" );
LocalDate startDate = LocalDate.of( "2016-06-01" );
ZonedDateTime zdt start = startDate.atStartOfDay( zoneId );
ZonedDateTime zdt stop = startDate.plusMonths(1).atStartOfDay( zoneId );
// Perform database search where ( ( x >= start ) AND ( x < stop ) ) . Notice '>=' versus '<' with no 'equals' on the latter.
Similarly, the month of records for UTC rather than Paris.
ZoneOffset zoneOffset = ZoneOffset.UTC;
LocalDate startDate = LocalDate.of( "2016-06-01" );
OffsetDateTime start = OffsetDateTime.of( startDate , zoneOffset );
OffsetDateTime stop = OffsetDateTime.plusMonths(1).of( startDate , zoneOffset );
// Perform database search where ( ( x >= start ) AND ( x < stop ) ) . Notice '>=' versus '<' with no 'equals' on the latter.
Using the Half-Open approach consistently throughout your app where handling spans of time will make your code more sensible and easier to understand. You can also train your users to think this way. We all use Half-Open intuitively in situations situations like "Lunch break is from 12:00 to 13:00". We all know this means be back from lunch before the clock strikes 13:00:00.0.
public class DateSample {
public static void main(String[] args) throws ParseException {
String startDate = "2016-06-01";
String endDate = "2016-07-01";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date strDate = formatter.parse(startDate+" 00:00:00.000");
Date enDate = formatter.parse(endDate+" 23:59:59.999");
System.out.println(formatter.format(strDate));
System.out.println(formatter.format(enDate));
}
}
You will get
2016-06-01 00:00:00
2016-07-01 23:59:59
If you are running under jdk 1.8, use LocalDateTime
LocalDateTime is an embedded api of jdk 1.8. You can found explaination here docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html. You can use minus* or plus*, and parse methods

Categories