20

How to convert the UUID to date format 2011-04-22 ?

For example, I have UUID like this

118ffe80-466b-11e1-b5a5-5732cf729524.

How to convert this to date format?

I tried

 String uuid="118ffe80-466b-11e1-b5a5-5732cf729524"; 
    UUID uid = UUID.fromString(uuid);
    long ls=convertTime(uid.timeStamp()); // it returns long value

    public String convertTime(long time){
            System.out.println("====="+time);
            Date date = new Date(time);
            Format format = new SimpleDateFormat("yyyy/MM/dd");
            return format.format(date).toString();
        }

output I got:4294744/11/02

Same case working fine for perl

$uuid='ef802820-46b3-11e2-bf3a-47ef6b3e28e2';
$uuid =~ s/-//g;

my $timelow = hex substr( $uuid, 2 * 0,     2 * 4 );
my $timemid = hex substr( $uuid, 2 * 4,     2 * 2 );
my $version = hex substr( $uuid, 2 * 6,     1 );
my $timehi  = hex substr( $uuid, 2 * 6 + 1, 2 * 2 - 1 );

my $time = ( $timehi * ( 2**16 ) + $timemid ) * ( 2**32 ) + $timelow;
my $epoc = int( $time / 10000000 ) - 12219292800;
my $nano = $time - int( $time / 10000000 ) * 10000000;

#$time_date = scalar localtime $epoc;
#print strftime( '%d-%m-%Y %H:%M:%S', localtime($epoc) );
#print "\n Time: ", scalar localtime $epoc, " +", $nano / 10000, "ms\n";
Reg
  • 10,717
  • 6
  • 37
  • 54
BALASCJP
  • 579
  • 2
  • 10
  • 21
  • kindly check with this url http://stackoverflow.com/questions/15127648/how-do-we-convert-uuid-to-date-in-perl – BALASCJP Mar 02 '13 at 21:10
  • Do you know if that source UUID is a v1 UUID? – Joe Mar 02 '13 at 21:12
  • `timeStamp()` returns a timestamp measured in 100-nanosecond units since midnight, October 15, 1582 UTC ; `Date(long date)` expects milliseconds since January 1, 1970, 00:00:00 GMT. So you have to convert from one format to the other – tmuguet Mar 02 '13 at 21:12
  • 2
    @JonSkeet depending on the version of the UUID algorithm it might contain a timestamp. – assylias Mar 02 '13 at 21:13
  • 2
    @assylias: It may well *contain* one, but that's not the same thing as converting the complete value. If the question had been "How do I extract the timestamp part of a UUID" that would be a different matter. – Jon Skeet Mar 02 '13 at 21:15

1 Answers1

23

The javadoc for UUID says the following about the timestamp field:

The 60 bit timestamp value is constructed from the time_low, time_mid, and time_hi fields of this UUID. The resulting timestamp is measured in 100-nanosecond units since midnight, October 15, 1582 UTC.

(emphasis mine)

The Java timestamp is in milliseconds since 1970-01-01. In order to get a meaningful date from a UUID, you'll need to do two things: convert from 100ns to 1ms precision (divide by 10000) and rebase from 1582-10-15 to 1970-01-01, which you can do by adding a constant value.

WolframAlpha tells us that 1582-10-15 corresponds to a UNIX timestamp of -12219292800, so to get the correct date, you must add 12219292800 to the number of milliseconds you got after dividing by 10000.

As a side note:

The timestamp value is only meaningful in a time-based UUID, which has version type 1. If this UUID is not a time-based UUID then this method throws UnsupportedOperationException.

...so make sure your code either only ever encounters Type 1 UUID's, or can handle that they don't have a timestamp.

Barend
  • 17,296
  • 2
  • 61
  • 80
  • Thanks Barend can give some simple example. – BALASCJP Mar 02 '13 at 21:19
  • 2
    You mean `new Date(uid.timeStamp() / 10000L + 12219292800L)`? I could give you an example, but I'm sure you can figure it out :). – Barend Mar 02 '13 at 21:21
  • are you sure that you should add the 12219292800? I would say that in order to convert from the uuid to unix you should rather subtract the 12219292800 (12219292800 in the uuid space is 0 in the unix space). – oo_olo_oo Oct 31 '13 at 11:51
  • @oo_olo_oo do the math ;-). This answer is too long ago for me to remember the specifics, but I'm pretty sure I remember seeing the expected value. – Barend Nov 01 '13 at 14:49
  • 9
    From what I have tested the answer is wrong. See https://support.datastax.com/entries/22391451-Converting-TimeUUID-Strings-to-Dates for a solution that worked fine for me instead. – Iker Jimenez May 30 '14 at 13:26
  • @IkerJimenez, the link you provided is password protected. Can you elaborate on the solution that you found. Thanks. – peterl May 29 '15 at 18:15
  • 1
    @peterl This is what I have been using, should be in an answer but question is closed so apologies for the poor formatting: private static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L; UUID uuid = UUID.fromString(aUuid); long epoch = (uuid.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH) / 10000; – Iker Jimenez Jun 04 '15 at 08:48
  • 2
    `-12219292800` corresponds to the unix date/time of `1582-10-15 00:00:00` in *seconds*, not milliseconds, so that might be what is off about this answer. You should multiple this constant by 1000 to get the value in milliseconds so that you can then add it to the uuid timestamp, which has been divided by 10000 to get it into milliseconds. This way they are both in milliseconds. You add the two timestamps because the gregorian timestamp is a negative number in relationship to the epoch timestamp. – Anthony May 18 '17 at 18:04
  • 3
    This works `new Date(uuid.timestamp() / 10000L - 12219292800000L)` I used value from the article https://www.famkruithof.net/guid-uuid-timebased.html – Sergey Ponomarev Apr 02 '19 at 19:46