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"