yuva ツ
yuva ツ

Reputation: 3703

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.

Upvotes: 0

Views: 3268

Answers (2)

ppeterka
ppeterka

Reputation: 20726

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.

Upvotes: 3

Basil Bourque
Basil Bourque

Reputation: 338584

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

Upvotes: 2

Related Questions