我正在秒内从服务器接收数据,我想将其转换为日期。
但是我收到的秒数不是从UNIX时代01/01/1970开始而是2000年1月1日。
通常我会使用:
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.US);
String dateString = formatter.format(new Date(millisToConvert));
将millisConvert转换为我收到的毫秒数。但是现在,自然而然地,我会得出错误的日期,因为出处不同。如何更改纪元(原点)?
答案 0 :(得分:2)
OffsetDateTime.of( 2000 , 1 , 1 , 0 , 0 , 0 , 0 , ZoneOffset.UTC ) // Define your epoch reference moment.
.pluSeconds( yourSeconds ) // Add the number of seconds given to you. Returns another `OffsetDateTime` object rather than altering the original (immutable objects pattern).
.toLocalDate() // Extract a date-only value without time-of-day and without offset-from-UTC.
使用现代的 java.time 类代替了可怕的旧遗留类,例如Date
和Calendar
。
Instant
Instant
代表UTC的时刻。
定义您特定的纪元参考日期时间。
Instant epoch = Instant.parse( "2000-01-01T00:00Z" ) ;
添加您的秒数。
Instant later = epoch.plusSeconds( yourSecondsGoHere ) ;
OffsetDateTime
如果您要使用没有日期和时区的仅日期值,请使用LocalDate
类。首先,将基本类型Instant
转换为更灵活的OffsetDateTime
,将常量ZoneOffset.UTC
指定为偏移量。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
LocalDate
提取仅日期值。
LocalDate ld = odt.toLocalDate() ;
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:1)
加上946080000秒来解决30年的差异,纪元时间应该是长值
答案 2 :(得分:0)
与Basil建议的答案不同的另一种方法。 Basil建议的内容仅适用于API级别26及更高版本,即Android 8.0.0。如今,在2018年年中之后,Android 8.0.0非常罕见,因此许多设备都没有此功能。
所以我写了这个算法:
private long getDateInMilliSeconds (long secondsSinceRippleEpoch){
Locale.setDefault(Locale.US);
if (Build.VERSION.SDK_INT >= 26) { //**WHAT BASIL SUGGESTED**
LocalDateTime desiredDate = OffsetDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)
.plusSeconds(secondsSinceRippleEpoch)
.toLocalDateTime();
Date convertedDate = Date.from(desiredDate.atZone(ZoneId.systemDefault()).toInstant());
return convertedDate.getTime();
} else { //MY SOLUTION. Works for both but still I wanted to use the upper
//for higher APIs.
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.US);
String dateString = formatter.format(new Date((secondsSinceRippleEpoch+946684800)*1000L )); //To not to cause overflow, use L at the end.
try {
Date wantedDate = formatter.parse(dateString);
return wantedDate.getTime();
} catch (ParseException e) {
e.printStackTrace();
return 200000;
}
}
希望这对将来的访客有帮助。