如何更改一个java.util.Calendar / Date的TIMEZONE

我想在运行时更改Java日历实例中的TIMEZONE值。 我在下面尝试。 但是在两种情况下输出都是一样的:

Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); System.out.println(cSchedStartCal.getTime().getTime()); cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta")); System.out.println(cSchedStartCal.getTime().getTime()); 

OUTPUT:
1353402486773
1353402486773

我也试过这个,但输出仍然是一样的:

  Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); System.out.println(cSchedStartCal.getTime()); Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta")); cSchedStartCal1.setTime(cSchedStartCal.getTime()); System.out.println(cSchedStartCal.getTime()); 

在API中,我看到下面的评论,但我不能理解它:

  * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST). * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More * generally, a call to setTimeZone() affects calls to set() BEFORE AND * AFTER it up to the next call to complete(). 

你可以帮我吗?

可能的解决scheme

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

这个解决scheme好吗?

在Java中,date自内部以UTC毫秒表示(因此不考虑时区),这就是为什么得到相同的结果,因为getTime()提供了所提到的毫秒)。
在你的解决scheme:

 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到指定的时区(在你的例子中的“亚洲/加尔各答”)的偏移量,以毫秒为单位,所以这应该工作正常。

另一个可能的解决scheme是利用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/以获得更深入的解释。

  1. Date/Timestamp类表示一个特定的即时时间,自1970年1月1日00:00:00 GMT以来,精度为毫秒级。 所以这个时间差(从时代到现在的时间)在世界各地的所有计算机中都是一样的,而不考虑时区。

  2. Date/Timestamp不知道给定的时间是在哪个时区。

  3. 如果我们想要基于时区的时间,我们应该去java中的日历或SimpleDateFormat类。

  4. 如果您尝试使用toString()打印date/时间戳记对象,它将使用机器的默认时区进行转换和打印。

  5. 所以我们可以说(Date / Timestamp).getTime()对象将始终有UTC(时间以毫秒为单位)

  6. 总结Date.getTime()会给出UTC时间,但toString()是在特定于语言环境的时区,而不是UTC。

现在我将如何创build/更改指定时区的时间?

下面的代码为您提供了指定时区的date(以毫秒为单位)。 这里唯一的问题是你必须给string格式的date。

  DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); dateFormatLocal.setTimeZone(timeZone); java.util.Date parsedDate = dateFormatLocal.parse(date); 

使用dateFormat.format将inputdate(始终为UTC),时区和返回date作为string。

如何在数据库中存储UTC / GMT时间:

如果您打印parsedDate对象,时间将在默认的时区。 但是您可以像下面那样将UTC时间存储在数据库中。

  Calendar calGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT")); Timestamp tsSchedStartTime = new Timestamp (parsedDate.getTime()); if (tsSchedStartTime != null) { stmt.setTimestamp(11, tsSchedStartTime, calGMT ); } else { stmt.setNull(11, java.sql.Types.DATE); }