How to convert UTC and local timezone in Java - java

I am curious about timezone in Java. I want to get UTC time in milliseconds from a device and send to server. Server will convert it to local timezone when it displays time to users. Timezone in my system is Australia/Sydney( UTC + 11:00), and I have got the result below when I tested timezone:
int year = 2014;
int month = 0;
int date = 14;
int hourOfDay = 11;
int minute = 12;
int second = 0;
Calendar c1 = Calendar.getInstance();
c1.set(year, month, date, hourOfDay, minute, second);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss z");
System.out.println(sdf.format(c1.getTime()));
Calendar c2 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c2.set(year, month, date, hourOfDay, minute, second);
System.out.println(sdf.format(c2.getTime()));
output:
14/01/2014 11:12:00 EST
14/01/2014 22:12:00 EST
I thought I could have 13/01/2014 00:12:00 for c2 because UTC time is 11 hours later than mine. Does not Calendar work the way I expect?
Your help would be appreciated.
EDIT
Added z to display timezone. This makes me more confused because Mac says its timezone is (AEDT) Australian Eastern Daylight Time but Java is EST. Anyway still result is different because EST is UTC-5 hours.

UPDATE: This Answer is now out-of-date. The Joda-Time library is now supplanted by the java.time framework built into Java 8 and later. See this new Answer.
Three-Letter Codes
You should avoid using 3 or 4 letter time zone codes such as EST or IST. They are neither standard nor unique.
Use proper time zone names, mostly Continent/CityOrRegion such as America/Montreal or Asia/Kolkata.
Joda-Time
The java.util.Date/Calendar classes are notoriously bad. Avoid using them. Use either Joda-Time or, in Java 8, the new java.time.* classes defined by JSR 310 and inspired by Joda-Time.
Notice how much simpler and more obvious is the Joda-Time code shown below. Joda-Time even knows how to count – January is 1, not 0!
Time Zone
In Joda-Time, a DateTime instance knows its own time zone.
Sydney Australia has a standard time of 10 hours ahead of UTC/GMT, and a Daylight Saving Time (DST) of 11 hours ahead. DST applies to the date specified by the question.
Tip: Don't think like this…
UTC time is 11 hours later than mine
Think like this…
Sydney DST is 11 hours ahead of UTC/GMT.
Date-time work becomes easier and less error-prone if you think, work, and store in UTC/GMT. Only convert to localized date-time for presentation in the user-interface. Think globally, display locally. Your users and your servers can easily move to other time zones, so forget about your own time zone. Always specify a time zone, never assume or rely on default.
Example Code
Here is some example code using Joda-Time 2.3 and Java 8.
// Better to specify a time zone explicitly than rely on default.
// Use time zone names, not 3-letter codes.
// This list is not quite up-to-date (read page for details): http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZone = DateTimeZone.forID("Australia/Sydney");
DateTime dateTime = new DateTime(2014, 1, 14, 11, 12, 0, timeZone);
DateTime dateTimeUtc = dateTime.toDateTime(DateTimeZone.UTC); // Built-in constant for UTC (no time zone offset).
Dump to console…
System.out.println("dateTime: " + dateTime);
System.out.println("dateTimeUtc: " + dateTimeUtc);
When run…
dateTime: 2014-01-14T11:12:00.000+11:00
dateTime in UTC: 2014-01-14T00:12:00.000Z

You probably meant to set the timezone on your formatter, not the Calendar (or in addition the the Calendar, it is not 100% clear what you mean to accomplish)! The timezone used to create the human representation comes from the SimpleDateFormat. All "timezone" information is lost from the Calendar when you convert it back into a java.util.Date by calling getTime().
The code:
Calendar c2 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c2.set(year, month, date, hourOfDay, minute, second);
System.out.println(sdf.format(c2.getTime()));
is printing 14/01/2014 10:12:00 because 11AM UTC displayed in Syndey (the timezone of your formatter) is 10PM! (use HH in the format for 24 hour time)
This would print what it seems like you meant to do:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss z");
System.out.println(sdf.format(c1.getTime()));
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(c1.getTime()));
The concept of 'UTC milliseconds' is meaningless. A quantity of milliseconds is just a fixed point in history, it has no timezone associated with it. We add a timezone to it to convert it into human-readable representations.
edit: Yes, the ambiguity of using 'EST' for both (US) Eastern Time and (Australian) Eastern Time has been a pitfall in Java since forever.

tl;dr
Use modern java.time classes.
ZonedDateTime
.of( 2014 , 1 , 14 , 11 , 12 , 0 , 0 , ZoneId.of( "Australia/Sydney" ) )
.toInstant()
.toEpochMilli()
1389658320000
Going the other direction.
Instant
.ofEpochMilli( 1_389_658_320_000L ) // .toString(): 2014-01-14T00:12:00Z
.atZone(
ZoneId.of( "Australia/Sydney" )
) // .toString(): 2014-01-14T11:12+11:00[Australia/Sydney]
.format(
DateTimeFormatter
.ofPattern (
"dd/MM/uuuu HH:mm:ss z" ,
new Locale( "en" , "AU" )
)
)
14/01/2014 11:12:00 AEDT
java.time
You are using terrible date-time classes that were made obsolete years ago by the adoption of JSR 310 defining the modern java.time classes.
I am curious about timezone in Java.
FYI, an offset-from-UTC is merely a number of hours-minutes-seconds. When we say “UTC” or put a Z at the end of a string, we mean an offset of zero hours-minutes-seconds, for UTC itself.
A time zone is much more. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region. Politicians around the world have an odd penchant for changing the offset of their jurisdiction.
I want to get UTC time in milliseconds from a device and send to server.
For the current moment, use Instant. An Instant internally is the number of whole seconds seconds since the epoch reference of first moment of 1970 UTC, plus a fraction of a second in nanoseconds.
Instant now = Instant.now() ; // Capture current moment in UTC.
long millisecondsSinceEpoch = now.toEpochMilli() ;
Going the other direction.
Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch ) ;
Server will convert it to local timezone …
Specify the time zone desired/expected by the user.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
… when it displays time to users
Automatically localize for the user's language and culture.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine:
The human language for translation of name of day, name of month, and such.
The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.CANADA_FRENCH ; // Or Locale.US, Locale.JAPAN, etc.
DateTimeFormatter f =
DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( l )
;
String output = zdt.format( f );
Timezone in my system is Australia/Sydney( UTC + 11:00)
The current default time zone of your server should be irrelevant to your program. Always specify the desired/expected time zone. Frankly, making optional the time zone (and Locale) argument of the various date-time methods is one of the very few design flaws in java.time framework.
Tip: Generally best to set your servers to UTC as their current default time zone.
By the way, be clear that time zone and locale have nothing to do with one another. You might want Japanese language for displaying a moment as seen in Africa/Tunis time zone.
ZoneID zAuSydney = ZoneId.of( "Australia/Sydney" ) ;
ZonedDateTime zdt = instant.atZone( zAuSydney ) ;
String output = zdt.format(
DateTimeFormatter
.localizedDateTime( FormatStyle.LONG )
.withLocale( new Locale( "en" , "AU" ) ;
) ;
int year = 2014; …
Note that java.time uses sane numbering, unlike the legacy classes. Months are 1-12 for January-December, and weekdays are 1-7 for Monday-Sunday.
LocalDate ld = LocalDate.of( 2014 , 1 , 14 ) ;
LocalTime lt = LocalTime.of( 11 , 12 ) ;
ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
zdt.toString() = 2014-01-14T11:12+11:00[Australia/Sydney]
Generally best to automatically localize for display, as seen above. But if you insist, you can hard-code a formatting pattern.
Locale locale = new Locale ( "en" , "AU" );
ZoneId z = ZoneId.of ( "Australia/Sydney" );
ZonedDateTime zdt = ZonedDateTime.of ( 2014 , 1 , 14 , 11 , 12 , 0 , 0 , z );
zdt.toString(): 2014-01-14T11:12+11:00[Australia/Sydney]
Specify that formatting pattern of yours.
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu HH:mm:ss z" , locale );
String output = zdt.format ( f );
output = 14/01/2014 11:12:00 AEDT
Your Question was interested in a count of milliseconds since epoch of 1970-01-01T00:00:00Z. So adjust from the Australia time zone to UTC. Same moment, same point on the timeline, different wall-clock time.
Instant instant = zdt.toInstant() ; // Adjust from time zone to UTC.
instant.toString(): 2014-01-14T00:12:00Z
Note the difference in hour-of-day between instant and zdt.
I thought I could have 13/01/2014 00:12:00 for c2 because UTC time is 11 hours later than mine.
➥ As you asked for, twelve minutes after 11 AM in Sydney zone is the same moment as twelve minutes after midnight in UTC, because Australia/Sydney on that date is eleven hours ahead of UTC.
Calculate milliseconds since epoch.
long millisecondsSinceEpoch = instant.toEpochMilli() ;

here is the output result you need to check this out
final String time="UTC";
int year = 2014;
int month = 0;
int date = 14;
int hourOfDay = 11;
int minute = 12;
int second = 0;
calendar.set(year, month, date, hourOfDay, minute, second);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz");
System.out.println(sdf.format(calendar.getTime()));
Calendar calendar1=Calendar.getInstance();
Date dat= calendar.getTime();
calendar1.set(year,month,date,hourOfDay,minute,second);
sdf.setTimeZone(TimeZone.getTimeZone(time));
System.out.println(sdf.format(calendar1.getTime()));

Related

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")

java.text.ParseException: Unparseable date: "09:07:31 AM PDT"

I have a field in the response that is coming as time which I want to parse before adding some minutes into it. I have written the below code which results in error.
SimpleDateFormat df = new SimpleDateFormat("HH:MM:ss a SSS");
Date date = df.parse(currentTime);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MINUTE, 10);
here, currentTime is coming in as "09:07:31 AM PDT"
tl;dr
LocalTime // Represent a time-of-day without a date and without a time zone or offset-from-UTC.
.parse(
"09:07:31 AM PDT".substring( 0 , 11 ) , // Remove the senseless `PDT` from the input.
DateTimeFormatter.ofPattern( "hh:mm:ss a" ) // Define a formatting pattern to match our modified input string.
) // Returns a `LocalTime` object.
.toString() // Generates text in standard ISO 8601 format to represent the value of our `LocalTime` object.
09:07:31
Avoid Date & Calendar
You are using terrible date-time classes that were bundled with the earliest versions of Java. These were supplanted years ago by the modern java.time classes defined in JSR 310.
Never use Date, Calendar, SimpleDateFormat, and such.
Date class does not fit
The java.util.Date class represents a moment, a date with time-of-day, as seen in UTC. Your input lacks a date. So your input cannot be represented by this class.
Time-of-day with zone makes no sense
Your input represents a time-of-day with what is a false time zone. The PDT likely stands for "Pacific Daylight Saving Time", to indicate whether Daylight Saving Time (DST) is in effect or not. This is not a true time zone name. Instead a time zone name such as America/Los_Angeles should be used.
At any rate, the combination of a time-of-day with a time zone makes no sense. Without the context of a date, the time zone carries no meaning.
LocalTime
I suggest you extract the time-of-day and ignore the PDT. Take the first 11 characters.
String input = "09:07:31 AM PDT";
String s = input.substring( 0 , 11 ); // Uses annoying zero-based index counting. So asking for first through the eleventh characters requires ( 0 , 11 ).
Define a formatting pattern to match our modified input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "hh:mm:ss a" );
Parse as a LocalTime, a time-of-day without a date and without a time zone or offset-from-UTC.
LocalTime lt = LocalTime.parse( s , f );
lt.toString(): 09:07:31
ZonedDateTime
For fun, let's apply a time zone to your time-of-day, and a date to get a ZonedDateTime.
LocalTime lt = LocalTime.parse( "01:59:00 AM PDT".substring( 0 , 11 ) , DateTimeFormatter.ofPattern( "hh:mm:ss a" ) );
LocalDate ld = LocalDate.of( 2020 , Month.MARCH , 7 );
ZoneId z = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
ZonedDateTime zdtLater = zdt.plusMinutes( 5 );
System.out.println( "zdtLater = " + zdtLater );
We get 2:04 AM.
zdtLater = 2020-03-07T02:04-08:00[America/Los_Angeles]
Change that date to the 8th.
LocalTime lt = LocalTime.parse( "01:59:00 AM PDT".substring( 0 , 11 ) , DateTimeFormatter.ofPattern( "hh:mm:ss a" ) );
LocalDate ld = LocalDate.of( 2020 , Month.MARCH , 8 );
ZoneId z = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
ZonedDateTime zdtLater = zdt.plusMinutes( 5 );
System.out.println( "zdtLater = " + zdtLater );
We get 3:04 AM, not 2:04 AM.
zdtLater = 2020-03-08T03:04-07:00[America/Los_Angeles]
The date is what gives meaning to that time-of-day in a time zone.
Offsets vary over time. That is the meaning of a time zone. A time zone such as America/Los_Angeles is a history of the past, present, and future changes to the offset used by the people in many regions on the west coast of North America. On March 7, 2020 the offset was eight hours behind UTC. On March 8, 2020, the offset was changed to seven hours behind UTC. At the first moment of 2 AM, the clock jumped an hour to 3 AM. The 2 AM hour never happened on the 8th as it did on the 7th.
OffsetTime
The java.time framework does offer the OffsetTime class. This represents a time-of-day with an offset-from-UTC.
This class makes no sense, for the same reasons discussed above. A time-of-day with an offset but no date serves no useful purpose. I presume this was added to java.time merely to match the SQL-standard type TIME WITH TIME ZONE, in parallel with LocalTime matching TIME WITHOUT TIME ZONE. But this TIME WITH TIME ZONE type makes no sense in SQL. This problem is noted by others, not merely my opinion. And this is not the only senseless thing in the SQL standard.
Furthermore, your input carries a time zone (or at least a time zone was intended by the mis-use of PDT), not an offset. An offset is a number of hour-minutes-seconds, nothing more. A time zone is a history of changes in offset, as discussed above.
You need to use the right combination of letters in format, here:
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss aa zzz");
You might also want to look at API docs [1].
Note: Parsing would work if you use the above format, but you will need the date part as well for accurate calculations. Here is an example with the current date of the current timezone of your machine used as the date part.
String recievedTime = "09:07:31 AM PDT";
String currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss aa zzz");
Date date = df.parse(currentDate +" " + recievedTime);
[1] https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html

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

Converting UTC timestamp to local date

So I tried now for about hours to convert a Timestamp to a local date (CEST).
Date date = new Date(stamp*1000);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("CEST"));
String myDate = simpleDateFormat.format(date);
It's not working whatever I tried and looked up in Internet I always get back the UTC time......
for better understanding: stamp is a variable timestamp with type long which I will receive from a service
tl;dr
String output = ZonedDateTime.ofInstant ( Instant.ofEpochSecond ( 1_468_015_200L ) , ZoneId.of ( "Europe/Paris" ) ).toString();
Details
A few issues:
You are not using proper time zone names.
Proper names are in continent/region format.
The 3-4 letter abbreviations so commonly seen in the media such as CEST are not true time zones. Avoid them. They are neither standardized nor unique(!).
You are using old outmoded date-time classes that are poorly designed and confusing. They have been supplanted by the java.time framework.
If by CEST you meant 2 hours ahead of UTC in the summer, then let's take Europe/Paris as an example time zone. Your Question lacks example data, so I'll make up this example.
Apparently your input is a count of whole seconds from the epoch of first moment of 1970 in UTC. That value can be used directly, no need to multiply.
The ZoneId class represents the time zone. An Instant is a point on the timeline in UTC with a resolution up to nanoseconds. A ZonedDateTime is the Instant adjusted into the ZoneId.
ZoneId zoneId = ZoneId.of ( "Europe/Paris" );
long input = 1_468_015_200L; // Whole seconds since start of 1970.
Instant instant = Instant.ofEpochSecond ( input );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
Dump to console.
System.out.println ( "input: " + input + " | instant: " + instant + " | zdt: " + zdt );
input: 1468015200 | instant: 2016-07-08T22:00:00Z | zdt: 2016-07-09T00:00+02:00[Europe/Paris]
Your TimeZone id is likely to be incorrect (well, not recognized by Java). It seems that instead of throwing an exception the TimeZone is evaluated to UTC in that case.
Try this instead:
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("ECT"));
Here is a page giving some information about Java's TimeZone and a list of timezone ids.

Categories