如何为java.util.Calendar/Date更改TIMEZONE

Kan*_*mar 40 java datetime calendar

我想在运行时更改Java Calendar实例中的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());
Run Code Online (Sandbox Code Playgroud)

输出:
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());
Run Code Online (Sandbox Code Playgroud)

在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().
Run Code Online (Sandbox Code Playgroud)

请你帮助我好吗?

可能的解决方案:

    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);
Run Code Online (Sandbox Code Playgroud)

这个解决方案好吗?

Bas*_*i M 51

在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);
Run Code Online (Sandbox Code Playgroud)

您只需将GMT的偏移量添加到指定的时区(在您的示例中为"Asia/Calcutta"),以毫秒为单位,因此这应该可以正常工作.

另一种可能的解决方案是利用类的静态字段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);
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案的前半部分是完全错误的.自纪元以来的毫秒数指定了没有时区信息的绝对时间点.调整日历的毫秒时间将更改日历以表示不同的时间点.OP显然希望在不同时区表示*相同*绝对时间点. (3认同)

Kan*_*mar 16

  1. 该类Date/Timestamp表示特定的时刻,精确到毫秒,自1970年1月1日00:00:00 GMT.因此,无论时区如何,这个时间差(从纪元到当前时间)在全世界所有计算机中都是相同的.

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

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

  4. 如果您尝试使用打印日期/时间戳对象toString(),它将使用您机器的默认时区转换并打印时间.

  5. 所以我们可以说(日期/时间戳).getTime()对象将始终具有UTC(以毫秒为单位的时间)

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

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

下面的代码为您提供了指定时区的日期(以毫秒为单位的时间).这里唯一的问题是你必须以字符串格式给出日期.

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

使用dateFormat.format采取输入日期(这始终是UTC),时区和返回日期字符串.

如何在DB中存储UTC/GMT时间:

如果打印parsedDate对象,则时间将为默认时区.但您可以将UTC时间存储在DB中,如下所示.

        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);
        }
Run Code Online (Sandbox Code Playgroud)