Time zone in Java - java

This may be a very basic question, but i could'nt find any satisfactory answers.Hope my doubts gets clear on stackoverflow.
Q 1. Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
Q 2. Is there any way to get timezone using JavaScript?
Q 3. A timezone is just the representation of time in a particular zone, but actually every zone is at the same time,just representation wise it may be different depending on geographical conditions. - Is this understanding Correct?
possible duplicate link

Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
Create a formatter and set the timezone in there.
Internally, java.util.Date just stores milliseconds since the Epoch in the UTC timezone.
When you use Date.toString() or new SimpleDateFormat() without a timezone, then the default timezone of your VM is used.
So in a sense, Java always converts to your current/default timezone (unless you happen to be in UTC).
Is there any way to get timezone using Java Script?
It depends. You can use getTimezoneOffset() but that gives you only the offset. There is no API to get the client's OSs timezone ID (like UTC, Europe/Berlin, etc.)
A timezone is just the representation of time...
Not really. See above.

Q 1. Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
The modern way is with the java.time classes.
Firstly, do much of your work in UTC. Apply a time zone only where necessary, such as presentation to a user.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
If you have only an offset-from-UTC rather than a time zone, apply a ZoneOffset to get a OffsetDateTime.
ZoneOffset offset = ZoneOffset.ofHours( -4 );
OffsetDateTime odt = instant.atOffset( offset );
A time zone is an offset-from-UTC (a specific number of hours, minutes, and seconds) plus a set of rules for handling anomalies such as Daylight Saving Time (DST). Represent a time zone with a ZoneId object. Specify a proper time zone name. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
Apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
You can apply other time zones to either the Instant or the ZonedDateTime.
ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );
Q 2. Is there any way to get timezone using JavaScript?
The issue of determining a time zone from a web browser has been handled countless times on Stack Overflow already.
So I'll skip this, except to say the upshot: No, not really in a reliable way; When important to know the time zone precisely you must ask the user herself.
Q 3. A timezone is just the representation of time in a particular zone, but actually every zone is at the same time,just representation wise it may be different depending on geographical conditions. - Is this understanding Correct?
No, a time zone is not a date-time moment.
A time zone adds meaningful context to a date-time in the same way that a currency designation adds meaningful context to an amount of money. A date-time without a time zone is just a rough idea of possible moments, not a precise point on the timeline. Noon at Auckland is earlier than noon in Kolkata which is earlier than noon in Paris which is earlier than noon in Montréal Québec.
You can think of it as pseudo-math statement:
Time Zone = ( Offset-from-UTC + set-of-rules-for-anomalies )
An example of an imaginary time zone:
An offset might be “one hour ahead of UTC”, plus
This set of rules: “On this date we will engage DST, on this date we will disengage DST, on this date during World War II we did shift ahead one hour, on this date after World War II we shifted back one hour, on this date our government shifted clocks forward a half-hour to make us distinct from our arch-rival neighbor country, …”.
You can apply a time zone to a point on the timeline. Like looking at art through a lens, it changes your perception but not the artifact itself. Looking at a point on the timeline through the lens of a time zone distorts the time-of-day and possibly the date into that of a particular community’s wall-clock time.
Another pseudo-math equation as a way of thinking about the class representations of a time zone and a moment on the timeline:
ZonedDateTime = Instant + ZoneId
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.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, 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, 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 can answer to your second question and correct the Aaron Digulla very complete response
Is there any way to get timezone using Java Script?
try to use this library, it will return a TimeZone ID with particular limitation (menthioned in the developer's page):
https://bitbucket.org/pellepim/jstimezonedetect

Related

How convert Timestamp to Date

Other system send for us Timestamp in their time zone.If we run that in cloud in other system is +2 hours. Local is good because the server is the same time zone. How can I be sure that the time will always be right?
String TIME_STAMP_FORMAT = "yyyy-MM-dd-HH.mm.ss.SSSSSS";
DateTimeFormatter TIME_STAMP_FORMATTER = DateTimeFormatter.ofPattern(TIME_STAMP_FORMAT, Locale.getDefault());
private static Timestamp parseTimestamp(String dateString) {
try {
return Timestamp.valueOf(LocalDateTime.parse(dateString, TIME_STAMP_FORMATTER));
} catch (DateTimeParseException e) {
log.error("Not able to parse timestamp", e);
}
return null;
}
Date afterParse = parseTimestamp('2018-12-31-12.30.50.000200')
tl;dr
How can I be sure that the time will always be right?
Include an indicator of time zone or offset-from-UTC with your date-time input string.
Use standard ISO 8601 formats when exchanging date-time values.
Use only java.time classes in Java. Never use Date, Timestamp, Calendar, etc.
Tip: Adjust values from other zones to UTC before sending (generally speaking).
If not possible, then here is a workaround. This assumes you know the time zone intended by the sender of this poor data.
LocalDateTime // Represent a date and time-of-day without the context of a time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline. A meaningless value until you assign a zone/offset.
.parse(
"2018-12-31-12.30.50.000200" , // Avoid such custom formats. Use only ISO 8601 when exchanging date-time values textually.
DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) // Define formatting pattern to match youre input.
) // Returns a `LocalDateTime` object.
.atZone( // Give meaning to the `LocalDateTime` object by applying a time zone.
ZoneId.of( "Africa/Tunis" ) // Always specify a time zone with `Continent/Region` name, never the 2-4 character pseudo-zones popularly seen in the media.
) // Returns a `ZonedDateTime` object.
.toInstant() // Adjust from a time zone to UTC by extracting an `Instant` object. Same moment, same point on the timeline, different wall-clock time.
See this code run live at IdeOne.com.
Best to avoid java.util.Date class. But if you must interoperate with old code not yet updated to java.time, you can convert. Call on the new methods added to the old classes such as Date.from( Instant ).
Avoid legacy classes
Never use java.sql.Timestamp nor java.util.Date. All of the date-time classes bundled with the earliest versions of Java are now legacy, per the adoption of JSR 310. Use only the modern java.time classes.
Wrong data type
You are using the wrong data type. To track a moment, a specific point on the timeline, you must have a time zone or offset-from-UTC. The LocalDateTime class exactly the wrong class to use here. That class purposely lacks any concept of zone or offset. So it is the opposite of what you want.
To track a moment, use Instant, OffsetDateTime, or ZonedDateTime.
Where the java.time classes have methods with an optional time zone (ZoneId) or offset-from-UTC (ZoneOffset) argument, consider the argument required. Always pass a zone/offset. Then you never need worry about how the sysadmin is setting the JVM’s current default time zone at runtime.
ZonedDateTime.now( // Capture the current moment as seen through the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Pacific/Auckland" )
)
Or, use Instant which is always in UTC, by definition.
Instant.now() // Capture the current moment in UTC.
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(!).
ISO 8601
Your question is not clear, but it seems you are receiving an input string for a date-time in a custom format. I suggest you educate the people publishing that data about the ISO 8601 standard. This standard defines practical formats for date-time values being exchanged between systems textually.
The java.time classes use the ISO 8601 formats by default when parsing/generating strings.
Workaround
If the data publisher is sending you values such as 2018-12-31-12.30.50.000200 in order to communicate a moment, they have failed. A date and time-of-day without a zone or offset is useless, like communicating an amount of money without indicating a currency.
Do you know for certain the time zone that was implicitly assumed by the sender of this faulty data input? If so, apply it, as a clumsy stop-gap measure for their poor practice.
First parse your input as a LocalDateTime given that it lacks any indicator of zone/offset.
String input = "2018-12-31-12.30.50.000200" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Apply a ZoneId to get a ZonedDateTime object, thereby adjusting to view the moment through the wall-clock time used by the people of that particular region.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( ldt ) ;
Generally best to work with moments in UTC, unless you have a specific reason to use a time zone (such as presentation to user). So extract an Instant from your ZonedDateTime.
Instant instant = zdt.toInstant() ;
The Z at the end of an ISO 8601 compliant string means UTC, and is pronounced “Zulu”.
See this code run live at IdeOne.com.
input: 2018-12-31-12.30.50.000200
ldt: 2018-12-31T12:30:50.000200
zdt: 2018-12-31T12:30:50.000200+09:00[Asia/Tokyo]
instant: 2018-12-31T03:30:50.000200Z
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.
Just a small supplement to Basil Bourque’s clever and very informative answer.
I know the date is in CET timezone.
I am sorry, this is not enough. Central European Time (CET) is the common term for quite many European and African(!) time zones the details of which differ. The European ones are generally at offset +01:00 during standard time and at +02:00 during summer (known as Central European Summer Time or CEST). The African ones are at +01:00 all year. For past dates, just a few decades back, some zones used summer time (DST), others didn’t, some were at +00:00, +01:00 or +02:00, and further back in history many other offsets were used, generally not whole hours.
The future is even worse! It has been suggested that the European Union abandons summer time and leaves it to each member state whether they will use permanent standard time or permanent summer time, avoiding the time adjustments in spring and autumn. There is a power struggle going on about this, so we don’t know whether it will happen, nor what each member state chooses. So even if you could tell me the exact time zone of your string from the other system (for example, Europe/Sarajevo), no one knows yet whether 2019-11-01-00.30.50.000200 — less than 7 months from now — will be at offset +01:00 or +02:00.
Link: European MPs vote to end summer time clock changes on BBC News.

Recommended use for Joda-Time's DateMidnight

The javdoc for LocalDate#toDateMidnight reads as follows:
As from v1.5, you are recommended to avoid DateMidnight and use
toDateTimeAtStartOfDay() instead because of the exception detailed
below.
This method will throw an exception if the default time zone switches
to Daylight Savings Time at midnight and this LocalDate represents
that switchover date. The problem is that there is no such time as
midnight on the required date, and as such an exception is thrown.
The fact that midnight does not exist in certain time zones seems like reason enough to avoid using DateMidnight entirely (assuming your code is not using a fixed time zone that is known not to have this DST situation and will never need to use different time zones in the future).
However, DateMidnight is not deprecated and there is no similar recommendation or warning in the javadoc for the DateMidnight class itself. Furthermore, the DateMidnight constructor happily accepts an instant and time zone such that midnight does not exist on the given day, rather than throwing an IllegalArgumentException like LocalDate#toDateMidnight. The resulting DateMidnight behaves like a DateTime with time at start of day.
When midnight does not exist on a given day, why does LocalDate#toDateMidnight throw an exception while the DateMidnight constructor does not? What is the recommended use case for DateMidnight if any?
There is no good reason to use DateMidnight. LocalDate is the better option. Thats because midnight does not occur once a year in certain time-zones, completely messing up the usability of the class, and creating bugs in applications.
The constructor was fixed to avoid the worst problem, however seeing a DateMidnight object with the internal millisecond value pointing at 01:00 isn't exactly great.
new DateTime().withTimeAtStartOfDay() is recommended.
Or better use the LocalDate method toDateTimeAtStartOfDay directly to bypass creation of DateTime object (in relation to answer above).
new LocalDate().toDateTimeAtStartOfDay( myDateTimeZone )
tl;dr
Use java.time classes, specifically LocalDate::atStartOfDay instead of the slippery idea of “midnight”.
ZoneId z = ZoneId.of( "America/Montreal" ); // A time zone.
ZonedDateTime todayStart = LocalDate.now( z ).atStartOfDay( z ); // Produces a LocalDate (a whole day without time zone), then transforms into a `ZonedDateTime` (a moment on the timeline)
java.time
Since the Joda-Time project is now in maintenance mode, and the team advises migration to the java.time classes, I will add example using java.time.
If you want to represent the entire day as a whole, use the LocalDate class. The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );
As discussed on this page, trying to pinpoint the end of the day is poor practice. For one thing, you have the problem of an infinitely divisible fraction for that last second of the day. Do you resolve to milliseconds, microseconds, nanoseconds, or something else, as all of these are in common use? Instead use the first moment of the new day.
Let java.time determine the wall-clock time of that first moment of the day. Do not assume the time will be 00:00:00 as anomalies such as Daylight Saving Time (DST) may mean the first moment is a time such as 01:00:00. Such DST adjustments are currently use in time zones of multiple countries.
So, to get a moment, an actual point on the timeline, for the start of the day call LocalDate::atStartOfDay. Notice this is a shorter version of the method name than used in Joda-Time’s withTimeAtStartOfDay method. Specify the desired/expected time zone in a ZoneId to produce a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = today.atStartOfDay( z );
Half-Open
So how to represent a span of time? If I want to pinpoint the the beginning and ending of this single day, how do I do that while also following this advice? The solution commonly used in date-time work is the Half-Open approach. In this approach, the beginning of the span is inclusive while the ending is exclusive. So “today” means starting with the first moment of the day and running all the way up to, but not including, the first moment of the following day.
ZonedDateTime zdtStartToday = LocalDate.now( z ).atStartOfDay( z );
ZonedDateTime zdtStartTomorrow = zdtStartToday.plusDays( 1 );
By the way, the ThreeTen-Extra project has a handy Interval class for such spans of time.
Interval todayInterval = Interval.of(
zdtStartToday.toInstant() ,
zdtStartTomorrow.toInstant()
)
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.
Look at the exception i had in my code
Illegal instant due to time zone offset transition (daylight savings time 'gap'): 2015-03-27T00:00:00.000 (Asia/Amman)
org.joda.time.IllegalInstantException: Illegal instant due to time zone offset transition (daylight savings time 'gap'): 2015-03-27T00:00:00.000 (Asia/Amman)
Now i solved it by using
LocalDate currentDate=new LocalDate();
someMethodSetsTheDate(currentDate.toDateTimeAtStartOfDay().toDate());
Instead of
someMethodSetsTheDate(new DateMidnight(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth()).toDate());
Now my recommendation is to use
.toDateTimeAtStartOfDay()
to avoid similar exceptions .
Please Feel Free To Edit My Answer Thanks
Here a more simple solution that will check if the dateTime occurs at midnight local time
private boolean isAtMidnight(org.joda.time.DateTime dateTime) {
return dateTime.toLocalDateTime().getMillisOfDay() == 0;
}

Java Date and time

I am making a change to some code which runs on a unix box. It sets the time for a field in a database based on the current date and time for London.
The methods I am using are as follows;
private static Date getCurrentTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS");
format.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Calendar cal = Calendar.getInstance();
Date currentDate = cal.getTime();
try {
return format.parse(format.format(currentDate));
} catch (ParseException e) {
log.error("Error occured while parsing date-->" + e.getMessage());
}
return new Date();
}
private String getStringFromDate(Date date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS");
return sdf.format(date);
}
When the message is processed by the java app on the production unix box (which is set to north america time as thats where it is hosted) then when it is inserted into the database it is an hour behind (not being set to BST).
If I run the same code in Eclipse on my desktop, I get the correct time in the database.
I am unsure what might be causing this issue and was hoping someone might be able to help.
Thanks
edit*** at second glance, even the log files on the unix box are an hour behind so on that basis i assume its unix that is causing the issue opposed to my code.
A Date instance is always in UTC (or, it should be unless you've done something wrong). you should store your dates in the db in UTC and convert them to whatever timezone you desire when presenting them to the user. anything else is just asking for trouble.
your code which formats and then parses the Date instance in the same TimeZone is just meaningless.
tl;dr
A Date (and Instant) are always in UTC by definition. So no need to futz with time zone.
Instant.now() // Capture current moment in UTC.
Or, if you must use the troublesome legacy class Date:
java.util.Date.from( Instant.now() ) // Avoid the legacy classes whenever possible. When required, you can convert back-and-forth via new methods added to the old classes as seen here.
Always specify time zone
Never rely on the current default time zone of either your host OS or your JVM. That default value is out of your control and can change at any moment during runtime.
Instead:
Always use the java.time classes rather than the troublesome old legacy classes seen in your code.
Always specify your desired/expected time zone as an optional argument to the various java.time methods rather than rely implicitly on the JVM’s current default.
java.time
You appear to be trying to get the current moment as a java.util.Date object. That legacy class represents a value in UTC, so the time zone is irrelevant.
Instant
The modern replacement for that class is java.time.Instant. 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).
Capturing the current moment is simple: Instant.now.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
If you must have Date to inter-operate with old code not yet updated to java.time, convert by calling new methods added to the old classes.
java.util.Date javaUtilDate = java.util.Date.from( instant ) ;
Either way, be very aware that both a Date and an Instant represent a point on the timeline in UTC, always UTC.
UTC versus London Time
Also, be aware that UTC is not London time, a common misconception given that UTC/GMT is tracked from a point at the Royal Observatory, Greenwich. Actually, London has a history of anomalies in its offset-from-UTC, including the adoption of Daylight Saving Time (DST).
To get London time, assign a ZoneId to get a ZonedDateTime.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-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( "Europe/London" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, but viewed with a different wall-clock time used by the people of a particular region (time zone).
Generally, best practice is to keep your servers in UTC, and to do as much of your business logic, storage, and exchange of date-time values in UTC. Use a zoned value such as London time only when required either by business logic or presentation to user.
Notice in the code seen above that the current default time zone of any computer or JVM is irrelevant. A change in that default has no effect on your code.
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, 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.

Why date is changing with same number of milliseconds on different time zones?

We know that getTime method of java.util.Date returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
I noticed a weird situation as below;
System time zone is:(UTC+02:00) Istanbul
Date currentDate = new Date();
System.out.println(currentDate .getTime());
System.out.println(currentDate);
Java ConsoleOutput:
1360753217219
Wed Feb 13 13:00:17 VET 2013
Then my javascript plugin is using this long object like below;
Javascript:
console.log(new Date(1360753217219));
Browser ConsoleOutput:
Date {Wed Feb 13 2013 13:00:17 GMT+0200 (Turkey Standard Time)}
Thats all ok, however! After change my local time zone as (UTC-04:30) Caracas, situation and hour is changing as below with same number of milliseconds;
Javascript:
console.log(new Date(1360753217219));
Browser ConsoleOutput:
Date {Wed Feb 13 2013 06:30:17 GMT-0430 (Venezuela Standard Time)}
Can someone explain this? Is that js bug? Or more importantly, how should I handle this on java side, to get same date with same number of miliseconds for different time zones on js side?
Thanks!
The milliseconds are time zone agnostic. Time is measured as an absolute since Jan 1, 1970 GMT. So, the idea is that you get the milliseconds and then work out what the local time for a given time zone is after the fact. If you think about it, it makes sense. The number of milliseconds that have passed since 1970 are the same no matter where you are.
It gets a bit confusing but do NOT noodle around with the milliseconds in order to adjust for time zones. Every Date library has mechanisms to translate a millisecond stamp into a time zone specific local time.
So if your specific question is how to communicate the date effectively between the server and the client (what languages you're using is not important), the answer is it's perfectly safe to pass milliseconds back and forth and work out on either side what global specific time you're talking about, if that's important to the context of what you're doing with that time.
not a bug, that's just how time zones work.
if you call someone in Venezuela right now and ask him what time it is, he'll tell you it's
6.5 (according to your example) hours earlier than the time in turkey.
as you mentioned, the number you're dealing with represents the number of milliseconds since 1970, 00:00:00 GMT, in Caracas at that very same second, the time was 31.12.1969 19:30 GMT-0430
so, however many seconds later, the time in Venezuela will still be 4:30 hours earlier compared to GMT.
you can't get the exact same date in different time zones if you use the same input (milliseconds) because that would simply be wrong.
if you want to get the same result, you could add the difference in timezones (6.5 hours in this case) to the output. following Dr.Dredel's advice, you probably shouldn't mess with the milliseconds.
tl;dr
Instant.ofEpochMilli( 1_360_753_217_219L ) // UTC
2013-02-13T11:00:17.219Z
Instant.ofEpochMilli( 1_360_753_217_219L )
.atZone( ZoneId.of( "Europe/Istanbul" ) ) // Same moment, two hours *ahead* of UTC.
2013-02-13T13:00:17.219+02:00[Europe/Istanbul]
Instant.ofEpochMilli( 1_360_753_217_219L )
.atZone( ZoneId.of( "America/Caracas" ) ) // Same moment, four-and-a-half hours *behind* UTC.
2013-02-13T06:30:17.219-04:30[America/Caracas]
Using java.time
You are using troublesome old date-time classes bundled with the earliest versions of Java. They are now legacy, supplanted by the java.time classes, the best date-time library on any platform.
Start with your number of milliseconds since an epoch reference date of the beginning of 1970 in UTC (1970-01-01T00:00:00Z). Others point out that you may not grasp that an epoch reference date has a time zone, and here with this epoch that zone is UTC, an offset of zero hours. All other offsets are measured against this one, a number of hours and minutes ahead of UTC or behind UTC.
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).
long input = 1_360_753_217_219L ;
Instant instant = Instant.ofEpochMilli( input ) ;
instant.toString(): 2013-02-13T11:00:17.219Z
If you want to see that same moment through the lens of a particular region’s wall-clock time, apply a time zone.
A time zone is a history of past, present, and future changes to the offset in use by a particular region.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId zEurope_Istanbul = ZoneId.of( "Europe/Istanbul" ) ;
ZonedDateTime zdtEurope_Istanbul = instant.atZone( zEurope_Istanbul ) ;
zdtEurope_Istanbul.toString(): 2013-02-13T13:00:17.219+02:00[Europe/Istanbul]
You can apply another time zone.
ZoneId zAmerica_Caracas = ZoneId.of( "America/Caracas" ) ;
ZonedDateTime zdtAmerica_Caracas = zdtEurope_Istanbul.withZoneSameInstant( zAmerica_Caracas ) ;
zdtAmerica_Caracas.toString(): 2013-02-13T06:30:17.219-04:30[America/Caracas]
See this code live at IdeOne.com.
These three objects, instant & zdtEurope_Istanbul & zdtAmerica_Caracas, all represent the very same simultaneous moment, the same point on the timeline.
Your count-from-epoch represents 11 AM in UTC. Istanbul is two hours ahead of UTC, so the time-of-day there at the same moment is two hours after 11 AM, 1 PM (13:00). Venezuela is four and a half hours behind UTC, so the time-of-day there at the same moment is 6:30 AM. These all make sense, all the same moment but different wall-clock time.
ISO 8601
Do not use a count-from-epoch for exchanging or storing date-time values. That is error-prone, being impposible to read meaningfully by a human, and ambiguous as there are at least a couple dozen epoch reference dates in use by various software systems and at different granularities (whole seconds, milliseconds, microseconds, nanoseconds, etc.).
When passing date-time values outside your JVM, use the standard ISO 8601 formats for textual representation. The java.time classes use the standard formats by default when parsing/generating strings. You can see those formats in this Answer’s example code.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, 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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.

Joda-Time: DateTime, DateMidnight and LocalDate usage

Joda-Time library includes different datetime classes
DateTime - Immutable replacement
for JDK Calendar DateMidnight
- Immutable class representing a date where the time is forced to
midnight LocalDateTime -
Immutable class representing a local
date and time (no time zone)
I'm wondering how are you using these classes in your Layered Applications.
I see advantages in having almost all the Interfaces using LocalDateTime (at the Service Layer at least) so that my Application doesn't have to manage Timezones and can safely assume Times always in UTC. My app could then use DateTime to manage Timezones at the very beginning of the Execution's Flow.
I'm also wondering in which scenario can DateMidnight be useful.
I see advantages in having almost all
the Interfaces using LocalDateTime (at
the Service Layer at least) so that my
Application doesn't have to manage
Timezones and can safely assume Times always in UTC.
I'm not sure I understand your line of thinking here. LocalDateTime and DateTime represent two quite different concepts. It's not the case that a LocalDateTime has some implicit UTC timezone: it actually has no timezone (internally it may be represented as a DateTime with UTC timezone, but it's just a implementation detail, it does not matter to the programmer who uses it).
You can see in the API docs that, while a DateTime is a "Instant" (a point in the world time line, a physical concept), a LocalDateTime is NOT such a thing. The LocalDateTime is actually a Partial, (a "civil" concept), in a different class hierarchy. The classes names might -unfortunately- make you think that LocalDateTime is some specialization of DateTime: well, it isn't.
A LocalDateTime should be regarded as a pair {Date (Y/M/D) ; Time (hh:mm:ss.msec)}, a bunch of numbers which corresponds to the "civil" standard representation of time-related data. If we are given a LocalDateTime, we cannot convert it directly to a DateTime, we need to specify a timezone; and that conversion takes we to another kind of entity. (An analogy: Strings and byte streams in Java: to convert between them you must specify a charset encoding, because they are conceptually different things)
When to use one or the other in the application... it's sometimes arguable, but frequently is clear enough, once the Jodatime concepts are understood. And IMO is not much related to "layers", perhaps more to use cases or scenarios.
A non-trivial -borderline- example: You work at Google, programming the Calendar. You must let the user manage (add, see, modify) an event which includes a date-time (lets ignore recurrent events), say "I have an appointement with my doctor on 2019-July-3 at 10:00 am". What is the time-date entity to use in the software layer (for this usecase)? I'd say: a LocalDateTime. Because the user is not really dealing with a physical point in time, but with a civil time: the date and time that displays the clock in his wrist or in his home. He does not even think of timezones (lets ignore the special case of a user who is traveling around the world...) Then, in the bussiness and presentation layer, a LocalDateTime seems the right entity.
But suppose that you must also code a different scenario: a reminder. When the Google internal scheduler detects that the event stored by the user is N minutes in the future from now, it must send him a reminder. Here, "N minutes from now" is a totally "physical" concept of time, so here the "business layer" would deal with a DateTime. There are several alternatives, for example: the event was stored in the DB as a LocalDateTime (ie. just time and date without timezone - one frequently uses a UTC timestamp to represent that, but this an implementation detail). In this scenario (only in this) we must load it as a DateTime, we convert it using a Timezone, probably from the user's profile.
The Answer by leonbloy is correct and vitally important. I am merely translating to the java.time classes that replace the Joda-Time project.
java.time
Specific moment
For a specific moment on the timeline:
Always in UTC is represented by Instant.
Assigned an offset-from-UTC is represented by OffsetDateTime.
Assign a full time zone rather than mere offset is represented by ZonedDateTime.
These all replace the Instant & DateTime class in Joda-Time. These java.time classes all have a resolution of nanoseconds versus the milliseconds used by Joda-Time.
Midnight versus Start-of-day
For midnight, the Joda-Time project concluded “midnight” is a vague and unproductive concept. The midnight-related classes and midnights were all deprecated in later versions of Joda-Time, replaced with the practical concept of “first moment of the day”.
The java.time classes took the same lesson, using a "first moment of the day" approach. Look for atStartOfDay methods on java.time classes such as LocalDate.
Never assume a day starts at 00:00. Anomalies such as Daylight Saving Time (DST) mean the day may start at other times such as 01:00.
ZonedDateTime zdt =
LocalDate.of( 2017 , Month.MARCH , 12 ) // Instantiate a date-only value without time zone.
.atStartOfDay( ZoneId.of( "America/Havana" ) ) ; // Cuba jumps from 00:00 to 01:00 on Spring DST cut-over.
For example, see how Cuba starts the day at 1 AM on their Spring DST cut-over.
zdt: 2017-03-12T01:00-04:00[America/Havana]
Unzoned
For representing the vague idea of possible moments over a range of about 26-27 hours but not an actual moment on the timeline, use LocalDateTime. This class purposely lacks any offset-from-UTC or time zone.
LocalDateTime ldt = LocalDateTime.of( 2017 , Month.JANUARY , 23 , 1 , 2 , 3 , 0 ) ;
If your business context implies a specific time zone, you can apply it to get a ZonedDateTime.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Determine a specific point on timeline by providing the context of a time zone.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, 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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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

Resources