如何使用特定的TimeZone创建日历?

时间:2016-03-09 12:33:05

标签: java calendar

我正在创建一个Calendar对象:

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

calendar.getTime()返回Wed Jan 01 00:00:00 BRT 2014

2014-01-01T00:00:00.000-0300

如何使用UTC TimeZone创建具有特定日期的日历?

当我尝试calendar.setTimeZone(TimeZone.getTimeZone("UTC"));

calendar.getTime()返回相同内容。

3 个答案:

答案 0 :(得分:5)

只需将“指定日期,指定时区”的顺序改为“指定时区,指定日期”:

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

我还建议完全避免使用Calendar / Date API - 对Java 8使用java.time,对旧版Java使用Joda Time。

答案 1 :(得分:0)

在Java中,日期在内部以UTC毫秒为单位表示时间(因此不考虑时区,这就是为什么你得到相同的结果,因为getTime()给你提到的毫秒数)。 在您的解决方案中:

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

你只需将GMT的偏移量添加到指定的时区("亚洲/加尔各答"在你的例子中),以毫秒为单位,所以这应该可以正常工作。

另一种可能的解决方案是利用Calendar类的静态字段:

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

有关更深入的解释,请参阅stackoverflow.com/questions/7695859/

答案 2 :(得分:0)

其他答案是正确的。

java.time

问题和其他答案都使用旧的日期时间类,现在已经过时了Java 8及更高版本中内置的java.time框架。事实证明,旧课程的设计很糟糕,令人困惑,也很麻烦。

在新课程中,LocalDate表示没有时间且没有时区的仅限日期的值。

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

我们可以在要求当天的第一时刻申请时区。第一时刻并不总是时间00:00:00.0所以我们应该问而不是假设。

结果ZonedDateTime是时间轴上的实际时刻。

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

您可以调整到另一个时区。

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