【问题标题】:Java: How do you convert a UTC timestamp to local time?Java:如何将 UTC 时间戳转换为本地时间?
【发布时间】:2012-09-11 07:32:25
【问题描述】:

我有一个 UTC 时间戳,我想将其转换为本地时间,而不使用像 TimeZone.getTimeZone("PST") 这样的 API 调用。你到底应该怎么做?我一直在使用以下代码,但没有取得多大成功:

private static final SimpleDateFormat mSegmentStartTimeFormatter = new        SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

Calendar calendar = Calendar.getInstance();

    try {
        calendar.setTime(mSegmentStartTimeFormatter.parse(startTime));
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return calendar.getTimeInMillis();

示例输入值:[2012-08-15T22:56:02.038Z]

应该返回相当于[2012-08-15T15:56:02.038Z]

【问题讨论】:

    标签: java api date calendar timezone


    【解决方案1】:

    Date 没有时区,内部存储为 UTC。只有当日期被格式化时,时区更正才适用。使用DateFormat 时,它默认为其运行所在的JVM 的时区。根据需要使用setTimeZone 进行更改。

    DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    
    Date date = utcFormat.parse("2012-08-15T22:56:02.038Z");
    
    DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
    pstFormat.setTimeZone(TimeZone.getTimeZone("PST"));
    
    System.out.println(pstFormat.format(date));
    

    这打印2012-08-15T15:56:02.038

    请注意,我在 PST 格式中省略了 'Z',因为它表示 UTC。如果您只是使用Z,那么输出将是2012-08-15T15:56:02.038-0700

    【讨论】:

    • 酷,它确实有效。我可以通过调用 TimeZone.getDefault() 来获取 Android 设备的默认时区。
    • 没有变化,和UTC时间一样,怎么办?
    【解决方案2】:

    这是一个简单修改的​​解决方案

        public String convertToCurrentTimeZone(String Date) {
                String converted_date = "";
                try {
    
                    DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    
                    Date date = utcFormat.parse(Date);
    
                    DateFormat currentTFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone()));
    
                    converted_date =  currentTFormat.format(date);
                }catch (Exception e){ e.printStackTrace();}
    
                return converted_date;
        }
    
    
        //get the current time zone
    
        public String getCurrentTimeZone(){
                TimeZone tz = Calendar.getInstance().getTimeZone();
                System.out.println(tz.getDisplayName());
                return tz.getID();
        }
    

    【讨论】:

      【解决方案3】:

      使用现代 Java 日期和时间 API,这很简单:

          String inputValue = "2012-08-15T22:56:02.038Z";
          Instant timestamp = Instant.parse(inputValue);
          ZonedDateTime losAngelesTime = timestamp.atZone(ZoneId.of("America/Los_Angeles"));
          System.out.println(losAngelesTime);
      

      打印出来

      2012-08-15T15:56:02.038-07:00[America/Los_Angeles]
      

      注意事项:

      • 您的期望中有一个小错误。时间戳中的Z 表示UTC,也称为祖鲁时间。因此,在您的本地时间值中,Z 不应该存在。相反,您需要一个返回值,例如 2012-08-15T15:56:02.038-07:00,因为偏移量现在是 -7 小时而不是 Z。
      • 避免使用三个字母的时区缩写。它们不是标准化的,因此通常是模棱两可的。例如,PST 可能表示菲律宾标准时间、太平洋标准时间或皮特凯恩标准时间(尽管缩写中的 S 通常表示夏令时(表示 DST))。如果您打算使用太平洋标准时间,那甚至不是时区,因为在夏季(您的示例时间戳所在的位置)使用的是太平洋夏令时间。在我的代码中,使用 region/city 格式的时区 ID 而不是缩写。
      • 时间戳通常最好作为Instant 对象处理。仅在需要时转换为 ZonedDateTime,例如用于演示。

      问题:我可以在我的 Java 版本中使用现代 API 吗?

      如果至少使用 Java 6,则可以。

      【讨论】:

        猜你喜欢
        • 2019-08-15
        • 2011-02-06
        • 2013-09-12
        • 2019-03-09
        • 2018-04-17
        • 2019-01-05
        • 2013-03-23
        • 2018-09-17
        • 2015-04-20
        相关资源
        最近更新 更多