kostepanych
kostepanych

Reputation: 2619

How to create Calendar with specific TimeZone?

I'm creating a Calendar object:

Calendar calendar = new GregorianCalendar(2014, 0, 1);

and calendar.getTime() returns Wed Jan 01 00:00:00 BRT 2014

that is2014-01-01T00:00:00.000-0300

How to create Calendar with specific date in UTC TimeZone?

When I try to do calendar.setTimeZone(TimeZone.getTimeZone("UTC"));

calendar.getTime() returns the same.

Upvotes: 1

Views: 2467

Answers (3)

Basil Bourque
Basil Bourque

Reputation: 340320

The other Answers are correct.

java.time

Both the Question and other Answers use old date-time classes now outmoded by the java.time framework built into Java 8 and later. The old classes have proven to be poorly designed, confusing, and troublesome.

In the new classes, LocalDate represents a date-only value without time-of-day and without time zone.

LocalDate localDate = LocalDate.of( 2014 , 0 , 1 );

We can apply a time zone while asking for the first moment of the day. That first moment is not always the time 00:00:00.0 so we should ask rather than assume.

The resulting ZonedDateTime is an actual moment on the timeline.

ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = localDate.atStartOfDay( zoneId );

You can adjust to yet another time zone.

ZoneId zoneIdSaoPaulo = ZoneId.of( "America/Sao_Paulo" );
ZonedDateTime zdtSaoPaulo = zdt.withZoneSameInstant( zoneIdSaoPaulo );

Converting between legacy and modern classes

Best to avoid the legacy classes if possible. But if you must have an object of that class to interoperate with old code not yet updated for java.time, you can convert.

Calendar c = GregorianCalendar.from( zdtSaoPaulo ) ;

Going the other direction.

if( myCalendar instanceof GregorianCalendar ) 
{
    ZonedDateTime zdt = ( ( GregorianCalendar ) myCalendar ).toZonedDateTime() ;
}

Similarly, you can go between legacy java.util.Date and modern Instant. And java.sql.Date and LocalDate.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1504122

Just reverse the order of "specify date, specify time zone" to "specify time zone, specify date":

Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.set(2014, 0, 1, 0, 0, 0);
calendar.set(Calendar.MILLISECOND, 0);

I'd also recommend avoiding the Calendar/Date API entirely - use java.time for Java 8, and Joda Time for older versions of Java.

Upvotes: 6

Mohith P
Mohith P

Reputation: 585

In Java, Dates are internally represented in UTC milliseconds since the epoch (so timezones are not taken into account, that's why you get the same results, as getTime() gives you the mentioned milliseconds). In your solution:

Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
long gmtTime = cSchedStartCal.getTime().getTime();

long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone("Asia/Calcutta").getRawOffset();
Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
cSchedStartCal1.setTimeInMillis(timezoneAlteredTime);

you just add the offset from GMT to the specified timezone ("Asia/Calcutta" in your example) in milliseconds, so this should work fine.

Another possible solution would be to utilise the static fields of the Calendar class:

//instantiates a calendar using the current time in the specified timezone
Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
//change the timezone
cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
//get the current hour of the day in the new timezone
cSchedStartCal.get(Calendar.HOUR_OF_DAY);

Refer to stackoverflow.com/questions/7695859/ for a more in-depth explanation.

Upvotes: 1

Related Questions