Supposons une variable donnée, elle contient un horodatage UNIX
, mais que ce soit au format secondes ou millisecondes est inconnu, je veux l'assigner à une variable au format secondes
unknown = 1398494489444 # This is millisecond
t = ???
Mise à jour: je comprends qu'il n'est pas possible de le dire sans donner quelques limitations, alors le voici
Assume current_ts = current unix timestamp
Si vous convertissez les valeurs d'horodatage maximales avec x chiffres en millisecondes, vous obtenez quelque chose comme ceci:
Vos horodatages peuvent-ils être antérieurs à 2001? Sinon, je pense que vous pouvez vérifier si le nombre comporte 13 chiffres ou plus - si oui, vous avez des millisecondes, sinon vous avez des secondes. Bien sûr, cela ne fonctionnera que jusqu'à ce que les horodatages en secondes aient également 13 chiffres, ce qui signifie que les horodatages en millisecondes auront 16 chiffres:
P.S. vous pouvez assouplir la condition à 12 chiffres ou plus, si vos horodatages ne peuvent pas remonter plus loin que 1973. La condition ne devrait être correcte que jusqu'à:
Au risque d'attirer des votes négatifs, je tiens à dire officiellement que ne le faites pas.
Faire des hypothèses sur les unités d'une quantité physique est une idée terrible - cela a conduit à la destruction de Mars Meteorological Orbiter (les unités de poussée calculées étaient en livres, les moteurs attendaient des Newtons. Pas assez de poussée - et l'orbiteur a brûlé dans l'atmosphère).
Si vous avez une assez bonne idée de l'ampleur d'un nombre, vous devriez pouvoir faire une "supposition éclairée" des unités. Par exemple, si je vous dis que mon poids est de 230, vous pourriez me regarder et penser "je parie que ce sont des livres, pas des kilos". De même, si vous convertissez un horodatage de mon anniversaire en une date en supposant qu'elle était en secondes, et que cela se révèle être de 200 ans dans le futur, vous pouvez raisonnablement supposer que "secondes" n'était pas la bonne unité.
Mais c'est une chose DANGEREUSE à faire.
Pourtant - si vous devez le faire, alors en général, je recommanderais l'approche suivante:
Cette dernière chose est importante - elle vous permettra d'apprendre de votre erreur. Par exemple, si votre horodatage vous indique quelque chose sur la prochaine apparition de la comète, vous pouvez imprimer
Prochaine apparition attendue de la comète: 29 décembre 2546 (hypothèse: l'horodatage de X a été donné en secondes)
De cette façon, il y a un "retour". En général, " documentez vos hypothèses " n'est pas seulement un bon conseil - il est essentiel dans toute science exacte.
Enfin - la conversion d'un horodatage de ms en s est obtenue en divisant le nombre par 1000. Mais je suis sûr que vous le savez.
Avec vos contraintes, il est trivial de détecter des horodatages en millisecondes. Même les horodatages d'un an dans le passé sont encore plus grands que l'horodatage actuel.
Testez simplement si le nombre est supérieur à l'horodatage actuel; si oui, vous avez un horodatage en millisecondes:
now = time.mktime(time.gmtime())
if t > now:
# milliseconds, convert to seconds
t /= 1000.0
En divisant par 1000, vous reconvertissez l'horodatage en un exprimé en secondes et les fonctions par défaut du module time
peuvent être appliquées.
En effet, même un horodatage en millisecondes représentant une année dans le passé, interprété accidentellement comme horodatage en secondes, se situerait loin dans le futur:
>>> import time
>>> ts = time.mktime(time.gmtime())
>>> year_ago = ts - (86400 * 365)
>>> time.gmtime(year_ago * 1000) # misinterpret milliseconds as seconds
time.struct_time(tm_year=45395, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=190, tm_isdst=0)
Vous devez avoir un horodatage début 197 avant de pouvoir confondre les deux plages:
>>> now = time.mktime(time.gmtime())
>>> time.gmtime(ts / 1000) # misinterpret seconds as milliseconds
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=17, tm_hour=5, tm_min=25, tm_sec=13, tm_wday=5, tm_yday=17, tm_isdst=0)
Par exemple. les horodatages des 17 premiers jours suivant l'époque UNIX pourraient être confondus avec les horodatages en millisecondes. Tout après cette date sera plus grande qu'un horodatage de "l'heure actuelle".
Avec vos contraintes spécifiques, vous avez la chance de pouvoir séparer les deux unités si facilement. meilleure option est de ne pas entrer dans cette situation en premier lie. Ces données provenaient de quelque part; déterminez le plus tôt possible quel type de données vous avez au lieu de devoir deviner plus tard. Aucun système ne vous donnera au hasard des horodatages en secondes une partie du temps, des horodatages en millisecondes le reste du temps. Vous pouvez sûrement savoir sur la base d'autres informations quel type de données vous recherchez et convertir à ce moment-là ou annoter vos données pour inclure le type?
Une alternative à la réponse donnée par Martin:
Nous avons rencontré ce problème lorsque nous avons dû unifier les horodatages des documents provenant de tiers. Alors que la condition précédente était:
if date > time.time():
use_miliseconds(date)
else:
use_seconds(date)
, et il semble que cela devrait fonctionner, il existe des cas Edge, surtout si date
a été dérivé d'une représentation sous forme de chaîne sans informations de fuseau horaire, ou si les horloges sont modifiées.
Une variante plus sûre serait d'utiliser:
if date > time.time() + HUNDRED_YEARS:
use_miliseconds(date)
else:
use_seconds(date)
, où HUNDRED_YEARS = 365 * 24 * 3600
. Cette condition est beaucoup plus sujette aux erreurs, en fait, elle fonctionne pour n'importe quelle date sauf janvier et février 1970 (qui sont ambigus dans les deux cas).