我有一个 UTC 时间长值:1555415100000L
我使用此源代码按时区转换为本地时间。
//data.getTime() = 1555415100000L
String timeFormat = "HH:mm";
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
long gmtTime = Long.parseLong(data.getTime()) + TimeZone.getDefault().getRawOffset();
String timeString = sdf.format(new Date(gmtTime));
在 GMT+7 时:时间字符串 = 01:45(正确)
但在 GMT+6.5 时:timeString = 00:45(不正确)-> 应该是 01:15
您有什么建议可以按本地更正时间吗?
几件事:
-
通过添加或减去偏移量来操作时间戳从来都不是转换时区的正确方法,在任何语言中。 始终查找允许您改用时区标识符的 API。 如果您操纵时间戳,则故意选择不同的时间点。 这与调整本地时区的概念不同。
-
世界上只有两个时区使用 +6.5。 它们是
Asia/Yangon
(在缅甸)和Indian/Cocos
(在科科斯/基林群岛)。 您应该改用其中之一。 -
您关于该时间戳的本地时间的断言不正确。
1555415100000
对应于 UTC 时间2019-04-16T11:45:00.000Z
- 偏移量为 +7,即
2019-04-16T18:45:00.000+07:00
(18:45,而不是您所说的 01:45) - 偏移量为 +6.5,即
2019-04-16T18:15:00.000+06:30
(18:15,而不是您所说的 01:15)
-
您应该考虑使用 Java 8 中引入的
java.time
包。 在Android上,您可以使用ThreeTenABP库,这是Android版java.time API的反向移植。import java.time.*; import java.time.format.*; ... long time = 1555415100000L; Instant instant = Instant.ofEpochMilli(time); ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Yangon")); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm"); System.out.println(formatter.format(zonedDateTime)); //=> "18:15"
-
如果您真的坚持使用较旧的日期和时间 API,尽管它们存在所有非常有据可查的问题,那么您需要设置格式化程序的时区,而不是操作时间戳。
import java.util.*; import java.text.*; ... long time = 1555415100000L; long date = new Date(time)); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); sdf.setTimeZone(TimeZone.getTimeZone("Asia/Yangon")); System.out.println(sdf.format(date); //=> "18:15"
请尝试正常转换它,例如,
long time = 1555415100000L;
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
我在在线 java 编译器中获得的输出: 19-4-16 上午11:45
或者如果将其转换为格林威治标准时间,
long time = 1555415100000L;
Date date = new Date(time);
DateFormat gmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
gmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(gmt.format(date));
在线编译器中的输出:2019 年 4 月 16 日上午 11:45:00 GMT
希望这有帮助。