在 java 语言中,如何将纳秒值,例如 1568694302232954486 和 1568703521360049938 转换为 Java 日期对象?
In java language, how to convert nano seconds value, for example 1568694302232954486 and 1568703521360049938 into a Java Date object?
我有很多看起来像 1568694302232954486 和 1568703521360049938 的长数字,我需要将它们中的每一个都转换成一个 Java 日期对象。
如何在Java8中实现上述需求?
我还需要将纳秒值转换为 elasticsearch 的时间戳,并找到了正确的方法;感谢大家的帮助!
以下代码块已通过测试,仅供需要者参考。它实际上是 logstash 配置文件的一部分:
ruby {
init => ""
code => "
event.set('time_local',event.get('time_local').to_f*0.000001)
"
}
date {
#15/Aug/2019:14:46:19 +0800 [02/Sep/2019:09:28:33 +0800]
match => [ "time_local" , "yyyy-MM-dd HH:mm:ss,SSS","UNIX_MS"]
timezone => "Asia/Shanghai"
target => "@timestamp"
}
如果你想要它作为一个 Date
对象,那么你将丢失一些信息,因为 Date
只有毫秒精度。 Date
在 Java 8 中也已过时,因此如果您使用 Java 8 或更高版本,请考虑改用 Instant
。
这是转换为 Date
的方法。不要这样做,除非你真的必须这样做。
long nano = 1568694302232954486L;
Date d = new Date(nano / 1000000); // 1000000 is how many nanoseconds there are in a millisecond
另一方面,Instant
具有纳秒精度,这是您应该做的:
// 1000000000 is how many nanoseconds there are in a second.
Instant i = Instant.ofEpochSecond(nano / 1000000000, nano % 1000000000);
java.time
知道怎么做就很容易了。虽然双参数 Instant.ofEpochSecond()
的第二个参数名为 nanoAdjustment
,但它的类型为 long
,并且该方法接受在此参数中传递的完整 nano 值。所以只需将 0 作为秒传递,并将转换留给方法:
Instant instant1 = Instant.ofEpochSecond(0, 1_568_694_302_232_954_486L);
System.out.println(instant1);
Instant instant2 = Instant.ofEpochSecond(0, 1_568_703_521_360_049_938L);
System.out.println(instant2);
输出为:
2019-09-17T04:25:02.232954486Z
2019-09-17T06:58:41.360049938Z
如果您确实需要一个老式的 Date
旧对象 API,您现在无法更改或不想升级:
Date oldfashionedDate1 = Date.from(instant1);
System.out.println(oldfashionedDate1);
在我的电脑上,转换后的 Date
打印为:
Tue Sep 17 06:25:02 CEST 2019
不过,通常要避免 Date
class。它设计不佳且早已过时。使用 java.time,现代 Java 日期和时间 API,要好得多。
Link: Oracle tutorial: Date Time 解释如何使用 java.time.
我有很多看起来像 1568694302232954486 和 1568703521360049938 的长数字,我需要将它们中的每一个都转换成一个 Java 日期对象。
如何在Java8中实现上述需求? 我还需要将纳秒值转换为 elasticsearch 的时间戳,并找到了正确的方法;感谢大家的帮助!
以下代码块已通过测试,仅供需要者参考。它实际上是 logstash 配置文件的一部分:
ruby {
init => ""
code => "
event.set('time_local',event.get('time_local').to_f*0.000001)
"
}
date {
#15/Aug/2019:14:46:19 +0800 [02/Sep/2019:09:28:33 +0800]
match => [ "time_local" , "yyyy-MM-dd HH:mm:ss,SSS","UNIX_MS"]
timezone => "Asia/Shanghai"
target => "@timestamp"
}
如果你想要它作为一个 Date
对象,那么你将丢失一些信息,因为 Date
只有毫秒精度。 Date
在 Java 8 中也已过时,因此如果您使用 Java 8 或更高版本,请考虑改用 Instant
。
这是转换为 Date
的方法。不要这样做,除非你真的必须这样做。
long nano = 1568694302232954486L;
Date d = new Date(nano / 1000000); // 1000000 is how many nanoseconds there are in a millisecond
另一方面,Instant
具有纳秒精度,这是您应该做的:
// 1000000000 is how many nanoseconds there are in a second.
Instant i = Instant.ofEpochSecond(nano / 1000000000, nano % 1000000000);
java.time
知道怎么做就很容易了。虽然双参数 Instant.ofEpochSecond()
的第二个参数名为 nanoAdjustment
,但它的类型为 long
,并且该方法接受在此参数中传递的完整 nano 值。所以只需将 0 作为秒传递,并将转换留给方法:
Instant instant1 = Instant.ofEpochSecond(0, 1_568_694_302_232_954_486L);
System.out.println(instant1);
Instant instant2 = Instant.ofEpochSecond(0, 1_568_703_521_360_049_938L);
System.out.println(instant2);
输出为:
2019-09-17T04:25:02.232954486Z 2019-09-17T06:58:41.360049938Z
如果您确实需要一个老式的 Date
旧对象 API,您现在无法更改或不想升级:
Date oldfashionedDate1 = Date.from(instant1);
System.out.println(oldfashionedDate1);
在我的电脑上,转换后的 Date
打印为:
Tue Sep 17 06:25:02 CEST 2019
不过,通常要避免 Date
class。它设计不佳且早已过时。使用 java.time,现代 Java 日期和时间 API,要好得多。
Link: Oracle tutorial: Date Time 解释如何使用 java.time.