在我的应用程序中,第三方API返回时间戳中的时间戳。
有时它以秒为单位返回纪元时间,有时以毫秒为单位返回未确认。我的应用程序使用下面的代码 将它转换为java日期并显示给用户,但是当我以毫秒为单位收到时间时,它会在一年内失败。
String time = "1519377196185"; //Time in miliseconds
//String time = "1521575819"; //Time in seconds.
String timeZone = "US/Pacific";
long epochdate = Long.parseLong(time);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy hh:mm a");
LocalDateTime date34 =
Instant.ofEpochSecond(epochdate)
.atZone(ZoneId.of(timeZone))
.toLocalDateTime();
String date = date34.format(formatter).toString();
System.out.println("date : " + date);
如果我使用Instant.ofEpochMilli(epochdate)
毫秒,那么它工作正常。所以我的问题是我怎么知道即将到来的时间戳是以毫秒或秒为单位所以在此基础上我会在ofEpochMilli
和ofEpochSecond
之间切换
答案 0 :(得分:0)
一个简单(临时,类似)解决方案就是检查time
String
的长度。如果长度等于13
,则表示毫秒。在1 ms
2286-11-20T17:46:39.999Z
之后,这将是真实的,这是很长一段时间。以秒为单位的时间需要更长的时间才能达到13
的长度。
答案 1 :(得分:0)
您可以通过以秒为单位将纪元转换为纪元(以毫秒为单位)并仅对{8}同时应用Instant.ofEpochMilli()
来解决此问题。
String time = "1519377196185"; //Time in miliseconds or seconds
if(time.length() == 10) { // length of epoch in seconds is 10
time = time + "000";
}
String timeZone = "US/Pacific";
long epochdate = Long.parseLong(time);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy hh:mm a");
LocalDateTime date34 = Instant.ofEpochMilli(time)
.atZone(ZoneId.of(timeZone))
.toLocalDateTime();
String date = date34.format(formatter).toString();
System.out.println("date: " + date);
答案 2 :(得分:0)
如Jacob G. his Answer所述,检查长度。
String input = "1519377196185"; // Milliseconds since epoch.
//String input = "1519377196" ; // Seconds since epoch.
Instant instant = null;
int length = input.length();
switch ( length )
{
case 13:
instant = Instant.ofEpochMilli( Long.parseLong( input ) );
break;
case 10:
instant = Instant.ofEpochSecond( Long.parseLong( input ) );
break;
default:
throw new IllegalStateException( "Unexpected length of input text for count-from-epoch number: " + input + ". Message # 2188d054-5720-4393-9b18-829913d7ba1c." );
}
System.out.println( input + " ➞ " + instant.toString() ); // Generate a String representing textually the value of the `Instant` object.
1519377196185➞2018-02-23T09:13:16.185Z
或者:
1519377196➞2018-02-23T09:13:16Z
ZonedDateTime
要从Instant
中的UTC移动到某个特定时区,请提供时区(ZoneId
)的上下文以获取ZonedDateTime
对象。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString():2018-02-23T10:13:16.185 + 01:00 [非洲/突尼斯]
LocalDateTime
- 这里不合适要使用 LocalDateTime
类是错误的类,如问题所示。这个类故意缺乏任何时区概念或从UTC偏移。所以它不代表片刻,并且不时间轴上的一个点。此类表示在大约26-27小时范围内的潜在时刻。
仅在区域/偏移未知(可怕的情况)或需要无限期值时使用LocalDateTime
,例如“2018年12月25日第一时间的圣诞节开始”。
答案 3 :(得分:0)
年度偏差
我会尝试首先将日期解析为秒,因为如果日期是毫秒,则年份将是非常大的(在这种情况下为50000),那么如果年份不大于定义的年份偏差(例如, 3000),返回该日期,否则日期以毫秒返回。
getZonedDateTime("1519377196185"); // 2018-02-23T01:13:16.185-08:00[US/Pacific]
getZonedDateTime("1521575819"); // 2018-03-20T12:56:59-07:00[US/Pacific]
使用功能打印:
1970-01-01T00:00:00Z
错误保证金
您决定使用的任何方法都可能出错,并且日期转换不正确,特别是当日期以毫秒为单位并且距离纪元3000
太近时。
使用Instant.ofEpochMilli(LocalDateTime.of(3000, 1, 1, 0, 0) // year = 3000
.toEpochSecond(ZoneOffset.UTC)); // 1971-01-12T04:48:00Z
年份偏差的保证金误差为:
以毫秒为单位计算错误范围
您可以使用以下命令计算最初的日期误差范围(以毫秒为单位):
if (custDoe_TextField.isEditable()) {//isEditable returns boolean
//do something here
}