как я могу получить дату / время обратно из UUID типа 1 - PullRequest
0 голосов
/ 30 июня 2018

Я включил следующую библиотеку UUID группа компиляции: 'com.fasterxml.uuid', имя: 'java-uuid-generator', версия: '3.1.5' в моей сборке.

У меня есть такой код

        NoArgGenerator timeBasedGenerator = Generators.timeBasedGenerator()
        UUID tuid = timeBasedGenerator.generate()
        Timestamp timestamp = new Timestamp ((tuid.timestamp()/1000) as Long)
        Date dateTime = new Date (timestamp.getTime())

однако, когда я пытаюсь посмотреть на дату, это совсем не то, что должно быть, например, я получаю 'uid fef57eca-7c8b-11e8-bedd-992c2ac3197a было вс 6 февраля 07:55:54 GMT 6327', когда сегодня 30 / 06/2018

Кто-нибудь знает, как правильно извлечь реальную дату и время из UUID, основанного на времени, используя библиотеку fastxml.uuid?

но в тупик

PS попробовал это вместо

        UUID tuid = timeBasedGenerator.generate()
        Long t = tuid.timestamp()
        Timestamp timestamp = new Timestamp (t)
        Date dateTime = new Date (timestamp.getTime())

, который дает идентификатор ff79d7d9-7cb5-11e8-976c-6ba57a5e9636 и дату Чт 14 августа 11:11:40 BST 4359073

1 Ответ

0 голосов
/ 01 июля 2018

Я сделал еще несколько поисков в Интернете.

Я построил следующий класс «простых утилит», который может быть расширен при необходимости:

import com.fasterxml.uuid.Generators
import com.fasterxml.uuid.NoArgGenerator

class UuidUtil {

    static final NoArgGenerator timeBasedGenerator = Generators.timeBasedGenerator()


    /**
     * From UUID javadocs the resulting timestamp is measured in 100-nanosecond units since midnight, October 15, 1582 UTC
     * timestamp() from UUID is measured in 100-nanosecond units since midnight, October 15, 1582 UTC
     *
     * The Java timestamp in milliseconds since 1970-01-01 as baseline
     *
     * @return
     */
    static long getStartOfUuidRelativeToUnixEpochInMilliseconds () {
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT-0"))
        c.set(Calendar.YEAR, 1582)
        c.set(Calendar.MONTH, Calendar.OCTOBER)
        c.set(Calendar.DAY_OF_MONTH, 15)
        c.set(Calendar.HOUR_OF_DAY, 0)
        c.set(Calendar.MINUTE, 0)
        c.set(Calendar.SECOND, 0)
        c.set(Calendar.MILLISECOND, 0)

        return c.getTimeInMillis()
    }

    //https://www.wolframalpha.com/input/?i=convert+1582-10-15+UTC+to+unix+time
    final static long START_OF_UUID_RELATIVE_TO_UNIX_EPOCH_SECONDS = -12219292800L
    final static long START_OF_UUID_RELATIVE_TO_UNIX_EPOCH_MILLIS = -12219292800L * 1000L

    /**
     * timestamp() from UUID is measured in 100-nanosecond units since midnight, October 15, 1582 UTC,
     * so we must convert for 100ns units to millisecond procession
     * @param tuid
     * @return
     */
    static long getMillisecondsFromUuid (UUID tuid) {

        assert tuid.version() == 1      //ensure its a time based UUID

        // timestamp returns in 10^-7 (100 nano second chunks), 
        // java Date constructor  assumes 10^-3 (millisecond precision)
        // so we have to divide by 10^4 (10,000) to get millisecond precision  
        long milliseconds_since_UUID_baseline = tuid.timestamp() /10000L

    }

    static getDateFromUuid (UUID tuid) {
        // Allocates a Date object and initializes it to represent the specified number of milliseconds since the 
        // standard java (unix) base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT
        // have to add relative offset from UUID start date of unix epoch to get start date in unix time milliseconds 
        new Date (getMillisecondsFromUuid (tuid) + START_OF_UUID_RELATIVE_TO_UNIX_EPOCH_MILLIS )
    }

    static UUID getTimeBasedUuid () {
        UUID tuid = timeBasedGenerator.generate()
    }

}

Я добавил пояснительный комментарий, чтобы вы могли следить за тем, что вам нужно было сделать для обработки метода UUID timestamp () в формате, который работает для обычной обработки даты и времени в Java.

Почему класс Java UUID не может обеспечить методы, которые можно ожидать, чтобы сделать UUID, основанный на времени, совместимым с обычными форматами даты / времени Java, основанными на обычной эпохе Unix, для меня загадка.

Я запустил небольшой тестовый скрипт, используя приведенные выше статические методы:

println "get start of epoch in milliseconds " + UuidUtil.getStartOfUuidRelativeToUnixEpochInMilliseconds()
assert UuidUtil.START_OF_UUID_RELATIVE_TO_UNIX_EPOCH_MILLIS == UuidUtil.startOfUuidRelativeToUnixEpochInMilliseconds

UUID tuid = UuidUtil.timeBasedUuid

println "uid : $tuid"

Date date = UuidUtil.getDateFromUuid(tuid)
println "extracted date from uid is " + UuidUtil.getDateFromUuid(tuid)

и получил это

get start of epoch in milliseconds -12219292800000
uid : 43acb588-7d39-11e8-b37b-59f77bf2d333
extracted date from uid is Sun Jul 01 15:15:53 BST 2018

, который выглядел правильным для времени запуска скрипта.

...