SImpleDateFormat return GMT + 6.5 的错误值
SImpleDateFormat return wrong value with GMT + 6.5
我有一个 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:timeString = 01:45(正确)
但在 GMT+6.5:timeString = 00:45(不正确)-> 应该是 01:15
你有什么建议用当地校正时间吗?
请尝试正常转换,例如,
long time = 1555415100000L;
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
我在网上得到的输出java compiler: 4/16/19 11:45 AM
或者如果将其转换为 GMT,
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 AM GMT
希望对您有所帮助。
几件事:
通过添加或减去偏移量来操作时间戳永远不是转换时区的正确方法,在任何语言中都是如此。始终寻找允许您使用 time zone identifiers 的 API。如果您操纵时间戳,您就是在故意选择一个 不同的 时间点。这与调整本地时区的概念不同。
世界上只有两个时区使用+6.5。它们是Asia/Yangon
(在缅甸)和Indian/Cocos
(在Cocos/Keeling群岛)。您应该改用其中之一。
您关于该时间戳的本地时间的断言是不正确的。
1555415100000
对应2019-04-16T11:45:00.000Z
的UTC时间
- 偏移+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.time
package, introduced with Java 8. On Android, you can use the ThreeTenABP library,java.time API 的向后移植 Android。
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"
如果你真的坚持使用较旧的日期和时间 APIs,尽管它们的所有问题都有很好的记录,那么你需要设置格式化程序的时区而不是操纵时间戳。
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"
我有一个 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:timeString = 01:45(正确)
但在 GMT+6.5:timeString = 00:45(不正确)-> 应该是 01:15
你有什么建议用当地校正时间吗?
请尝试正常转换,例如,
long time = 1555415100000L;
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(time)));
我在网上得到的输出java compiler: 4/16/19 11:45 AM
或者如果将其转换为 GMT,
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 AM GMT
希望对您有所帮助。
几件事:
通过添加或减去偏移量来操作时间戳永远不是转换时区的正确方法,在任何语言中都是如此。始终寻找允许您使用 time zone identifiers 的 API。如果您操纵时间戳,您就是在故意选择一个 不同的 时间点。这与调整本地时区的概念不同。
世界上只有两个时区使用+6.5。它们是
Asia/Yangon
(在缅甸)和Indian/Cocos
(在Cocos/Keeling群岛)。您应该改用其中之一。您关于该时间戳的本地时间的断言是不正确的。
1555415100000
对应2019-04-16T11:45:00.000Z
的UTC时间
- 偏移+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.time
package, introduced with Java 8. On Android, you can use the ThreeTenABP library,java.time API 的向后移植 Android。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"
如果你真的坚持使用较旧的日期和时间 APIs,尽管它们的所有问题都有很好的记录,那么你需要设置格式化程序的时区而不是操纵时间戳。
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"