用javascript时间创build一个唯一的数字

我需要使用JavaScript生成唯一的ID号。 在过去,我通过使用时间创build一个数字来完成这个任务。 该数字将由四位数年份,两位数月份,两位数日,两位数小时,两位数分钟,两位数秒和三位毫秒组成。 所以它看起来像这样:20111104103912732 …这将给我的目的一个唯一的编号足够的确定性。

我已经做了一段时间,而且现在还没有代码。 任何人都有这样的代码,或有一个更好的build议,以生成一个唯一的ID?

如果你只想要一个唯一的号码,那么

 var timestamp = new Date().getUTCMilliseconds(); 

会给你一个简单的数字。 但是如果你需要可读的版本,你需要进行一些处理:

 var now = new Date(); timestamp = now.getFullYear().toString(); // 2011 timestamp += (now.getFullMonth < 9 ? '0' : '') + now.getFullMonth().toString(); // JS months are 0-based, so +1 and pad with 0's timestamp += (now.getDate < 10) ? '0' : '') + now.getDate().toString(); // pad with a 0 ... etc... with .getHours(), getMinutes(), getSeconds(), getMilliseconds() 

更好的方法是:

 new Date().valueOf(); 

代替

 new Date().getUTCMilliseconds(); 

valueOf()是“最有可能”唯一的数字。 http://www.w3schools.com/jsref/jsref_valueof_date.asp

这可以通过以下代码简单实现:

 var date = new Date(); var components = [ date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds() ]; var id = components.join(""); 

这比创buildDate实例更快,使用更less的代码,并且始终会生成一个唯一的编号(本地):

 function uniqueNumber() { var date = Date.now(); // If created at same millisecond as previous if (date <= uniqueNumber.previous) { date = ++uniqueNumber.previous; } else { uniqueNumber.previous = date; } return date; } uniqueNumber.previous = 0; 

jsfiddle: http : //jsfiddle.net/j8aLocan/

我在Bower和npm上发布了这个: https : //github.com/stevenvachon/unique-number

你也可以使用更复杂的东西,如cuid , puid或shortid来生成一个非数字。

当我想要一些小于一堆数字的东西时,我会这样做 – 改变基础。

 var uid = (new Date().getTime()).toString(36) 

创build一个可以确定的数字的最短path将在您想象的单独实例中独一无二

 Date.now() + Math.random() 

如果函数调用有1毫秒的差异,则100%保证产生一个不同的数字 。 对于同一毫秒内的函数调用,如果在同一个毫秒内创build超过几百万个数字,则只会开始担心,这不太可能。

有关在同一毫秒内获得重复数字的概率的更多信息,请参阅https://stackoverflow.com/a/28220928/4617597

我用

 Math.floor(new Date().valueOf() * Math.random()) 

所以如果在任何时候代码被同时触发,那么随机数字也是一样的。

从网上调查,我想出了以下对象,每个会话创build一个唯一的ID:

  window.mwUnique ={ prevTimeId : 0, prevUniqueId : 0, getUniqueID : function(){ try { var d=new Date(); var newUniqueId = d.getTime(); if (newUniqueId == mwUnique.prevTimeId) mwUnique.prevUniqueId = mwUnique.prevUniqueId + 1; else { mwUnique.prevTimeId = newUniqueId; mwUnique.prevUniqueId = 0; } newUniqueId = newUniqueId + '' + mwUnique.prevUniqueId; return newUniqueId; } catch(e) { mwTool.logError('mwUnique.getUniqueID error:' + e.message + '.'); } } } 

这可能对某些人有帮助。

干杯

安德鲁

这应该做的:

 var uniqueNumber = new Date().getTime(); // milliseconds since 1st Jan. 1970 

这也应该做到:

 (function() { var uniquePrevious = 0; uniqueId = function() { return uniquePrevious++; }; }()); 

在这里发布这个代码片段为我自己的未来参考(不保证,但令人满意的“独特”足够):

 // a valid floating number window.generateUniqueNumber = function() { return new Date().valueOf() + Math.random(); }; // a valid HTML id window.generateUniqueId = function() { return "_" + new Date().valueOf() + Math.random().toFixed(16).substring(2); }; 

这创build了一个几乎保证唯一的32个字符的关键客户端,如果你想只是数字改变“字符”变种。

 var d = new Date().valueOf(); var n = d.toString(); var result = ''; var length = 32; var p = 0; var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; for (var i = length; i > 0; --i){ result += ((i & 1) && n.charAt(p) ? '<b>' + n.charAt(p) + '</b>' : chars[Math.floor(Math.random() * chars.length)]); if(i & 1) p++; }; 

https://jsfiddle.net/j0evrdf1/1/

假设@abarber提出的解决scheme是一个很好的解决scheme,因为使用了(new Date()).getTime()所以它有一个毫秒的窗口,并且在这个区间内碰撞的情况下总结一个tick ,我们可以考虑使用built-正如我们在这里可以清楚地看到的那样:

我们可以在这里看到如何使用(new Date()).getTime()在1/1000窗口框架中碰撞(new Date()).getTime()

 console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() ) VM1155:1 1469615396590 VM1155:1 1469615396591 console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() ) VM1156:1 1469615398845 VM1156:1 1469615398846 console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() ) VM1158:1 1469615403045 VM1158:1 1469615403045 

其次,我们尝试所提出的解决scheme,避免在1/1000窗口中发生冲突:

 console.log( window.mwUnique.getUniqueID() ); console.log( window.mwUnique.getUniqueID() ); VM1159:1 14696154132130 VM1159:1 14696154132131 

这就是说,我们可以考虑使用像事件循环中调用的节点process.nextTick这样的函数作为一个单独的tick ,并且在这里很好的解释。 当然在浏览器中没有process.nextTick所以我们必须弄清楚如何做到这一点。 这个实现将在浏览器中使用距离setTimeout(fnc,0)setImmediate(fnc)window.requestAnimationFrame的I / O nextTick函数在浏览器中安装nextTick函数。 正如我们在这里所build议的,我们可以添加window.postMessage ,但是我把它留给读者,因为它也需要一个addEventListener 。 我已经修改了原来的模块版本,以使其更简单:

 getUniqueID = (c => { if(typeof(nextTick)=='undefined') nextTick = (function(window, prefixes, i, p, fnc) { while (!fnc && i < prefixes.length) { fnc = window[prefixes[i++] + 'equestAnimationFrame']; } return (fnc && fnc.bind(window)) || window.setImmediate || function(fnc) {window.setTimeout(fnc, 0);}; })(window, 'r webkitR mozR msR oR'.split(' '), 0); nextTick(() => { return c( (new Date()).getTime() ) }) }) 

所以我们在1/1000窗口中:

 getUniqueID(function(c) { console.log(c); });getUniqueID(function(c) { console.log(c); }); undefined VM1160:1 1469615416965 VM1160:1 1469615416966 
 function UniqueValue(){ var date = new Date(); return date.toISOString().replace(/[^0-9]/g, ""); } 

使用这个:在javascript中创build唯一的数字

 var uniqueNumber=(new Date().getTime()).toString(36); 

真的行。 🙂

Interesting Posts