Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取基于时间的uuid';秒高达100纳秒_Java_Scala_Time_Cassandra_Timeuuid - Fatal编程技术网

Java 获取基于时间的uuid';秒高达100纳秒

Java 获取基于时间的uuid';秒高达100纳秒,java,scala,time,cassandra,timeuuid,Java,Scala,Time,Cassandra,Timeuuid,我正在使用这个libraryDependencies+=“com.datastax.oss”%”java驱动程序核心“%”4.3.0“库来创建基于时间的uuid。虽然它生成基于时间的uuid,但它给我最多秒的时间,但我正在寻找100纳秒的值 import com.datastax.oss.driver.api.core.uuid.Uuids println(Uuids.timeBased().toString) 输出uuid类似于f642f350-0230-11ea-a02f-597f2801

我正在使用这个
libraryDependencies+=“com.datastax.oss”%”java驱动程序核心“%”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
,对应于
2019年11月8日星期五格林威治标准时间下午2:06:30

请帮助我们如何以毫秒为单位计算时间
2019年11月8日星期五格林威治标准时间下午2:06:30:0000000 Z


我希望将时间戳转换为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);
}
为了便于重用,我会将这些方法和常量放在实用程序类中

几点注意:

  • 这里有很多静态导入的常量。它们来自
    java.time.format.TextStyle
    java.time.temporal.ChronoField
  • 我使用了
    DateTimeFormatterBuilder
    ,而不是更常见的
    DateTimeFormatter.forPattern(String)
    。我觉得它更具可读性,并且愿意容忍由此产生的冗长
  • 我对你想要的格式做了一点调整:你要求的时间是
    2:06:30:001
    ;此代码生成
    2:06:30.001
    ——秒和毫秒之间的小数点,而不是冒号。这更正确,但如果您喜欢冒号,只需更改相应的
    .appendLiteral('.')
    以传递冒号即可
  • 您经常会发现内联定义DateTimeFormatters、ZoneID等的示例代码。这些类是线程安全且可重用的,所以为了获得最佳结果,您应该将它们定义为常量,就像我在这里所做的那样。您将获得更好的性能并减少内存使用
  • 请注意,DataStax驱动程序的
    UUID
    类使用系统时钟的毫秒精度值作为输入,因此您只会在最后四个位置看到零,除非您实现自己的基于纳秒的变体。您可以使用
    System.nanoTime()
    来实现这一点,但是有一些复杂的问题--
要确定两个ZoneDateTimes之间的时间量,只需执行以下操作:

Duration duration = Duration.between(date1, date2);

Duration
类提供了一个可以用来解释结果的工具。

谢谢:)。对于方法
timeBasedUuidToDate
如果返回毫秒为7位,我需要更改什么?目前它返回的是
2019-11-08T16:03:15.762Z[GMT]
我需要类似于
2019-11-08T16:03:15.7621112Z[GMT]
的东西,这些不是毫秒。六位数是微秒;七位数将是100纳秒,这是UUID可用的最大精度。我们必须改变过程的每一步。继续更新你的问题;我将把更新的代码放在一起并编辑此答案。更新问题。非常感谢您的时间和耐心。在我得到日期后,我想做的最后一件事是将它与另一个日期进行比较,得到时差。我在java中使用简单的dateformat,但它给了我精确的值。你能告诉我有没有简单的方法吗?再次感谢你如此及时的回答。不要错过我在注释列表中添加的最后一项!谢谢你,杰克。我不得不跳槽去做其他的工作,结果被这件事耽误了。我会回来核实,但我想确认你的答案并接受它。再次感谢:)