Convert date to Eastern Time - Get Date object as output - java

I've seen many examples of converting date from one time zone to another. But all of them has output as a String. I want a date object as output.
The methods I've tried -
Approach 1
SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z");
dateTimeFormat.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
Date date = new Date();
System.out.println(dateTimeFormat.format(date)); // this print IST Timezone
DateFormat timeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z");
timeFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String estTime = timeFormat.format(date);
try {
date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z", Locale.ENGLISH).parse(estTime);
System.out.println(date);
} catch (ParseException ex) {
Logger.getLogger(A.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(timeFormat.format(date));
Approach 2
private static Date shiftTimeZone(Date date, TimeZone sourceTimeZone, TimeZone targetTimeZone) {
System.out.println(sourceTimeZone.toString());
System.out.println(targetTimeZone.toString());
Calendar sourceCalendar = Calendar.getInstance();
sourceCalendar.setTime(date);
sourceCalendar.setTimeZone(sourceTimeZone);
Calendar targetCalendar = Calendar.getInstance();
for (int field : new int[]{Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND}) {
targetCalendar.set(field, sourceCalendar.get(field));
}
targetCalendar.setTimeZone(targetTimeZone);
return targetCalendar.getTime();
}
Approach 1 gives me result as a String.
03/22/2018 10:16:57 AM EDT <- instanceOf String
Approach 2 gives me correct date and time of Eastern Time time zone, but the Date has the time zone of IST.
Thu Mar 22 10:16:57 IST 2018 <- instanceof Date
Can anyone please help me to obtain a Date object with Eastern Time TimeZone.
Update - My ultimate goal is to get Unix Timestamp of the current Eastern Time.

tl;dr
Instant.now() // Capture the current moment in UTC, an `Instant` object.
.atZone( // Adjust from UTC into a particular time zone.
ZoneId.of( “Asia/Kolkata” )
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust into yet another time zone. All three are the same moment but vowed using different wall-clock times.
ZoneId.of( “Africa/Tunis” )
) // Returns another `ZonedDateTime` object.
Or…
ZonedDateTime.now(
ZoneId.of( “Asia/Kolkata” )
).withZoneSameInstant(
ZoneId.of( “Africa/Tunis” )
)
Avoid legacy date-time classes
Firstly, stop using the legacy date-time classes. They are an awful wretched mess. Supplanted by the java.time classes.
Date is replaced by Instant.
Calendar is replaced by ZonedDateTime
SimpleDateFormat is replaced by DateTimeFormatter.
Deceived by Date::toString
Secondly, understand that Date has a horribly confusing feature of dynamically applying your JVM’s current default time zone while generating a String. Date always represents a moment in UTC. The toString method creates a false illusion of Date carrying a time zone, when actually its value is in UTC. While well-intentioned by the class designers, this was a disastrous decision, causing no end of confusion amongst countless programmers for decades now.
Even worse: There actually is a time zone buried in a Date, but is irrelevant to this discussion. Confusing? Yes; as I said, an awful wretched mess of bad design.
Instant
The Instant class replacing Date is much clearer. An Instant represents a moment, a point on the timeline, always in UTC, with a resolution of nanoseconds.
Use Instant to capture the current moment in UTC. The JVM’s current default time zone is irrelevant. The host OS’ assigned time zone is irrelevant.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Unlike Date::toString, the Instant::toString method tells the truth. A Instant is always in UTC, so toString always reports UTC. A String is generated in standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.
instant.toString(): 2018-01-23T12:34:56.123456789Z
About capturing the current moment… In Java 8, the current moment was captured in milliseconds even though the java.time classes can represent nanoseconds. In Java 9 and later, a new implementation of Clock provides for capturing the current moment in finer granularity. In Java 9.0.4 on macOS Sierra, I see microseconds. The hardware clocks on conventional computers nowadays cannot capture the current moment with accuracy beyond microseconds.
ZonedDateTime
To view that same moment through the lens of a wall-clock time used by the people of a particular region, assign that region’s time zone. Applying a ZoneId to an Instant produces a ZonedDateTime. Conceptually:
ZonedDateTime = ( Instant + ZoneId )
In code:
ZoneId z = ZoneId.of( “Pacific/Auckland” ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
Adjusting to another time zone is easy. You can start with the Instant again.
ZoneId zKolkata = ZoneId.of( “Asia/Kolkata” ) ;
ZonedDateTime zdt = instant.atZone( zKolkata ) ;
Or you can adjust the ZonedDateTime object. The java.time classes use immutable objects. So rather than “mutate” (alter) the original object, the adjustment produces a new distinct object.
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ; // Same moment, same point on the timeline, different wall-clock time.
You can skip the use of the Instant. I do not recommend doing so. Programmers should be doing their thinking, debugging, logging, exchanging of data, and much of their business logic in UTC. So Instant should be your go-to class whenever you start any work with date-time values.
ZonedDateTime zdtNewYork = ZonedDateTime.now( ZoneId.of( "America/New_York" ) ) ;
The ZonedDateTime::toString method wisely extends the ISO 8601 standard by appending the name of the time zone in square brackets.
String output = zdtNewYork.toString() ;
2018-01-23T07:34:56.123456789-05:00[America/New_York]
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.

Related

Convert CST time zone to required Time zone Java

I need to convert a Date which is in CST to required time zone. I will get Date as String like "11/5/2018 12:54:20" which is in CST time zone. I have to convert this to a time zone which is passed as a parameter. suppose lets take it as "GMT+0530".
The result for the above date ideally "Nov 06 2018 00:24:20"
I have tried the below code which returned the passed date(11/05/2018 12:54:20) as same instead of(Nov 06 2018 00:24:20) . I have executed this on a system which has IST time zone.
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT-0600"));
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20").getTime()));
Edit:
Answer:
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;
ZoneId z = ZoneId.of( "GMT-0600" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
System.out.println(zdt);
ZoneId zKolkata = ZoneId.of( "GMT+0530" ) ;
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;
System.out.println(zdtKolkata);
tl;dr
LocalDateTime // Represent a date and a time-of-day, without offset nor zone. So *not* a moment, *not* a point on the timeline.
.parse(
"11/5/2018 12:54:20" ,
DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" ) // Define a formatting pattern to match your input string.
) // Returns a `LocalDateTime`.
.atZone( // Assign a time zone, to give meaning to the `LocalDateTime` object, making it a `ZonedDateTime` object.
ZoneId.of( "America/New_York" ) // Define a time zone properly with `Continent/Region` naming, never 2-4 letter pseudo-zones such as CST or IST.
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust from New York time to Kolkata time. Some moment, different wall-clock time.
ZoneId.of( "Asia/Kolkata" )
) // Returns another `ZonedDateTime` object rather than altering (“mutating”) the original, per Immutable Objects pattern.
.toString() // Generate text in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.
2018-05-11T22:24:20+05:30[Asia/Kolkata]
java.time
You are using terrible old classes, now supplanted by java.time classes.
Parse your input string as a LocalDateTime because it lacks any indication of offset-from-UTC or time zone.
Define a formatting pattern to match your input.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;
ldt.toString(): 2018-05-11T12:54:20
You say this was intended for CST. Did you mean China Standard Time? Or Central Standard Time in North America?
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 CST or EST or IST as they are not true time zones, not standardized, and not even unique(!).
I will assume you meant something like New York time.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
zdt.toString(): 2018-05-11T12:54:20-04:00[America/New_York]
And apparently you want to see this same moment through the lens of the wall-clock time used by the people of a different region, a different time zone. By IST did you mean Irish Standard Time? Or India Standard Time? Again, use real time zones not these 2-4 character pseudo-zones.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;
zdtKolkata.toString(): 2018-05-11T22:24:20+05:30[Asia/Kolkata]
To see the same moment in UTC, extract a Instant.
Instant instant = zdtKolkata.toInstant() ;
instant.toString(): 2018-05-11T16:54:20Z
All three of these ( zdt, zdtKolkata, instant ) all represent the same moment, the same point on the timeline.
In contrast, the ldt as a LocalDateTime object does not represent a moment, is not a point on the timeline. It held no real meaning until you assigned it a time zone to give it a context. Until assigning that zone, we do not know if meant noon hour in Australia or in Africa, or in America. It could have meant any of about 26-27 hours, the range of time zones around the globe.
ISO 8601
Rather than inventing your own formats for exchanging date-time values as text, use the standard ISO 8601 formats.
The java.time classes conveniently use ISO 8601 formats by default when generating/parsing strings.
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.
You are setting the timezone of sdf twice and not setting timezone of sdf2 and thus getting incorrect results. Also, you don't need to call getTime() when passing object to DateFormat::format().
Here is a fixed version of your code:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
TimeZone cstTimeZone = TimeZone.getTimeZone("CST");
sdf.setTimeZone(cstTimeZone);
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20")));
Note that the classes you are using are quite old and since version 8, Java provides new Date and Time APIs.

Java Convert UTC Date to local Date with Joda

This code is working, but I want to use Joda-Time
public static Date dateFromUTC(Date date){
return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(date.getTime()));
}
I tried this, but it's not working - what's the problem with this?
public static Date dateFromUTC(Date date){
return new DateTime(date).withZone(DateTimeZone.getDefault()).toDate();
}
tl;dr
Use java.time classes instead.
Instant.now() // Capture current moment in UTC. Always in UTC, by definition.
…and…
ZonedDateTime.now() // Capture current moment as seen through the wall-clock time of the people in the region of the time zone used by default in this JVM.
Details
As others said, you misunderstood the concepts involved in these classes. A java.util.Date represents a moment in UTC, always in UTC†, never in some other time zone. So the code seen in the Question is non-sensical. You are working too hard!
java.time
The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. Many of the concepts are similar between Joda-Time and java.time as both projects are led by the same man, Stephen Colebourne.
When you are ready to migrate, use Instant in place of java.util.Date.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString(): 2018-01-23T12:34:56.123456789Z
Instead of java.util.Calendar, use ZonedDateTime to represent a moment seen through the wall-clock time of a particular region (a 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( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
As a shortcut, you can skip the Instant if you want only the zoned time.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen by people in a certain time zone.
You can get to UTC from there by extracting an Instant object.
Instant instant = zdt.toInstant() ; // Same moment, same point on the timeline, but viewed with the wall-clock time of UTC.
† Actually, there is a time zone assigned deep within a java.util.Date but is irrelevant to our discussion here. Confusing? Yes. One of many reasons to avoid the awful mess that is the old Date/Calendar and related legacy date-time classes.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Try this:
new DateTime(date, DateTimeZone.UTC)
.toLocalDateTime() // value without timezone
.toDateTime() // convert to default timezone
.toDate();
Your code actually does nothing to the date, because new DateTime(date) creates a DateTime object with default timezone. And then you just convert it back to java.util.Date.
First of all, read the article linked in the comments: https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
A java.util.Date doesn't have a timezone. It actually represents a point in time: the number of milliseconds since unix epoch (Jan 1st 1970, at midnight, in UTC).
When you print the Date, though, it uses the JVM default timezone to convert the Date to date/time values, but the Date itself doesn't have a timezone.
That's why converting a Date object to another timezone doesn't make sense.
If you want to know the date (day, month, year) and time (hour, minute, second, millisecond) that corresponds to the Date in a specific timezone, then you can use Joda-Time:
// java.util.Date
Date date = new Date();
// the Date converted to UTC
DateTime utc = new DateTime(date, DateTimeZone.UTC);
// the Date converted to JVM default timezone
DateTime convertedToDefaultTz= new DateTime(date, DateTimeZone.getDefault());
The conversion can also be made using another DateTime:
DateTime convertedToDefaultTz = utc.withZone(DateTimeZone.getDefault());
Joda's DateTime has a timezone attached to it, so now it makes sense to convert to another one. But the Date objects returned by it will always be the same, because all of them represent the same instant (the same point in the timeline):
Date d1 = utc.toDate();
Date d2 = convertedToDefaultTz.toDate();
System.out.println(d1.equals(d2)); // true
All because - again - a Date doesn't have a timezone.

Understanding Java util Date

Why does java.util.Date object show date & time with respect to a timezone when in actuality, java.util.Date represents an instant on the time-line, not a "date"?
The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).
Also in docs, A java.util.Date instance has no concept of time-zone.
If so is the case, why does this snippet print date specifying timezone.
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
Output : Wed Mar 22 14:58:56 IST 2017
Why is it showing specific timezone in the output? I understand the SOP implements toString() internally. Does toString() effect the timezone?
Just follow the javadoc, as it says:
public String toString()
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
zzz is the time zone (and may reflect daylight saving time).
And when you dive into the source code, that this toString() implementation will at some point use TimeZone.getDefault()
( or to be precise: getDefaultRef()). In other words: the default implementation pulls in the "default" timezone of your JVM.
tl;dr
Current moment in UTC.
Instant.now() // Capture current moment in UTC.
.toString() // Generate String in standard ISO 8601 format.
2018-01-23T01:23:45.677340Z
Current moment in India time zone.
ZonedDateTime.now(
ZoneId.of( "Asia/Kolkata" )
).toString() // Generate string in format wisely extended from ISO 8601 standard, adding the time zone name in square brackets.
2018-01-23T06:53:45.677340+05:30[Asia/Kolkata]
Avoid legacy date-time classes
Why does java.util.Date object show date & time with respect to a timezone when in actuality, java.util.Date represents an instant on the time-line, not a "date"?
Because the java.util.Date and related classes (Calendar, SimpleDateFormat, and such) are poorly-designed. While a valiant effort at tackling the tricky subject of date-time handling, they fall short of the goal. They are riddled with poor design choices. You should avoid them, as they are now supplanted by the java.time classes, an enormous improvement.
Specifically to answer your question: The toString method of Date dynamically applies the JVM’s current default time zone while generating a String. So while the Date object itself represents a moment in UTC, the toString creates the false impression that it carries the displayed time zone.
Even worse, there is a time zone buried inside the Date object. That zone is used internally, yet is irrelevant to our discussion here. Confusing? Yes, yet another reason to avoid this class.
A java.util.Date instance has no concept of time-zone.
Not true. A Date represents a specific moment, a point on the timeline, with a resolution of milliseconds, in UTC. As you mention, it is defined as a count of milliseconds since the first moment of 1970 in UTC.
java.time
The java.time classes separate clearly the concepts of UTC, zoned, and unzoned values.
The java.time.Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). This class replaces java.util.Date.
Instant instant = Instant.now() ; // Capture current moment in UTC.
Apply a time zone (ZoneId object) to an Instant and you get a ZonedDateTime object. That class replaces the java.util.Calendar class.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same simultaneous moment as `instant`, but different wall-clock time.
If a value has only an offset-from-UTC but not a full time zone, use the OffsetDateTime class.
For a date only, without time-of-day and without time zone, use the LocalDate class. This class replaces the java.sql.Date class. Ditto for LocalTime replacing java.sql.Time.
LocalDate xmasDate2018 = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
If the zone or offset are unknown or indeterminate, such as "Christmas starts at stroke of midnight on December 25, 2018", use the LocalDateTime class. This class does not represent an actual moment, a specific point on the timeline. This class lacks any concept of time zone or offset. So it can only represent potential moments along a range of about 26-27 hours.
LocalDateTime xmasEverywhere2018 = LocalDateTime.of( xmasDate2018 , LocalTime.MIN ) ;
Or…
LocalDateTime xmasEverywhere2018 = LocalDateTime.of( 2018 , Month.DECEMBER , 25 , 0 , 0 , 0 , 0 ) ;
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.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or 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.
It does have a concept of time zone, but it is always UTC. When it prints the date therefore there is no problem converting it to the time zone of your computer.

Current time not getting converted into MST timezone

I'm trying to convert current time in MST using below code
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
TimeZone toTimeZone = TimeZone.getTimeZone("MST");
sdf.setTimeZone(toTimeZone);
Date date = new Date();
String strDate = sdf.format(date.getTime());
strDate displaying correct MST time, but after parsing it is giving wrong date time.
Date currentDate = sdf.parse(strDate);
I want current MST time in Date format not in string.
A java.util.Date object does not have a concept of time zone.
There is no way to set a timezone for a Date
There is no way to change the timezone of a Date object
A Date object created with the new Date() default constructor will be initialised with the current time in the system default timezone
All you did is add a time zone information for the formatting part... setTimeZone does not convert anything.
tl;dr
ZonedDateTime zdt = LocalDateTime.parse( input , DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" ) ).atZone( ZoneId.of( "America/Denver" ) );
Avoid legacy date-time classes
You are using old outmoded troublesome legacy date-time classes.
java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
Now in maintenance mode, the Joda-Time project also advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.
LocalDateTime
Your input string lacks any indication of offset-from-UTC or time zone. So we must parse as a LocalDateTime. A LocalDateTime has no offset or time zone, so it does not represent a moment on the timeline. Like saying "Christmas starts at midnight on December 25", that only has meaning (only becomes a point on the timeline) when you apply it to a particular time zone somewhere on the planet.
String input = …
DateTimeFormatter f = DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" );
LocalDateTime ldt = LocalDateTime.parse( input , f );
ZonedDateTime
If you know the context and can assume the intended offset or time zone, you can create an OffsetDateTime or ZonedDateTime respectively.
Use proper time zone names, named in the format of continent/region. By MST perhaps you meant the America/Denver time zone used in much of the Rocky Mountains parts of the United States, or America/Edmonton used in parts of Canada.
Never use the 3-4 letter abbreviations such as MST. These abbreviations are not true time zones, are not standardized, and are not even unique(!).
ZoneId zoneId = ZoneId.of( "America/Denver" ) ;
ZonedDateTime zdt = ldt.atZone( zoneId ) ;
Converting
I suggest avoiding the notoriously troublesome java.util.Date class. But if you must do so , you may convert to/from java.time types. To interoperate with other code or libraries, convert using new methods added to the old classes. In this case, use a Instant object extracted from the OffsetDateTime or ZonedDatetime and pass to java.util.Date.from.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
java.util.Date utilDate = java.util.Date.from( zdt.toInstant() ) ;
Going the other direction, use another new method added to the old class, java.util.Instant::toInstant.
Instant instant = utilDate.toInstant();
ZonedDateTime zdt = instant.atZone( zoneId ) ;

Java: Calculating time zone difference

How do I get the time difference from GMT for a specific date and time zone in Java?
Determining whether a specific time zone is in DST is quite straight-forward:
boolean isIsraelInDST = TimeZone.getTimeZone("Israel").inDaylightTime(new Date());
How do I get the actual time difference?
Use TimeZone.getRawOffset(): Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. Because this value is not affected by daylight saving time, it is called raw offset.
If you want the offset including DST then you use TimeZone.getOffset(long date). You should provide the concrete date to the method, eg now - System.currentTimeMillis()
tl;dr
ZoneId.of( "Pacific/Auckland" ) // Specify a time zone.
.getRules() // Get the object representing the rules for all the past, present, and future changes in offset used by the people in the region of that zone.
.getOffset( Instant.now() ) // Get a `ZoneOffset` object representing the number of hours, minutes, and seconds displaced from UTC. Here we ask for the offset in effect right now.
.toString() // Generate a String in standard ISO 8601 format.
+13:00
For the first moment of a certain date.
ZoneId.of( "Pacific/Auckland" )
.getRules()
.getOffset(
LocalDate.of( 2018 , Month.AUGUST , 23 ) // Specify a certain date. Has no concept of time zone or offset.
.atStartOfDay( ZoneId.of( "Pacific/Auckland" ) ) // Determine the first moment of the day on that date in that region. Not always `00:00:00` because of anomalies such as Daylight Saving Time.
.toInstant() // Adjust to UTC by extracting an `Instant`.
)
.toString()
+12:00
Avoid legacy date-time classes
The other Answers are outmoded, as the TimeZone class is now legacy. This and other troublesome old date-time classes are supplanted by the java.time time classes.
java.time
Now we use ZoneId, ZoneOffset, and ZoneRules instead of the legacy TimeZone class.
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( "Africa/Tunis" ) ;
Fetch the rules for that zone.
ZoneRules rules = z.getRules() ;
Ask the rules if Daylight Saving Time (DST) is in effect at a certain moment. Specify the moment as an 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).
Instant instant = Instant.now() ; // Capture current moment in UTC.
boolean isDst = rules.isDaylightSavings( instant ) ;
How do I get the actual time difference?
Not sure what you mean, but I will guess you are asking for the offset-from-UTC in effect at that moment for than zone. An offset is a number of hours, minutes, and seconds displacement from UTC. We represent an offset using ZoneOffset class. A time zone is a history of past, present, and future changes in offset used by the people of a particular region. We represent a time zone using ZoneId class.
Because the offset may vary over time for a region, we must pass a moment when asking for an offset.
ZoneOffset offset = rules.getOffset( instant ) ;
Generate a String representing that offset in ISO 8601 standard format.
String output output = offset.toString() ;
You can ask for the offset as a total number of seconds.
int offsetInSeconds = offset.getTotalSeconds() ;
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 suggest to add summer/winter time offset to getRawOffset:
TimeZone tz1 = TimeZone.getTimeZone("GMT");
TimeZone tz2 = TimeZone.getTimeZone("America/New_York");
long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings();
I see this is an old thread - but adding this since I had a similar requirement recently -
This gives the actual difference in millis based on the CURRENT time(millis from epoch).
TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())
public String timeZone(Date date) {
TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
long millis = timeZone.getRawOffset() + (timeZone.inDaylightTime(date) ? timeZone.getDSTSavings() : 0);
return String.format("%s%s:%s",
millis < 0 ? "-" : "+",
String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toHours(millis))),
String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))))
);
}

Categories

Resources