我想更改给定日期的时区。我使用此代码,但我没有得到好的结果。 我的输入是欧洲/巴黎
的"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) {
}
你来了: 通过这种方式,您可以获取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
}
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" )
)
查看此代码在 IdeOne.com 实时运行。
2020-06-16 12:01: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() ;
java.time
java.util
日期-时间 API 及其格式设置 APISimpleDateFormat
已过时且容易出错。建议完全停止使用它们,并切换到 2014 年 3 月作为 Java SE 8 标准库的一部分发布的现代日期-时间 API*。
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
在线演示
全部在一个语句中:
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))
);
在线演示
一些重要注意事项:
- 您可以使用单个模式,
uuuu-MM-dd HH:mm:ss
输入和输出字符串,但我更喜欢使用u-M-d H:m:s
进行解析,因为如果您有两位数的年份、一位数的月份、一位数的月份、一位数的一天等,uuuu-MM-dd HH:mm:ss
就会失败。对于解析,单个u
可以同时满足两位数和四位数的年份表示。同样,单个M
可以同时满足一位数和两位数的月份。其他符号的情况类似。 - 在这里,您可以使用
y
而不是u
但我更喜欢u
而不是y
。
要了解有关现代日期-时间 API 的更多信息,请参阅跟踪:日期时间。
* 出于任何原因,如果你必须坚持使用 Java 6 或 Java 7,你可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请查看通过脱糖提供的 Java 8+ API 和如何在 Android Project 中使用 ThreeTenABP。