我收到一个代表utc日期时间的日期。让我们说:201年6月21日至10月10日
我想把这个日期时间转换为“欧洲/维也纳”期待的时区:21-Jun-2019 12:00
我不明白,为什么下面的代码显示两者的相同时间
Date utcFinish = new Date(new Date().getYear(), Calendar.JUNE, 21);
TimeZone europeVienna = TimeZone.getTimeZone("Europe/Vienna");
Calendar finishInViennaTime = Calendar.getInstance(europeVienna);
finishInViennaTime.setTime(utcFinish);
System.out.println(format.format(utcFinish));
System.out.println(format.format(finishInViennaTime.getTime()));
输出:
2019-06-21 00:00
2019-06-21 00:00
什么是最好的java7(没有joda,localdate请)解决方案!?谢谢
编辑:我也尝试过:
SimpleDateFormat formatWithTimezone = new SimpleDateFormat("yyyy-MM-dd HH:mm");
formatWithTimezone.setTimeZone(TimeZone.getTimeZone("Europe/Vienna"));
SimpleDateFormat formatonly = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date utcDate = new Date(new Date().getYear(), Calendar.JUNE, 21);
System.out.println(formatonly.format(utcDate));
System.out.println(formatWithTimezone.format(utcDate));
输出:
2019-06-21 00:00
2019-06-21 00:00
解
感谢所有的解决方案。最后问题是默认时区。这是我目前的解决方案(欢迎进一步反馈!):
// Unfortunately this date has the wrong time zone (Local Time Zone),
// because Date assumes Local Time Zone the database stores timestamps
// in utc that's why I now convert to a datestring and reparse
Date finishTimeWrongTimeZone = new Date(new Date().getYear(), Calendar.JUNE, 21);
// in reality i call the db here like getFinishTime();
// get the plain date string without time shifting
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MMM-dd HH:mm");
String dateWithoutTimeZone = formatter.format(finishTimeWrongTimeZone);
// add the timezone to the formatter and reinterpret the datestring
// effectively adding the correct time zone the date should be in
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String finishTime = null;
try {
Date dateWithCorrectTimeZone = formatter.parse(dateWithoutTimeZone);
// Convert to expected local time zone (europe/vienna)
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Vienna"));
finishTime = formatter.format(dateWithCorrectTimeZone);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(finishTime);
在执行格式之前更改时区。日期将相应地“转换”,但正如我们已经告诉过你的那样,这种旧的编码风格有很多缺陷:
public static void main(String[] x) {
Date instant = new Date(new Date().getYear(), Calendar.JUNE, 21); // this call assumes the Timezone is your current default (system dependant).
DateFormat sdf = SimpleDateFormat.getDateTimeInstance();
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Vienna"));
System.out.println(sdf.format(instant)); //21 juin 2019 00:00:00
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Greenwich"));
System.out.println(sdf.format(instant)); // 20 juin 2019 22:00:00
}
我使用一个格式化程序对象并更改它的时区
SimpleDateFormat format = new SimpleDateFormat(“dd-MM-yyyy HH:mm”); format.setTimeZone(TimeZone.getTimeZone( “UTC”));
Date dUtc = format.parse("21-06-2019 10:00");
System.out.println(dUtc);
TimeZone europeVienna = TimeZone.getTimeZone("europe/vienna");
format.setTimeZone(europeVienna);
String sVienna = format.format(dUtc);
System.out.println(sVienna);
java.time
) solution我有一个旧API的版本,就像你问的那样,但为了完整性,我还将提供更现代的解决方案。如果不能更新Java,我建议您查看ThreeTen-Backport:
ZonedDateTime zdt = LocalDateTime.of(
Year.now().getValue(), Month.JUNE, 21, 10, 0, 0
).atZone(ZoneOffset.UTC);
System.out.println(
zdt.withZoneSameInstant(ZoneId.of("Europe/Vienna"))
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm"))
);
java.util
) solutionnew Date(...)
已被弃用,您不应该使用它。如果你真的需要坚持旧的API;你需要使用Calendar
:
Calendar utcFinish = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
utcFinish.set(Calendar.MONTH, Calendar.JUNE);
utcFinish.set(Calendar.DATE, 21);
utcFinish.set(Calendar.HOUR_OF_DAY, 10);
utcFinish.set(Calendar.MINUTE, 0);
然后使用DateFormat
与您实际希望打印的时区:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
TimeZone europeVienna = TimeZone.getTimeZone("Europe/Vienna");
format.setTimeZone(europeVienna);
System.out.println(format.format(utcFinish.getTime()));
两种解决方案都应该输出(在写作时,2019年):
2019-06-21 12:00
请使用SimpleDateFormat转换时区
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date utcFinish = new Date(new Date().getYear(), Calendar.JUNE, 21);
TimeZone europeVienna = TimeZone.getTimeZone("Europe/Vienna");
format.setTimeZone(europeVienna);
System.out.println(format.format(utcFinish));