获取基于时间的 uuid,最多 100 纳秒
get timebased uuid's upto 100s of nanoseconds
我正在使用这个 libraryDependencies += "com.datastax.oss" % "java-driver-core" % "4.3.0"
库来创建基于时间的 uuid。虽然它生成基于时间的 uuid,但它给了我最多几秒钟,但我正在寻找 100 纳秒的值
import com.datastax.oss.driver.api.core.uuid.Uuids
println(Uuids.timeBased().toString)
输出 uuid 类似于 f642f350-0230-11ea-a02f-597f2801796a
对应于
Friday, November 8, 2019 at 2:06:30 PM Greenwich Mean Time
请帮助如何获得以毫秒为单位的时间
Friday, November 8, 2019 at 2:06:30:0000000Z PM Greenwich Mean Time
我想将时间戳转换成uuid格式进行测试(测试只接受uuid格式)。然后我会将 uuid 转换回时间以测量一些时差。
这里有几个步骤。第一个是将基于时间的 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, 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);
}
我会将这些方法和常量放在实用程序中 class 以便于重用。
几个注意事项:
- 这里有很多静态导入的常量。他们来自
java.time.format.TextStyle
和 java.time.temporal.ChronoField
.
- 我使用
DateTimeFormatterBuilder
而不是更常见的 DateTimeFormatter.forPattern(String)
。我发现它更具可读性,并且愿意容忍由此产生的冗长。
- 关于您想要的格式,我调整了一件事:您要求的时间是
2:06:30:001
;此代码产生 2:06:30.001
——秒和毫秒之间的小数点,而不是冒号。这样更正确,但是如果您更喜欢冒号,只需将相应的 .appendLiteral('.')
更改为通过冒号即可。
- 您经常会发现内联定义 DateTimeFormatters、ZoneIds 等的示例代码。这些 classes 是线程安全的和可重用的,因此为了获得最佳结果,您应该将它们定义为常量,就像我在这里所做的那样。您将获得更好的性能并减少内存使用。
- 请注意,DataStax 驱动程序的
Uuids
class 使用系统时钟的毫秒精度值作为输入,因此您只会在最后四个位置看到零,除非您实现自己的基于纳秒的变体。您可以使用 System.nanoTime()
来做到这一点,但有一些复杂性 -- check out the note on the JavaDoc for more.
要确定两个 ZonedDateTime 之间的时间量,您只需这样做:
Duration duration = Duration.between(date1, date2);
Duration
class有several useful methods你可以用来解释结果。
我正在使用这个 libraryDependencies += "com.datastax.oss" % "java-driver-core" % "4.3.0"
库来创建基于时间的 uuid。虽然它生成基于时间的 uuid,但它给了我最多几秒钟,但我正在寻找 100 纳秒的值
import com.datastax.oss.driver.api.core.uuid.Uuids
println(Uuids.timeBased().toString)
输出 uuid 类似于 f642f350-0230-11ea-a02f-597f2801796a
对应于
Friday, November 8, 2019 at 2:06:30 PM Greenwich Mean Time
请帮助如何获得以毫秒为单位的时间
Friday, November 8, 2019 at 2:06:30:0000000Z PM Greenwich Mean Time
我想将时间戳转换成uuid格式进行测试(测试只接受uuid格式)。然后我会将 uuid 转换回时间以测量一些时差。
这里有几个步骤。第一个是将基于时间的 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, 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);
}
我会将这些方法和常量放在实用程序中 class 以便于重用。
几个注意事项:
- 这里有很多静态导入的常量。他们来自
java.time.format.TextStyle
和java.time.temporal.ChronoField
. - 我使用
DateTimeFormatterBuilder
而不是更常见的DateTimeFormatter.forPattern(String)
。我发现它更具可读性,并且愿意容忍由此产生的冗长。 - 关于您想要的格式,我调整了一件事:您要求的时间是
2:06:30:001
;此代码产生2:06:30.001
——秒和毫秒之间的小数点,而不是冒号。这样更正确,但是如果您更喜欢冒号,只需将相应的.appendLiteral('.')
更改为通过冒号即可。 - 您经常会发现内联定义 DateTimeFormatters、ZoneIds 等的示例代码。这些 classes 是线程安全的和可重用的,因此为了获得最佳结果,您应该将它们定义为常量,就像我在这里所做的那样。您将获得更好的性能并减少内存使用。
- 请注意,DataStax 驱动程序的
Uuids
class 使用系统时钟的毫秒精度值作为输入,因此您只会在最后四个位置看到零,除非您实现自己的基于纳秒的变体。您可以使用System.nanoTime()
来做到这一点,但有一些复杂性 -- check out the note on the JavaDoc for more.
要确定两个 ZonedDateTime 之间的时间量,您只需这样做:
Duration duration = Duration.between(date1, date2);
Duration
class有several useful methods你可以用来解释结果。