Is it possible to get a TimeZone ID from a certain TimeStamp ? If it is please explain by a simple code.
private String getDate(long timeStamp) {DateFormat objFormatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
TimeZone timeZone = TimeZone.getTimeZone("GMT+4:30");
//Instead of the Above code I want to get the TimeZone ID from my timeStamp objFormatter.setTimeZone(timeZone);
Calendar objCalendar =
Calendar.getInstance(timeZone);
objCalendar.setTimeInMillis(timeStamp * 1000);
String result = objFormatter.format(objCalendar.getTime());
objCalendar.clear();
return result;
}
tl;dr
Impossible to derive offset/zone from a count-from-epoch-in-UTC. But you can adjust into a zone.
Instant.ofEpochSecond( yourCount )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
Avoid count-from-epoch
Firstly, avoid using a count-from-epoch number to track date-time values. Do you mean a count of whole seconds, milliseconds, microseconds, nanoseconds, or something else? Do you mean the Unix/Java epoch of 1970-01-01T00:00:00Z or one of the couple dozen other epochs in use by many computer systems?
Apparently you have whole seconds, and I'll assume the Unix/Java epoch.
Impossible to get zone from count-from-epoch
You cannot “ get a TimeZone ID from a certain TimeStamp”, that is impossible. Your count-from-epoch was made while accounting for a certain time zone, usually UTC. If must know that intended zone used in creating that count-from-epoch, it cannot be deduced.
Perhaps your goal is actually adjusting this count-from-epoch into a date-time for a particular region’s time zone. Read on.
java.time
Avoid the troublesome old date-time classes such as Date & Calendar now supplanted by the java.time classes.
Convert your count-from-epoch into a point on the timeline in UTC.
Instant instant = Instant.ofEpochSecond( yourCount ) ;
Assign your desired time zone.
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( "Asia/Kabul" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
See this code run live at IdeOne.com.
Notice the 4.5 hour difference, changing from 02:40 to 07:10, appropriate for time in Kabul. This is the same moment, the same point on the time zone, but viewed through the lens of a different region’s wall-clock time.
input: 1500000000
instant: 2017-07-14T02:40:00Z
zdt: 2017-07-14T07:10+04:30[Asia/Kabul]
I would like to answer this question based on the definition of each terminology.
What is timestamp?
Timestamp or Unix Timestamp is the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970,minus the number of leap seconds that have taken place since then. Wikipedia
Wath is Time Zone?
A time zone is a region of the earth where the same standard time is used. Each time zone is described by an identifier and usually has the format region/city (Asia/Tokyo) and an offset from Greenwich/UTC time. For example, the offset for Tokyo is +09:00. Time Zone Oracle Doc
Regarding to both definitions there is no way to get a region of the earth based on a number of seconds (time), it is imperative to know from what region of the earth the time comes from.
Related
I am trying to understand LocalDate and LocalDateTime. Since they do not carry zone info, how does it work for now() on two different time zone.
Example:
Server 1(EST time zone):
LocalDateTime.now() -> 2020-04-06T23:00:00.040
LocalDate.now(). -> 2020-04-06
Server 2(UTC time zone):
LocalDateTime.now() -> What would be the value?
LocalDate.now(). -> What would be the value? (Note in EST, time it executed was 11 PM)
Also,
If I convert below date string to LocalDateTime and then toLocalDate, what would be the outcome?
2020-04-06T23:00:00.000
Offsets vary over time
On April 6, 2020, most time zones on the east coast of North America such as America/Montreal and America/New_York use an offset of four hours behind UTC.
So, in those zones 11 PM on 2020-04-06 is simultaneously 3 AM on the 7th in UTC. Add four hours to 2020-04-06T23:00 to get 2020-04-07T03:00. Adding four hours brings us from the wall-clock time used in America/Port-au-Prince and America/Nassau to UTC.
The offset used by the time zones mentioned above are four hours behind UTC only half the year. The politicians in those locations have decided to observe Daylight Saving Time (DST) for about half the year. So half the year they jump their clocks ahead an hour for an offset-from-UTC of -04:00, and later in the year they fall back an hour for an offset-from-UTC of -05:00. For example, earlier in the year 11 PM in America/New_York would be 04:00 in UTC rather than the 03:00 time seen in April.
Standard time, in January, is five hours behind UTC. So, 11 PM plus five hours is 4 AM next day.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( 2020 , 1 , 6 , 23 , 0 , 0 , 0 , zNewYork ) ;
Instant instant = zdt.toInstant() ; // 2020-01-07T04:00Z
Daylight Saving Time, in April, is four hours behind UTC. So, 11 PM plus four hours is 3 AM next day.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( 2020 , 4 , 6 , 23 , 0 , 0 , 0 , zNewYork ) ;
Instant instant = zdt.toInstant() ; // 2020-04-07T03:00Z
By the way, DST is only one of many reasons politicians have for changing the offset used by the time zone(s) of their jurisdiction. Politicians around the world have shown a penchant for changing their offsets surprisingly often. Your programming should always expect a time zone to change its offset. Just because your particular zone of concern does not currently observe DST does not mean the offset will never change.
As for parsing 2020-04-06T23:00:00.000 as a LocalDateTime, you will get 2020-04-06T23:00:00.000. Ignoring time zones is the entire point of LocalDateTime. So no adjustments are made.
You may be thinking of LocalDateTime as representing a particular locality. But, no, it represents any locality or all localities. But never any one particular locality. For a particular locality, use ZonedDateTime.
Pseudo time zones
Another point: EST is not a time zone. Such 2-4 letter letter codes are not real time zones, are not standardized, and are not even unique. For example, by EST, did you mean Australian Eastern Standard Time or North American Eastern Standard Time? Is CST Central Standard Time or China Standard Time? Avoid these pseudo-zones in your date-time-handling.
And you happened to use the wrong pseudo-code. On April 6 2020, most of those east coast time zones are observing Daylight Saving Time (DST). So they would be considered to be in “EDT” rather than “EST”. Avoid the problem by specifying the real time zone name.
Real time zones are named using Continent/Region format. See Wikipedia for a list of real time zones.
Never call LocalDateTime.now
I cannot imagine a case where calling LocalDateTime.now would be the right thing to do. Determining the current moment requires a time zone (or offset). And LocalDateTime by definition has no time zone or offset. When a programmer writes LocalDateTime.now, you can bet they do not fully understand the necessary concepts.
When you call LocalDateTime.now, the JVM’s current default time zone is implicitly used to capture the current time as seen by the people in the region of that zone. And then the fact of that time zone is deleted.
This:
LocalDateTime.now()
…is the same as this:
LocalDateDate.now( ZoneId.systemDefault() )
…which is the same as getting the current moment as seen in a particular time zone, followed by removing the time zone information:
ZonedDateTime.now( ZoneId.systemDefault() ).toLocalDateTime()
For more code examples demonstrating LocalDateTime.now, see the correct Answer by Ole V.V.
Where to use LocalDateTime
If LocalDateTime is not appropriate for getting the current moment, and is not appropriate for tracking any moment, what is the appropriate use for this class? Three things: representing any locality, representing all localities, and booking future appointments.
Any locality would be something like stating when Christmas starts. This year Christmas starts at 2020-12-25T00:00 wherever you are in the world. Of course this means Christmas starts first in Kiribati after midnight, later in Japan after midnight, even later in Tunisia after midnight, and still later in Chicago after midnight.
All localities would be something like stating our company policy that lunch breaks at all our factories in Delhi, Düsseldorf, and Detroit are scheduled for 12:30. So on April 6 2020, the break will be at 2020-04-06T12:30:00. This break will occur first in Delhi, several hours later in Düsseldorf, and even more hours later in Detroit.
Booking future appointments where you intend to keep the same time-of-day regardless of changes to the time zone’s offset must recorded without the offset. If your next dental appointments is in six months at 3 PM, we want to record the 3 PM without regard for the offset. If the offset were to be changed by politicians, we still want the appointment to start when the clock strikes three on that date in that zone.
Set the appointment.
LocalDateTime appointment = LocalDateTime.of( 2021 , 1 , 23 , 15 , 0 , 0 , 0 ) ;
Determine a moment for producing a calendar. Every time you do this, you may get a different result if the politicians have changed the rules of this time zone.
ZoneId z = ZoneId.of ( "America/Panama" ) ;
ZonedDateTime dueToArrive = appointment.atZone( z ) ;
LocalDate
As for LocalDate, we saw in the examples above that the date depends on time zone. For any given moment, the date varies around the globe by time zone. It may be “tomorrow” in Tokyo Japan while still “yesterday” in Montréal Québec Canada.
So, you must specify a time zone when asking for the current date.
LocalDate ld = LocalDate.now( ZoneId.of( "Asia/Kolkata" ) ) ;
If you omit the time zone, the JVM’s current default time zone is implicitly applied. So LocalDate.now() becomes LocalDate.now( ZoneId.systemDefault() ). I recommend specifying your desired/expected zone explicitly, rather than rely on implicit default.
Server time zone
You said:
server which runs in EST vs UTC
FYI, servers should generally be set to UTC. Most of your thinking, programming, logging, and so on should be done in UTC. Learn to think of UTC as The One True Time, with all other zones but mere variations.
As a programmer, you should never rely on the default time zone. That is far outside your control. That default can be changed so easily by the user or sysadmin. Furthermore, any code in any thread of any app within the JVM can instantly change the JVM’s current default time with a call to TimeZone.setDefault. So even during execution of your app, the default can be changed at any moment.
To prevent confusion pass explicit time zone to now() and see for yourself:
ZoneId easternTime = ZoneId.of("America/Montreal");
System.out.println(LocalDateTime.now(easternTime));
System.out.println(LocalDateTime.now(ZoneOffset.UTC));
System.out.println(LocalDate.now(easternTime));
System.out.println(LocalDate.now(ZoneOffset.UTC));
Output when I ran just now:
2020-04-06T09:56:17.381558
2020-04-06T13:56:17.385215
2020-04-06
2020-04-06
While you are correct that LocalDateTime and LocalDate don’t contain any time zone information, their now methods do use time zones. Either the one passed to them, or if you use the no-arg variant, the default time zone of the JVM.
You also asked:
Also, If I convert below date string to LocalDateTime and then
toLocalDate, what would be the outcome?
2020-04-06T23:00:00.000
Why not try out that too?
LocalDateTime ldt = LocalDateTime.parse("2020-04-06T23:00:00.000");
System.out.println(ldt);
LocalDate ld = ldt.toLocalDate();
System.out.println(ld);
2020-04-06T23:00
2020-04-06
Converting from LocalDateTime to LocalDate involves no time zone (or UTC offset) whatsoever. The time part is simply discarded and the date part kept unchanged.
I Have UTC String with a format (HH: mm: ss) and I need to convert the String value into device Time in the same format (HH: mm: ss) and also adding Day saving time if available I Have Tried to convert the UTC String to device time by this code but I am getting a 1 hour delay due to (day saving time).
String utcTimeString = "12:15:00"
SimpleDateFormat formatter = new SimpleDateFormat("HH: mm: ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = formatter.parse(utcTimeString);
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH: mm: ss");
dateFormatter.setTimeZone(TimeZone.getDefault());
utcDateString = dateFormatter.format(value);
My Time Zone is GMT-4
Expected Output: 08:15:00;
Given Output: 07:15:00;
The Answer by deHaar is generally correct, and wisely makes use of the modern java.time classes. However, I would use a slightly different approach.
tl;dr
OffsetDateTime.of( // Represent a moment as a date, a time-of-day, and an offset-from-UTC.
LocalDate.now( ZoneOffset.UTC ) , // Current date as seen right now in UTC. Beware: For any given moment, the date varies around the globe by zone.
LocalTime.parse( "12:15:00" ) , // Your specified time-of-day.
ZoneOffset.UTC // An offset of zero hours-minutes-seconds, for UTC itself.
) // Returns an `OffsetDateTime` object.
.atZoneSameInstant( // Adjust from UTC to a time zone. Same moment, different wall-clock-time.
ZoneId.of( "America/Port_of_Spain" ) ; // One of the many time zones that are behind UTC by four hours on that date.
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Extract the time-of-day only, leaving behind the date and the zone.
Time zone
My Time Zone is GMT-4
Nope. That is not a time zone.
The value GMT-4 represents merely an offset-from-UTC. A number of hours-minutes-seconds ahead or behind the UTC baseline.
A time zone is much more. A time zone has a name, and represents the history of past, present, and future changes the offset used by the people of a particular region. Therefore, a time zone is always preferable to a mere offset.
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( "Africa/Casablanca" ) ;
If your time zone is currently four hours behind UTC, you must be in a time zone such as America/Aruba, America/Puerto_Rico, America/Manaus, America/Martinique, etc.
ZoneId z = ZoneId.of( "America/Martinique" ) ;
UTC
I Have UTC String with a format (HH: mm: ss)
Nope.
A value such as "12:15:00" cannot be said to be a value in UTC. Without a date, that value has no real meaning. A moment consists of three parts:
a date,
a time-of-day, and
an offset/zone.
Saying "noon in UTC" only gives us 2 of the 3 parts. The date is missing.
Today… what a concept
Perhaps you want to apply that time-of-day to the current date as seen in UTC.
LocalDate todayUTC = LocalDate.now( ZoneOffset.UTC ) ;
Just keep in mind that for any given moment the date varies around the globe by zone. At this very moment, the date is “tomorrow“ in Tokyo Japan while still being “yesterday” in Toledo Ohio US.
OffsetDateTime
Combine all three into a OffsetDateTime object: date, time-of-day, and offset/zone.
LocalTime localTime = LocalTime.parse( "12:15:00" ) ;
OffsetDateTime odt = OffsetDateTime.of( todayUTC , localTime, ZoneOffset.UTC ) ;
ZonedDateTime
Adjust from UTC to your particular time zone. Same moment, same simultaneous point on the timeline, different wall-clock time. Apply a ZoneId to get a ZonedDateTime object. The time zone nows about if and when Daylight Saving Time (DST) applies for this particular zone, and adjusts accordingly.
ZoneId z = ZoneId.of( "America/Martinique" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Wrong approach
You should not be adding/subtracting some number of hours from a LocalTime. On some dates in some zones, a particular time-of-day may not exist. For example, for Daylight Saving Time, on the day of "Spring-ahead", in the United States, a time-of-day of 02:15:00 does not exist, as the clock jumps ahead from 02:00:00 to 03:00:00.
The correct approach using the ZonedDateTime class will automatically adjust accordingly.
You can use java.time, the modern date time API, and parse the time String to a moment in time, that is an Instant.
Then use ZonedDateTime objects to apply a certain time zone, which may be done in different ways, I show you one of them here:
public static void main(String[] args) {
// the source is just a time, but to correctly convert it, you need a date
String utcTime = "12:15:00";
// take today's date
LocalDate today = LocalDate.now();
// create a parseable date time String
String parseableDateTime = today.format(DateTimeFormatter.ISO_DATE) + "T" + utcTime + "Z";
// then create an Instant parsing the date time String
Instant instant = Instant.parse(parseableDateTime);
// get the ZoneId of UTC in order to have the time in UTC
ZoneId utc = ZoneId.of("UTC");
// do the same with your ZoneOffset of -4 Hours
ZoneId gmtMinusFour = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4));
// create a UTC ZonedDateTime of the instant and the UTC ZoneID
ZonedDateTime utcZdt = ZonedDateTime.ofInstant(instant, utc);
// then use that ZonedDateTime to convert it to a time with your ZoneId
ZonedDateTime gmtMinusFourZdt = utcZdt.withZoneSameInstant(gmtMinusFour);
// finally print both ZonedDateTimes in order to compare them
System.out.println("UTC time is:\t\t"
+ utcZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
System.out.println("GMT-4 time is:\t\t"
+ gmtMinusFourZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
// then just get the time part of the converted ZonedDateTime
LocalTime localTime = gmtMinusFourZdt.toLocalTime();
// and print it
System.out.println("Converted time is:\t"
+ localTime.format(DateTimeFormatter.ISO_TIME));
}
Output:
UTC time is: 2019-09-24T12:15:00Z[UTC]
GMT-4 time is: 2019-09-24T08:15:00-04:00[GMT-04:00]
Converted time is: 08:15:00
There may be better solutions, but I hope this helps anyway…
I am trying to convert 19 digit Unix timestamp such as 1558439504711000000 (one and a half quintillion) into a readable date/time format. My timestamp ends with 6 zeros which suggests the time is in nano seconds.
I have come across some examples where people have used time zones which I don't need. Another example uses ofEpochSecond like so:
Instant instant = Instant.ofEpochSecond(seconds, nanos);
But I am not sure whether I need to use ofEpochSecond.
The code below gives my most recent approach of achieving this:
String timeStamp = "1558439504711000000";
long unixNanoSeconds = Long.parseLong(timeStamp);
Date date = new java.util.Date(timeStamp*1000L);
// My preferred date format
SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String formattedDate = sdf.format(date);
System.out.println("The timestamp in your preferred format is: " + formattedDate);
But the output I get is something like this:
// The timestamp in your preferred format is: 11-12-49386951 11:43:20
Which does not show the year format in e.g. 2019 format.
tl;dr
Never use legacy class java.util.Date. Instead, use modern java.time.Instant.
Instant // The modern way to represent a moment in UTC with a resolution of nanoseconds. Supplants the terrible `java.util.Date` class.
.ofEpochSecond( // Parse a count since epoch reference of 1970-01-01T00:00:00Z.
0L , // Passing zero for the count of whole seconds, to let the class determine this number from the 2nd argument.
Long.parse( "1558439504711000000" ) // Count of nanoseconds since the epoch reference of 1970-01-01T00:00:00Z.
) // Returns a `Instant` object.
.atZone( // Adjust from UTC to the wall-clock time used by the people of a specific region (a time zone).
ZoneId.of( "Europe/London" )
) // Returns a `ZonedDateTime` object. Same moment as the `Instant`, same point on the timeline, different wall-clock time.
.format( // Generate text to communicate the value of the moment as seen through this time zone.
DateTimeFormatter.ofPattern( // Define how to format our generated text.
"dd-MM-uuuu HH:mm:ss" , // Specify your desired formatting pattern.
Locale.UK // Pass a `Locale` to be used in localizing, to (a) determine human language used in translating name of day-of-week and such, and (b) determine cultural norms to decide issues of capitalization, abbreviation, etc. Not really needed for this particular formatting pattern, but a good habit to specify `Locale`.
) // Returns a `DateTimeFormatter` object.
) // Returns a `String` object containing our text.
21-05-2019 12:51:44
…or…
Instant
.ofEpochSecond (
TimeUnit.NANOSECONDS.toSeconds(
Long.parse( "1558439504711000000" )
) ,
( 1_558_439_504_711_000_000L % 1_000_000_000L )
)
.toString()
2019-05-21T11:51:44.711Z
Note the hour difference because the time zone is one hour ahead of UTC.
Avoid legacy date-time classes
The java.util.Date class is terrible. Along with its littermates such as Calendar & SimpleDateFormat, they amount to a awful mess. Avoid them. Sun, Oracle, and the JCP community gave up on them when they adopted JSR 310.
Instant
A java.util.Date object represents a moment in UTC, with a resolution of milliseconds. Its replacement is java.time.Instant, also a moment in UTC but with a resolution of nanoseconds. Internally, both track a count since the epoch reference of first moment of 1970 in UTC.
To avoid dealing with gigantic numbers, internally a Instant tracks a number of whole seconds since 1970 plus a fractional second kept as a number of nanoseconds. Two separate numbers. Those are what you need to feed Instant.ofEpochSecond.
Parse your input string as a long using the Long class. By the way, notice that your value is pushing towards to the limit of a 64-bit integer.
long totalNanos = Long.parse( "1558439504711000000" ) ;
Use the TimeUnit enum to do the math of splitting out whole seconds.
long secondsPortion = TimeUnit.NANOSECONDS.toSeconds( totalNanos ) ;
Modulo by a billion, the remainder being the nanoseconds of the fractional second.
long nanosPortion = ( totalNanos % 1_000_000_000L ) ;
Instantiate an Instant.
Instant instant = Instant.ofEpochSecond( secondsPortion , nanosPortion ) ;
My timestamp ends with 6 zeros which suggests the time is in nano seconds.
Actually, nanoseconds count up to a billion, so nine (9) digits not six (6). The fractional second in your count from epoch is 711000000, or 711,000,000 nanos. Your number of whole seconds is 1558439504, or 1,558,439,504 (one and a half billion). As a decimal:
1,558,439,504.711000000 seconds since 1970-01-01T00:00Z
Time Zone
I have come across some examples where people have used time zones which I don't need.
To represent a moment, a specific point on the timeline, you always need a time zone (or offset-from-UTC of hours-minutes-seconds).
To see that same moment through the wall-clock time used by the people of a particular region (a time zone), apply 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 2-4 letter abbreviation such as BST or 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, different wall-clock time.
2019-05-21T12:51:44.711+01:00[Europe/London]
Notice the adjustment in the time-of-day, going from hour 11 to hour 12. This makes sense as Europe/London zone is an hour ahead of UTC on that date. Same moment, same point on the timeline, different wall-clock time.
Shortcut
As Ole V.V. noted in the comment, you could skip the math discussed above. Feed the entire number of nanoseconds as the second argument to ofEpochSecond. The class internally does the math to separate whole seconds from the fractional second.
Instant instant = Instant.ofEpochSecond( 0L , 1_558_439_504_711_000_000L ) ;
See this code run live at IdeOne.com.
Generate text
Generate text representing the value of that ZonedDateTime in standard ISO 8601 format extended to append the name of the time zone in square brackets.
String output = zdt.toString() ;
2019-05-21T12:51:44.711+01:00[Europe/London]
Or let java.time automatically localize for you.
Locale locale = Locale.UK;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ).withLocale( locale );
String output = zdt.format( f );
21/05/2019, 12:51
Or specify a custom format.
Locale locale = Locale.UK;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH:mm:ss" , locale ) ;
String output = zdt.format( f );
21-05-2019 12:51:44
Tip: Be very careful about providing a date-time without specifying the zone explicitly. This creates ambiguity, where the user may assume a different zone/offset is in play.
I think there is nothing wrong with that, you are dealing with a timestamp that represent a date in the FUTURE (a really far away date in the future).
If you consider this:
String timeStamp = "1558439504";
this should give you: 05/21/2019 # 11:51am (UTC)
Then there is I think an easy way to get the Date. Just create the Instant first based on that timestamp and then do:
Date myDate = Date.from(instant);
Try using this
Date date = new java.util.Date(timeStamp/1000000);
Instead of multiplying by 1000, divide by 1000000
Probably, this question is asked many times but I might not find the correct keywords to find them.
There was a time change at 30.10. The time was set back to 2 o'clock at 03:00 o'clock (Europe/Berlin). That means, at that day, there were two 02:00 o'clock (before and after time change)
Currently, I have two date (java.util.Date) objects. One of them was created at the first 02:00 o'clock (before the time was set back) and the second one was created at the second 02:00 o'clock.
Is there any way to differentiate these objects based on whether it was created at the first or second 02:00 o'clock?
Count from epoch
Your java.util.Date objects actually are in UTC but their toString method confusingly applies a time zone when generating the string output.
You can differentiate two Date objects by interrogating for their count from epoch. Internally the date-time is tracked as a number of milliseconds since first moment of 1970 in UTC. Call the badly-named method java.util.Date::getTime to get a long.
UTC
Record moments in UTC. Every programmer should learn to think in UTC, work in UTC, do logging in UTC, and keep a second clock on their desk and screen set to UTC.
UTC is the One True Time. All others are mere variations, every time zone being a deviation from UTC.
Let me repeat the acronym one more time to be clear: UTC
Instant
The Instant class is your new best friend in this arena, your go-to class for date-time work. It represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now() ;
You need not worry about Daylight Saving Time (DST) cut-overs, politicians redefining DST ( often with little notice), nor other anomalies particular to any one time zone. Just use UTC.
To generate a String representing this moment, call toString for a string in standard ISO 8601 format. This string is always in UTC, so you don't have the problem of Date::toString applying a time zone while generating the string. The standard format has a Z on the end, short for Zulu, and means UTC.
instant.toString(): 2016-01-23T12:34:56.123456789Z
Converting Date
Convert your java.util.Date objects to Instant. New conversion methods have been added to the old classes.
Instant instant = myUtilDate.toInstant();
Zoned
I do not care about Berlin time. You, as a programmer, do not care about Berlin time. Your network and server admins do not care about Berlin time. We care about UTC.
The only people who care about Berlin time are end-users. For them, you can assign a time zone for presentation of data.
ZoneId z = ZoneId.of( "Europe/Berlin" );
ZonedDateTime zdt = instant.atZone( z );
Call toString to generate a String in standard ISO 8601 format but wisely extended by appending the name of the time zone in square brackets.
2016-07-07T08:00:15.768+02:00[Europe/Berlin]
Use DateTimeFormatter class to generate Strings representing the date-time value in other formats.
DST in effect?
You can interrogate to determine if Daylight Saving Time (DST) is in effect for any particular ZonedDateTime. See this Question.
ZoneRules rules = zdt.getZone().getRules();
Boolean dstInEffect = rules.isDaylightSavings( zdt.toInstant() );
In the code below I have used calendar object to initialize time Zone to GMT and get the time accordingly but when I put back in date object, its automatically converting to my local time zone i.e. IST.
Calendar gmt = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dt=gmt.getTime();
Could anyone suggest a way through which I can retain the GMT format in date object also.
its automatically converting to my local time zone i.e. IST
No it's not. A Date object doesn't have a time zone - it's just an instant in time.
You'll see the system-local time zone if you call toString() on a Date, because that's unfortunately what Date.toString() does... but the time zone is not part of the information stored in a Date.
If you want to see a textual representation of a Date in a particular time zone, use DateFormat and set the time zone that you want to use.
java.time
The other answers are correct. The toString method silently applies your JVM’s current default time zone. This is one of many poor design choices in the old date-time classes. Dump those old classes. Move on to the java.time framework built into Java 8 and later.
An Instant is a moment on the time line in UTC.
Instant now = Instant.now();
Apply a time zone (ZoneId) to an Instant to get a ZonedDateTime.
Why are we bothering to create a ZonedDateTime in UTC if the Instant is already in UTC? Because a ZonedDateTime gives you flexibility in formatting String representations of the date-time values. The java.time.format package does not work with Instant objects.
A subclass of ZoneId, ZoneOffset, has a constant for UTC.
ZonedDateTime zdtUtc = ZonedDateTime.ofInstant( ZoneOffset.UTC );
Adjust into any desired time zone.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = ZonedDateTime.ofInstant( instant , zoneId );
Use proper time zone names
Avoid using 3-4 letter codes for time zones. They are neither standardized nor unique. By IST did you mean India Standard Time or Irish Standard Time?
Use standard time zone names. Most are in the pattern of continent/region. For India, Asia/Kolkata. For Ireland, Europe/Dublin.
The Date class does not represent a timezone. It's toString method uses the default platform time zone to output a human readable timestamp, internally it's just a long.