将日期时间转换为其他时区

x0fgdtte  于 2021-07-06  发布在  Java
关注(0)|答案(4)|浏览(334)

如何使用java将日期时间转换为其他时区。
示例:2021年6月11日20:00至2021年6月11日06:00 pm

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date parsed = format.parse("2021-03-01 20:00");

* \\to//*

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm z");
Date parsed = format.parse("2021-03-01 06:00 PM");

这样地

ct3nt3jp

ct3nt3jp1#

解决方案的关键是获得两个日期时间之间的区域偏移量,您可以使用该偏移量进行计算 Duration#between 然后将第一个日期时间的区域偏移量更改为第二个日期时间的区域偏移量(等于计算的持续时间的小时和分钟部分)。

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Given date-time strings
        String strOne = "11 June 2021 20:00";
        String strTwo = "11 June 2021 06:00 PM";

        // Respective formatters
        DateTimeFormatter dtfOne = DateTimeFormatter.ofPattern("dd MMMM uuuu HH:mm", Locale.ENGLISH);
        DateTimeFormatter dtfTwo = DateTimeFormatter.ofPattern("dd MMMM uuuu hh:mm a", Locale.ENGLISH);

        // Respective instances of LocalDateTime
        LocalDateTime ldtOne = LocalDateTime.parse(strOne, dtfOne);
        LocalDateTime ldtTwo = LocalDateTime.parse(strTwo, dtfTwo);

        // Duration between the two date-times
        Duration duration = Duration.between(ldtOne, ldtTwo);
        int hours = duration.toHoursPart();
        int minutes = duration.toMinutesPart();

        // Zone offset with hours and minutes of the duration
        ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes(hours, minutes);

        //
        ZonedDateTime zdt = ldtOne.atZone(ZoneId.systemDefault())   // ZonedDateTime using JVM's time zone
                                .withZoneSameInstant(zoneOffset);   // ZonedDateTime using the given zone offset
        System.out.println(zdt);
        String formatted = zdt.format(dtfTwo);// Format the given ZonedDateTime using the given formatter
        System.out.println(formatted);
    }
}

api的日期时间 java.util 以及它们的格式化api, SimpleDateFormat 过时且容易出错。建议完全停止使用它们,并切换到现代日期时间api。在trail:date-time了解有关现代日期时间api的更多信息。
注意:如果您正在为一个android项目工作,并且您的android api级别仍然不符合java-8,请检查通过desugaring提供的java8+api以及如何在android项目中使用threetenabp。

lpwwtiir

lpwwtiir2#

你必须把你的日期格式放到一个特定的区域,因为你在帖子中没有提到,我将在下面给出一个示例,

SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yyyy-MM-dd HH:mm);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

现在用这个 simpleDateFormat 对于特定的时区,可以设置值的格式。

u5rb5r59

u5rb5r593#

首先,您应该使用新的Java8API来处理数据和时间, java.time 其次,您需要有一个区域进行转换。在这里,我假设您要使用设备的区域(并转换为gmt)作为from,gmt作为to。

String input = "2021-03-01 20:00";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(ZoneId.systemDefault());
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd h:mm a").withZone(ZoneId.of("GMT"));

TemporalAccessor date = inputFormatter.parse(input);
String output = outputFormatter.format(date);
System.out.println(output);
d4so4syb

d4so4syb4#

joakim danielson的回答是正确的:使用java.time,现代的java日期和时间api,进行日期和时间工作。我的解决方案大致遵循相同的总体模式。我想给你看一些细节。

private static final DateTimeFormatter inputFormatter
        = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
private static final DateTimeFormatter outputFormatter
        = DateTimeFormatter.ofPattern("yyyy-MM-dd h:mm a");
``` `DateTimeFormatter` 是线程安全的,所以即使从不同的线程使用它们,也可以只示例化一次。

String input = "2021-03-01 20:00";

String output = LocalDateTime.parse(input, inputFormatter)
        .atZone(ZoneId.systemDefault())
        .withZoneSameInstant(ZoneOffset.UTC)
        .format(outputFormatter);
System.out.println(output);
输出与joakim的代码相同。在我的时区(欧洲/哥本哈根)是:
2021-03-01下午7:00
java.time非常适合流畅的写作风格。为什么不利用它呢?因为转换到不同的时区是关键,所以我更喜欢在代码中明确表示。这个 `withZoneSameInstant()` 呼叫进行转换。我更倾向于分析成 `LocalDateTime` 或者 `ZonedDateTime` 而不是用低级的 `TemporalAccessor` 直接接口。接口的文档说明:
此接口是框架级接口,不应在应用程序代码中广泛使用。相反,应用程序应该创建并传递具体类型的示例,例如 `LocalDate` . 这有很多原因,其中一部分原因是这个接口的实现可能在iso以外的日历系统中…

### 我需要api 21支持。这在api 21上不可用

实际上java.time在androidapi级别21上运行得很好。
在Java8和更高版本以及更新的android设备上(api级别26),现代api是内置的。
在非android的java6和java7中获得了三个十的backport,即现代类的backport(三个十用于jsr310;请参见底部的链接)。
在旧的android上,要么使用desugaring,要么使用android版本的threeten backport。它叫3TENABP。在后一种情况下,请确保从导入日期和时间类 `org.threeten.bp` 有分装的。

### 链接

oracle教程:date time解释如何使用java.time。
文件 `TemporalAccessor` 问题:无法解决android studio中关于在早期andoird上使用java.time的符号“java.time.localdate”错误
问:android-api第21级的日期[关闭]
java规范请求(jsr)310,其中 `java.time` 第一次被描述。
三十后港工程 `java.time` 到Java6和Java7(jsr-310为310)。
通过desugaring提供Java8+API
threetenabp,android版threeten backport
问:如何在android项目中使用threetenabp,有非常透彻的解释。

相关问题