web-dev-qa-db-fra.com

Créer un numéro unique avec du temps javascript

J'ai besoin de générer des identifiants uniques à la volée en utilisant javascript. Auparavant, je le faisais en créant un nombre en utilisant le temps. Le numéro serait composé de l'année à quatre chiffres, du mois à deux chiffres, du jour à deux chiffres, des heures à deux chiffres, des minutes à deux chiffres, des secondes à deux chiffres et des millisecondes à trois chiffres. Donc, cela ressemblerait à quelque chose comme ceci: 20111104103912732 ... cela donnerait assez de certitude d'un numéro unique pour mes besoins.

Cela fait longtemps que je n’ai pas fait cela et je n’ai plus le code. Quelqu'un at-il le code pour le faire ou une meilleure suggestion pour générer un identifiant unique? 

72
Nick Petrie

Si vous voulez juste un numéro unique, alors

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

vous obtiendrez un simple numéro. Mais si vous avez besoin de la version lisible, vous avez un peu de traitement:

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()
52
Marc B

Une meilleure approche serait:

new Date().valueOf();

au lieu de 

new Date().getUTCMilliseconds();

valueOf () est "très probablement" un nombre unique. http://www.w3schools.com/jsref/jsref_valueof_date.asp

90
3lRicko

Le moyen le plus rapide de créer un nombre qui, vous en êtes sûr, sera unique parmi autant d'instances distinctes que vous pouvez imaginer, c'est 

Date.now() + Math.random()

S'il existe une différence d'appels de fonction d'une milliseconde, il est garanti que 100% génère un nombre différent. Pour les appels de fonction dans la même milliseconde, vous ne devriez vous inquiéter que si vous créez plus de quelques millions de numéros dans la même milliseconde, ce qui n’est pas très probable.

Pour plus d'informations sur la probabilité d'obtenir un nombre répété dans la même milliseconde, voir https://stackoverflow.com/a/28220928/4617597

33
Marcelo Lazaroni

Ceci peut être réalisé simplement avec le code suivant:

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

var id = components.join("");
22
August Lilleaas

Cela fonctionne plus rapidement que la création d'une instance Date, utilise moins de code et always produira un nombre unique (localement):

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/

J'ai publié ceci sur Bower et npm: https://github.com/stevenvachon/unique-number

Vous pouvez également utiliser quelque chose de plus élaboré, tel que cuid , puid ou shortid pour générer un non-nombre.

15
Steven Vachon

Voici ce que je fais quand je veux quelque chose de plus petit qu'un tas de chiffres - changer de base.

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

J'utilise

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

Donc, si par hasard le code est déclenché en même temps, il y a aussi une chance infime que les nombres aléatoires soient les mêmes. 

11
Zach Mozel

Cela devrait faire:

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

En recherchant en ligne, j'ai créé l'objet suivant qui crée un identifiant unique par session:

        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 + '.');
            }
        }            
    }

Cela peut être utile pour certaines personnes.

À votre santé

Andrew

4
abarber

En ES6:

const ID_LENGTH = 36
const START_LETTERS_ASCII = 97 // Use 64 for uppercase
const ALPHABET_LENGTH = 26

const uniqueID = () => [...new Array(ID_LENGTH)]
  .map(() => String.fromCharCode(START_LETTERS_ASCII + Math.random() * ALPHABET_LENGTH))
 .join('')

Exemple:

 > uniqueID()
 > "bxppcnanpuxzpyewttifptbklkurvvetigra"
3
cntdwn
    function UniqueValue(d){
        var dat_e = new Date();
        var uniqu_e = ((Math.random() *1000) +"").slice(-4)

        dat_e = dat_e.toISOString().replace(/[^0-9]/g, "").replace(dat_e.getFullYear(),uniqu_e);
        if(d==dat_e)
            dat_e = UniqueValue(dat_e);
        return dat_e;
    }

Appel 1: UniqueValue ('0') 
Appel 2: UniqueValue (UniqueValue ('0')) // sera complexe 

Exemple de sortie: 
pour (var i = 0; i <10; i ++) {console.log (UniqueValue (Uniquevalue ('0')));} 
60950116113248802 
26780116113248803 
53920116113248803 
35840116113248803 
47430116113248803 
41680116113248803 
42980116113248804 
34750116113248804 
20950116113248804 
03730116113248804

1
George Livingston

Cela crée un côté client clé presque unique de 32 caractères, si vous voulez que les chiffres changent la var "caractères".

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/

1
lugreen

si vous voulez un nombre unique après quelques millièmes de secondes, utilisez Date.now(), si vous souhaitez l’utiliser dans un for loop, puis utilisez Date.now() and Math.random() ensemble.

numéro unique dans une boucle for

function getUniqueID(){
    for(var i = 0; i< 5; i++)
      console.log(Date.now() + ( (Math.random()*100000).toFixed()))
}
getUniqueID()

sortie :: tous les nombres sont uniques

15598251485988384 155982514859810330 155982514859860737 155982514859882244 155982514859883316

numéro unique sans Math.random()

function getUniqueID(){
        for(var i = 0; i< 5; i++)
          console.log(Date.now())
    }
    getUniqueID()

les :: sorties sont répétées

1559825328327 1559825328327 1559825328327 1559825328328 1559825328328

1
Raj Rj

Publier cet extrait de code ici pour ma propre référence future (non garanti mais suffisant "unique"):

// 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);
};
1
noseratio

Cela devrait aussi faire:

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

Il serait peut-être préférable d'utiliser getTime () ou valueOf (), mais de cette manière, il renvoie un nombre compréhensible par l'utilisateur, unique et humain (représentant la date et l'heure):

window.getUniqNr = function() {
  var now = new Date(); 
  if (typeof window.uniqCounter === 'undefined') window.uniqCounter = 0; 
  window.uniqCounter++; 
  var m = now.getMonth(); var d = now.getDay(); 
  var h = now.getHours(); var i = now.getMinutes(); 
  var s = now.getSeconds(); var ms = now.getMilliseconds();
  timestamp = now.getFullYear().toString() 
  + (m <= 9 ? '0' : '') + m.toString()
  +( d <= 9 ? '0' : '') + d.toString() 
  + (h <= 9 ? '0' : '') + h.toString() 
  + (i <= 9 ? '0' : '') + i.toString() 
  + (s <= 9 ? '0' : '') + s.toString() 
  + (ms <= 9 ? '00' : (ms <= 99 ? '0' : '')) + ms.toString() 
  + window.uniqCounter; 

  return timestamp;
};
window.getUniqNr();
0
Aurimas Rekštys

utiliser ceci: pour créer un numéro unique en javascript

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

Ça marche vraiment. :)

0
Bprajhh

J'ai fait de cette façon

function uniqeId() {
   var ranDom = Math.floor(new Date().valueOf() * Math.random())
   return _.uniqueId(ranDom);
}
0
DarkNominis
let now = new Date();
let timestamp = now.getFullYear().toString();
let month = now.getMonth() + 1;
timestamp += (month < 10 ? '0' : '') + month.toString();
timestamp += (now.getDate() < 10 ? '0' : '') + now.getDate().toString();
timestamp += (now.getHours() < 10 ? '0' : '') + now.getHours().toString();
timestamp += (now.getMinutes() < 10 ? '0' : '') + now.getMinutes().toString();
timestamp += (now.getSeconds() < 10 ? '0' : '') + now.getSeconds().toString();
timestamp += (now.getMilliseconds() < 100 ? '0' : '') + now.getMilliseconds().toString();
0
Manaaf Fanam

Comme les millisecondes ne sont pas mises à jour chaque milliseconde dans le nœud, voici une réponse. Cela génère un numéro de ticket lisible par l'homme unique. Je suis nouveau dans la programmation et les nodejs. S'il vous plait corrigez moi si je me trompe.

function get2Digit(value) {
if (value.length == 1) return "0" + "" + value;
else return value;

}

function get3Digit(value) {
if (value.length == 1) return "00" + "" + value;
else return value;

}

function generateID() {
    var d = new Date();
    var year = d.getFullYear();
    var month = get2Digit(d.getMonth() + 1);
    var date = get2Digit(d.getDate());
    var hours = get2Digit(d.getHours());
    var minutes = get2Digit(d.getMinutes());
    var seconds = get2Digit(d.getSeconds());
    var millSeconds = get2Digit(d.getMilliseconds());
    var dateValue = year + "" + month + "" + date;
    var uniqueID = hours + "" + minutes + "" + seconds + "" + millSeconds;

    if (lastUniqueID == "false" || lastUniqueID < uniqueID) lastUniqueID = uniqueID;
    else lastUniqueID = Number(lastUniqueID) + 1;
    return dateValue + "" + lastUniqueID;
}
0
Sai
function getUniqueNumber() {

    function shuffle(str) {
        var a = str.split("");
        var n = a.length;
        for(var i = n - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;
        }
        return a.join("");
    }
    var str = new Date().getTime() + (Math.random()*999 +1000).toFixed() //string
    return Number.parseInt(shuffle(str));   
}
0
Alex Pilugin

En supposant que la solution proposée par @abarber soit une bonne solution car (new Date()).getTime() a donc une fenêtre de plusieurs millisecondes et que la somme est tick en cas de collision dans cet intervalle, nous pourrions envisager d’utiliser la fonction intégrée as nous pouvons voir clairement ici en action:

Fist nous pouvons voir ici comment il peut y avoir des collisions dans le cadre de la fenêtre 1/1000 en utilisant (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

Deuxièmement, nous essayons la solution proposée qui évite les collisions dans la fenêtre 1/1000:

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

Cela dit, nous pourrions envisager d’utiliser des fonctions telles que le nœud process.nextTick appelé dans la boucle d’événements sous forme de variable unique tick et bien expliquée ici . Bien sûr, il n’existe pas de process.nextTick dans le navigateur, nous devons donc comprendre comment faire cela . Cette implémentation installera une fonction nextTick dans le navigateur en utilisant les fonctions les plus proches des E/S dans le navigateur, à savoir setTimeout(fnc,0), setImmediate(fnc), window.requestAnimationFrame. Comme suggéré ici nous pourrions ajouter le window.postMessage, mais je laisse cela au lecteur car il a aussi besoin de addEventListener. J'ai modifié les versions originales du module pour le simplifier:

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() )  
 })
})

Nous avons donc dans la fenêtre 1/1000:

getUniqueID(function(c) { console.log(c); });getUniqueID(function(c) { console.log(c); });
undefined
VM1160:1 1469615416965
VM1160:1 1469615416966
0
loretoparisi

Facile et obtenez toujours une valeur unique:

const uniqueValue = (new Date()).getTime() + Math.trunc(365 * Math.random());
**OUTPUT LIKE THIS** : 1556782842762
0