【问题标题】:Java Calendar setTimeZone method behaviourJava 日历 setTimeZone 方法行为
【发布时间】:2014-09-09 09:07:44
【问题描述】:

当我使用 java6 在 windows 上运行以下代码时,它会打印以下输出。

private static SimpleDateFormat timeZoneFormatter = new SimpleDateFormat("Z");
public static void main(String[] args) {
    try {
        String format = "yyyyMMdd";

        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        Date date1 = dateFormat.parse("20140330");
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);

        Date date2 = dateFormat.parse("20140401");

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        calendar1.setTimeZone(TimeZone.getTimeZone("GMT"));
        calendar2.setTimeZone(TimeZone.getTimeZone("GMT"));

        System.out.println(timeZoneFormatter.format(calendar1.getTime()));
        System.out.println(timeZoneFormatter.format(calendar2.getTime()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
+0200
+0300

据我所知,无论我在日历对象上设置什么时区,它都需要 SimpleDateFormat 对象上的默认时区信息。我在这里错过了什么吗?如果这是正常行为,在什么情况下我们应该使用 Calendar.setTimezone() 方法?

【问题讨论】:

    标签: java calendar timezone


    【解决方案1】:

    时区设置在您的示例中无效的原因是:不应将setTimeZone 应用于日历对象,而应将setTimeZone 应用于timeZoneFormatter 对象。

    请在下面查看我的可执行示例代码。这段代码将演示时区的用法和效果。

    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.TimeZone;
    
    public class TimeZoneTEST {
        private static SimpleDateFormat timeZoneFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        public static void main(String[] args) {
            try {
                String timezone_GMT = "GMT";
                String timezone_NYC = "America/New_York";
                long currentLongTime = System.currentTimeMillis();
    
                // Effect of time zone when displaying time as hhmm
                System.out.format("Current time(HHMM) in [%s] time zone is [%d]\n", timezone_GMT, getCurrentTime(currentLongTime, timezone_GMT));
                System.out.format("Current time(HHMM) in [%s] time zone is [%d]\n", timezone_NYC, getCurrentTime(currentLongTime, timezone_NYC));
    
                // Effect of time zone when displaying the formatted string representation of time
                System.out.format("Current time(String representation) in [%s] time zone is [%s]\n", timezone_GMT, fmtDateWithTZ(currentLongTime,timezone_GMT));
                System.out.format("Current time(String representation) in [%s] time zone is [%s]\n", timezone_NYC, fmtDateWithTZ(currentLongTime,timezone_NYC));
                } catch (Exception e) {
            }
        }
    
        public static int getCurrentTime(long longTime, String timeZone){
            Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(timeZone));
            cal.setTimeInMillis(longTime);
            int hhmm = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE);
            return hhmm;    
        }
    
        public static String fmtDateWithTZ( long ms, String timeZone) {
            timeZoneFormatter.setTimeZone(TimeZone.getTimeZone(timeZone));
            return timeZoneFormatter.format( new Date( ms) );
        } 
    }
    

    运行代码后,应该会看到如下输出(实际显示的时间为当前时间):

    [GMT] 时区的当前时间(HHMM) 为 [945]

    [America/New_York] 时区的当前时间(HHMM) 是 [545]

    [GMT] 时区的当前时间(字符串表示形式)为 [2014-09-09 09:45:42 GMT]

    [America/New_York] 时区的当前时间(字符串表示形式)为 [2014-09-09 05:45:42 EDT]

    附注,通过应用不同的时区,相同的时间组件可以根据指定的时区以不同的方式显示。这与时间的长时间表示不同,后者测量自 1970 年 1 月 1 日午夜以来经过的毫秒数。该数量与时区无关,其值不会随时区变化。

    【讨论】:

    • 感谢您的评论。实际上格式化程序部分来自api(我无法更改它),我应该发送一个日历对象。我试图找到一种设置时区的方法。
    【解决方案2】:

    在您的示例中,timeZoneFormatter 不是格式化 calendar1 的时区,而是由 calendar1.getTime() 返回的匿名日期的时区。正在格式化的正是这个 Date 对象。由于 Date 没有时区,它根据格式化程序的时区进行格式化,在这种情况下是默认时区。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      相关资源
      最近更新 更多