最近写代码时遇到需要转换将一个时间进行时区转换的问题,记录一下。
问题:
由于使用的account不同,从facebook取到的时间是诸如这样的形式"2019-05-05T22:48:52+0800"、“2019-05-05T22:48:52+0700”,但是由于业务需要,时间需要统一使用洛杉矶时区:ZoneId.of(“Asia/Shanghai”)。
解决:
- 首先使用ZonedDateTime+DateTimeFormatter将获取到的时间转换为带时区的时间对象;需要注意的是字符T属于时间格式化中的模式字母,如果想把它作为普通字符看待的话需要加’’ -> “yyyy-MM-dd’T’HH:mm:ssZ” 然后使用ZonedDateTime的withZoneSameInstant()方法,进行时间的转换,转换后时间会根据时区之间的时差自动转换。
- 注意withZoneSameInstant()和withZoneSameLocal()的区别:
- withZoneSameInstant() 会根据前后时区的时差,修改小时数;withZoneSameLocal() 维持年月日时分秒不变,仅修改时区。
示例代码:
public class ZoneDateTimeTest {
String timePattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(timePattern);
ZoneId losAngelesZoneId = ZoneId.of("America/Los_Angeles");
ZoneId beiJingZoneId = ZoneId.of("Asia/Shanghai");
@Test
public void transTimeZone () {
String dateTimeStr1 = "2019-05-05T22:48:52+0800";
String dateTimeStr2 = "2019-05-05T22:48:52+0700";
// String -> ZoneDateTime
ZonedDateTime zonedDateTime1 =
ZonedDateTime.parse(dateTimeStr1, dateTimeFormatter);
// 输出 2019-05-05T22:48:52+08:00
System.out.println(zonedDateTime1);
ZonedDateTime zonedDateTime2 =
ZonedDateTime.parse(dateTimeStr2, dateTimeFormatter);
// 输出 2019-05-05T22:48:52+07:00
System.out.println(zonedDateTime2);
// 1. ZoneDateTime(+0800) -> ZoneDateTime(-0800) 时间会会根据时区+/-
ZonedDateTime losAngelesZonedDateTime1 =
zonedDateTime1.withZoneSameInstant(losAngelesZoneId);
// 1.1 输出 2019-05-05T07:48:52-07:00[America/Los_Angeles]
System.out.println(losAngelesZonedDateTime1);
ZonedDateTime losAngelesZonedDateTime2 =
zonedDateTime2.withZoneSameInstant(losAngelesZoneId);
// 1.2 输出 2019-05-05T08:48:52-07:00[America/Los_Angeles]
System.out.println(losAngelesZonedDateTime2);
// 2. ZoneDateTime(+0800) -> ZoneDateTime(-0800) 时间不变,只改变时区
ZonedDateTime result = zonedDateTime1.withZoneSameLocal(beiJingZoneId);
// 输出 2019-05-05T22:48:52+08:00[Asia/Shanghai]
System.out.println(result);
}
}