以毫秒为单位的字符串时间戳错误1小时

时间:2015-06-29 02:58:17

标签: java android timestamp sms

我从SmsMessage sms获取getTimestampMillis()并尝试将其转换为MM / dd / yy hh:mm a。

我正在使用下面的代码,除了提前一小时返回之外。例如6-28-15 9:22 pm,代码返回6-28-15 10:22 pm。我读过这是一个java bug,因为伦敦在1970年没有观察过GMT,或类似的东西。是否有修复或解决方法,不要求我在夏天减去一个小时,然后在夏令时后更改代码?

long time = currentMessage.getTimestampMillis();
                Log.i(TAG, "time stamp in millis= "+time);
                Time date = new Time(time);
                DateFormat format = new SimpleDateFormat("MM/dd/yy hh:mm a");
                String timestamp = format.format(date);
                Log.i(TAG, "Human readable timestamp= "+timestamp);

2 个答案:

答案 0 :(得分:2)

tl; dr

Instant.ofEpochMilli( millisSinceEpoch ) 

GMT代表mean solar time,实际上与UTC同义。请勿将其与观察到Europe/London的时区Daylight Saving Time (DST)混淆。

java.time

请勿使用java.sql.TimeDateFormat或任何与Java最早版本捆绑在一起的旧式日期时间类。

现代解决方案使用 java.time 类。

我认为您的毫秒数是自1970年1月1日世界协调时(UTC)1970-01-01T00:00Z以来的epoch reference

long millisSinceEpoch = currentMessage.getTimestampMillis();

转换为Instant对象。

Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;

根据定义,Instant始终采用UTC。因此,您不会对夏令时(DST)感到惊讶。

以标准ISO 8601格式生成文本。

String output = instant.toString() ;

您未指定示例值epoch毫秒。但是我们可以倒推来推断它。

// Example it is 6-28-15 9:22 
LocalDate ld = LocalDate.of( 2015 , Month.JUNE , 28 ) ;
LocalTime lt = LocalTime.of( 9 , 22 ) ;
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
Instant instant = odt.toInstant() ;
long epochMilli = instant.toEpochMilli() ;

1435483320000

请参阅此code run live at IdeOne.com


Table of all date-time types in Java, both modern and legacy


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规范为JSR 310

Joda-Time项目(现在位于maintenance mode中)建议迁移到java.time类。

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。 Hibernate 5和JPA 2.2支持 java.time

在哪里获取java.time类?

答案 1 :(得分:0)

UTC和GMT是两回事。 UTC不会经历DST,而GMT则会。两步:
1.找出你的主机实际使用的标准时间(java将使用它) 2.可能完全忽略它,并明确声明要使用的时区。

如果你发现玩时区是单调乏味,烦人且令人困惑,可以考虑使用库joda-time。它比内置的Java东西更通用,更舒适。