用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++; };
假设@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);
真的行。 🙂