这里有几个步骤。第一种是将基于时间的UUID的时间戳(从1582年10月15日开始,以100纳秒为单位)转换为与Java的日期功能兼容的时间戳(即,从1970年1月1日起,以毫秒为单位)。显然,您要求的精度要高于毫秒。
接下来,我们需要将该日期解释为正确的时区。
最后,我们需要将其格式化为所需格式的文本。
代码如下:
// this is the difference between midnight October 15,1582 UTC and midnight January 1,1970 UTC as 100 nanosecond units
private static final long EPOCH_DIFFERENCE = 122192928000000000L;
private static final ZoneId GREENWICH_MEAN_TIME = ZoneId.of("GMT");
private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
.appendText(DAY_OF_WEEK,FULL)
.appendLiteral(",")
.appendText(MONTH_OF_YEAR,FULL)
.appendLiteral(' ')
.appendValue(DAY_OF_MONTH)
.appendLiteral(",")
.appendValue(YEAR,4)
.appendLiteral(" at ")
.appendValue(CLOCK_HOUR_OF_AMPM)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR,2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE,2)
.appendLiteral('.')
.appendFraction(NANO_OF_SECOND,7,false)
.appendLiteral(' ')
.appendText(AMPM_OF_DAY)
.appendLiteral(' ')
.appendZoneText(FULL)
.toFormatter(Locale.getDefault());
public static String formattedDateFromTimeBasedUuid(UUID uuid) {
ZonedDateTime date = timeBasedUuidToDate(uuid);
return FORMATTER.format(date);
}
public static ZonedDateTime timeBasedUuidToDate(UUID uuid) {
if (uuid.version() != 1) {
throw new IllegalArgumentException("Provided UUID was not time-based.");
}
// the UUID timestamp is in 100 nanosecond units.
// convert that to nanoseconds
long nanoseconds = (uuid.timestamp() - EPOCH_DIFFERENCE) * 100;
long milliseconds = nanoseconds / 1000000000;
long nanoAdjustment = nanoseconds % 1000000000;
Instant instant = Instant.ofEpochSecond(milliseconds,nanoAdjustment);
return ZonedDateTime.ofInstant(instant,GREENWICH_MEAN_TIME);
}
为了方便重用,我将这些方法和常量放在实用程序类中。
一些注意事项:
- 此处有很多静态导入的常量。它们来自
java.time.format.TextStyle
和java.time.temporal.ChronoField
。
- 我使用了
DateTimeFormatterBuilder
而不是更常见的DateTimeFormatter.forPattern(String)
。我发现它更具可读性,并愿意容忍由此产生的冗长。
- 我对您想要的格式做了一件事:您要求时间为
2:06:30:001
;这段代码产生2:06:30.001
-在秒和毫秒之间的小数点,而不是冒号。这是更正确的方法,但是如果您更喜欢冒号,只需更改相应的.appendLiteral('.')
即可通过冒号。
- 您经常会找到示例代码,它们内联定义了DateTimeFormatters,ZoneIds等。这些类是线程安全的和可重用的,因此为了获得最佳结果,您应该像在此所做的那样将它们定义为常量。您将获得更好的性能并减少内存使用。
- 请注意,DataStax驱动程序的
Uuids
类使用系统时钟的毫秒精度值作为输入,因此除非您实现自己的基于纳秒的变量,否则您只会在最后四个位置看到零。您可以使用System.nanoTime()
来做到这一点,但有一些麻烦-check out the note on the JavaDoc for more。
要确定两个ZonedDateTime之间的时间量,只需执行以下操作:
Duration duration = Duration.between(date1,date2);
Duration
类具有several useful methods,可用于解释结果。
本文链接:https://www.f2er.com/3137233.html