Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Extracting time from v1 uuid #49

Open
wants to merge 1 commit into from
@krassif

Added a method to extract msecs from v1 type uuid. I saw uuidjs had low/high time, but it would be better if everything was in a single, well performing library.

@booo

Any plans to merge this?

@broofa
Owner

Sorry for not responding earlier - I'm afraid this fell off my radar. (Feel free to harass me if you don't feel I'm responding fast enough in the future, btw)

There's been more than one request for the ability to parse fields out of UUIDs, and this obviously fits in nicely with that. However my suspicion is that a relatively small %'age of the people generating IDs need a parsing feature. Thus, I'm a little reluctant to add this as part of the core module.

Ideally I'd like to break this code apart such that people who only need to generate v4 UUIDs can do so without incurring the code bloat that goes along with v1 generation and parsing. If anyone has ideas on the best way to do that I'd love to hear them. For my part, I'm thinking this may take the form of separate modules for:

  • uuid-v4 - code for generating v4 UUIDs
  • uuid-v1 - code for generating v1 UUIDs
  • uuid-parse - utility functions for parsing RFC4122 fields

... and have a build script of some sort that compiles these together into a single uuid.js file. This way people can (for example) only use the uuid-v4 module if they don't want/need the code necessary for supporting v1 generation and parsing.

Anyhow... my point is that I see this as version 2 functionality. Thoughts?

@jonathandelgado

Major +1 to merge.

Props to you, @krassif.

@aiboy

+1 this is really useful thing to add.. plz add this if possible

@ronkorving

big +1
@broofa I appreciate the bigger plan here, but for now, nothing is happening at all and people need this. So how about we iterate small now, and perhaps later release a v2 where your suggestion can become a reality?

@sgronblo

Yes this would seem to be useful for Cassandra users where you can combine a row's created_at timestamp with the row's id. But when you display the row you will have to be able to extract the timestamp from the time uuid. As long as the pull request is correct I support a merge.

I think the package is still far from being bloated. And won't the performance conscious users who use this package in a low spec mobile browser optimize out the v1 functions when minimizing their JS code anyway?

Also, @ronkorving 久しぶりです

@pfarland

This seems like a useful feature for v1 uuids to warrant inclusion.

@krassif
@somecallmemike

I went ahead and patched this myself and it works splendidly. Broofa, this is way too useful not to incorporate as people need to convert both directions. +1 and a half.

@ronkorving

It's only been 2 years now. Still within reason to discuss architecture ;) Get this in already please.

@gwicke

+1 from me as well.

@somecallmemike

Is this going to be patched anytime soon?

@indexzero

FWIW, :+1: from me as well. I will bother @broofa over email since he said I should :smile:

@indexzero

But unfortunately, this does not work ...

v1time(uuid.v1());
Error: uuid version 1 expected
@indexzero

Sorry I was mistaken, it does work, but imho the above API is important to have working. The correct way to use this in it's current form is:

v1time(uuid.parse(uuid.v1()));
@indexzero

FYI I ripped this out into a module. Thanks @krassif for writing it. I attributed you in the README and also implemented optional parsing from strings. https://github.com/indexzero/uuid-time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 41 additions and 0 deletions.
  1. +41 −0 uuid.js
View
41 uuid.js
@@ -219,12 +219,53 @@
return buf || unparse(rnds);
}
+ // extracts time (msecs) from v1 type uuid
+ function v1time(buf, offset) {
+
+ var msec = 0, nsec = 0;
+ var i = buf && offset || 0;
+ var b = buf||[];
+
+ // inspect version at offset 6
+ if ((b[i+6]&0x10)!=0x10) {
+ throw new Error("uuid version 1 expected"); }
+
+ // 'time_low'
+ var tl = 0;
+ tl |= ( b[i++] & 0xff ) << 24;
+ tl |= ( b[i++] & 0xff ) << 16;
+ tl |= ( b[i++] & 0xff ) << 8;
+ tl |= b[i++] & 0xff ;
+
+ // `time_mid`
+ var tmh = 0;
+ tmh |= ( b[i++] & 0xff ) << 8;
+ tmh |= b[i++] & 0xff;
+
+ // `time_high_minus_version`
+ tmh |= ( b[i++] & 0xf ) << 24;
+ tmh |= ( b[i++] & 0xff ) << 16;
+
+ // account for the sign bit
+ msec = 1.0 * ( ( tl >>> 1 ) * 2 + ( ( tl & 0x7fffffff ) % 2 ) ) / 10000.0;
+ msec += 1.0 * ( ( tmh >>> 1 ) * 2 + ( ( tmh & 0x7fffffff ) % 2 ) ) * 0x100000000 / 10000.0;
+
+ // Per 4.1.4 - Convert from Gregorian epoch to unix epoch
+ msec -= 12219292800000;
+
+ // getting the nsec. they are not needed now though
+ // nsec = ( tl & 0xfffffff ) % 10000;
+
+ return msec;
+ }
+
// Export public API
var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;
uuid.parse = parse;
uuid.unparse = unparse;
+ uuid.v1time = v1time;
uuid.BufferClass = BufferClass;
// Export RNG options
Something went wrong with that request. Please try again.