【问题标题】:Change time zone of exesting date in Java更改Java中现有日期的时区
【发布时间】:2021-06-10 13:09:46
【问题描述】:

我想更改给定日期的时区。我使用这段代码,但我没有好的结果。 我的输入是欧洲/巴黎的“2020-06-16 14:00:00”时间,我想将其更改为 UTC,这意味着我想得到“2020-06-16 12:00:00”,但是我得到初步结果“2020-06-16 14:00:00”。

try {
    // Calendar calParis = Calendar.getInstance();
    String heure = "1400";
    Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2020-06-16");

    String hour = heure.substring(0, heure.length() - 2);
    String minute = heure.substring(heure.length() - 2);
    Calendar cal = Calendar.getInstance();
    String datenew = "2020-06-16" + " " + hour + ":" + minute + ":00";
    SimpleDateFormat sdfDatenew = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
    Date thisDate = sdfDatenew.parse(datenew);
    cal.setTime(thisDate);

    cal.setTimeZone(TimeZone.getTimeZone("Europe/UTC"));
    SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
    String dateISO = null;
    dateISO = sdfDate.format(cal.getTime());

    System.out.println("Time in ISO: " + dateISO);

} catch (Exception ex) {

}

【问题讨论】:

  • 我在这里找到了您问题的答案stackoverflow.com/questions/2891361/…
  • 这能回答你的问题吗? How to set time zone of a java.util.Date?
  • 我测试了代码 SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));日期日期 = isoFormat.parse("2010-05-23T09:01:02");但它不起作用
  • 你能用ZonedDateTimeZoneId吗?那么解决方案可能很简单。
  • ... 还是 OffsetDateTimeZoneOffset.UTC?这意味着使用java.time 而不是java.util.Datejava.text.SimpleDateFormat

标签: java timezone


【解决方案1】:

给你: 这样您就可以获取 Java-7 格式的日期和时间。

public static void main(String[] args) throws ParseException {
        String heure = "1400";
        Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2020-06-16");
        String hour = heure.substring(0, heure.length() - 2);
        String minute = heure.substring(heure.length() - 2);
        String datenew = "2020-06-16" + " " + hour + ":" + minute + ":00";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Calendar calendar = Calendar.getInstance();
        Date thisDate = sdf.parse(datenew);
        calendar.setTime(thisDate);
        sdf.setTimeZone(TimeZone.getTimeZone("PDT"));
        System.out.println(sdf.format(calendar.getTime())); // prints 2020-06-16 12:00:00
        sdf.setTimeZone(TimeZone.getDefault());
        System.out.println(sdf.format(calendar.getTime())); // prints 2020-06-16 14:00:00
    }

【讨论】:

  • 这些日期时间类是可怕的,避免它们。对于 Java 8 及更高版本,使用内置的 java.time 类。对于 Java 6 和 7,请使用 java.timeThreeTen-Backport 库的后向端口。
【解决方案2】:

tl;博士

LocalDateTime
.parse( 
    "2020-06-16 14:00:00"
    .replace( " " , "T" ) 
)
.atZone(
    ZoneId.of( "Europe/Paris" )
)
.toInstant()
.atOffset( ZoneOffset.UTC )
.format(
    DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" )
)

看到这个code run live at IdeOne.com

2020-06-16 12:00:00

java.time

现代解决方案使用 java.time 类。

您的输入字符串缺少时区或偏移量。所以解析为LocalDateTime 对象。

LocalDateTime ldt = LocalDateTime.parse( "2020-06-16 14:00:00".replace( " " , "T" ) ) ;

你肯定地说这个字符串代表了在法国巴黎时区看到的时刻。

ZoneId zParis = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = ldt.atZone( zParis ) ;

从那里调整到您的目标时区。您恰好需要 UTC,因此只需提取 Instant

Instant instant = zdt.toInstant() ;

【讨论】:

    【解决方案3】:

    java.time

    java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并改用 modern Date-Time API*,它于 2014 年 3 月作为 Java SE 8 标准库的一部分发布。

    answer by Basil Bourque 是正确的,但当DateTimeFormatter 足以解决这个问题以及更多问题时,我不会使用String 替换。

    演示:

    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            String input = "2020-06-16 14:00:00";
            DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH);
    
            LocalDateTime ldt = LocalDateTime.parse(input, dtfInput);
            ZonedDateTime zdtParis = ldt.atZone(ZoneId.of("Europe/Paris"));
    
            ZonedDateTime zdtUtc = zdtParis.withZoneSameInstant(ZoneId.of("Etc/UTC"));
    
            // Default format
            System.out.println(zdtUtc);
    
            // Custom format
            DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
            String output = dtfOutput.format(zdtUtc);
            System.out.println(output);
        }
    }
    

    输出:

    2020-06-16T12:00Z[Etc/UTC]
    2020-06-16 12:00:00
    

    ONLINE DEMO

    全部在一个语句中:

    System.out.println(
            LocalDateTime
            .parse("2020-06-16 14:00:00", DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH))
            .atZone(ZoneId.of("Europe/Paris"))
            .withZoneSameInstant(ZoneId.of("Etc/UTC"))
            .format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH))
    );
    

    ONLINE DEMO

    一些重要说明:

    1. 您可以对输入和输出字符串使用单一模式uuuu-MM-dd HH:mm:ss,但我更喜欢使用u-M-d H:m:s 进行解析,因为如果您有两位数的年份和一位数的月份,uuuu-MM-dd HH:mm:ss 将失败,单个数字的月份日期等。对于解析,单个u 可以同时满足两位数和四位数字的年份表示。同样,单个M 可以同时满足一位数和两位数的月份。其他符号也是如此。
    2. 在这里,您可以使用y 代替u,但可以使用I prefer u to y

    Trail: Date Time 了解有关现代日期时间 API 的更多信息。


    * 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 2017-06-28
      • 2014-02-16
      相关资源
      最近更新 更多