Comment convertir un horodatage Unix (secondes depuis l'époque) en Ruby DateTime?
369
DateTime.strptime
peut gérer les secondes depuis l'époque. Le nombre doit être converti en chaîne:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
tho.Time
nécessaire au lieu deDateTime
. Alors utilisezTime.strptime("1318996912345",'%Q').to_f
et vous verrez les millisecondes préservées, tout enDateTime.strptime("1318996912345",'%Q').to_f
ne les conservant pas.Désolé, bref moment d'échec de la synapse. Voici la vraie réponse.
Petit exemple (cela prend en compte le fuseau horaire actuel du système):
Mise à jour supplémentaire (pour UTC):
Mise à jour récente : j'ai comparé les meilleures solutions dans ce fil tout en travaillant sur un service HA il y a une semaine ou deux, et j'ai été surpris de constater que cela
Time.at(..)
surpasseDateTime.strptime(..)
(mise à jour: ajouté plus de repères).la source
Time.at
surpasseDateTime.strptime
. Ce dernier doit analyser une chaîne, ce qui est généralement beaucoup plus lent que la saisie directe d'un nombre.DateTime.strptime
car il crée deux nouvelles chaînes à chaque itération, ce qui est très cher. Ce n'est pas seulement l'analyse de chaînes comme @claw l'a ditGestion des fuseaux horaires
Je veux juste clarifier, même si cela a été commenté afin que les futurs gens ne manquent pas cette distinction très importante.
affiche une valeur de retour en UTC et nécessite que les secondes soient une chaîne et génère un objet UTC Time, tandis que
affiche une valeur de retour dans le fuseau horaire LOCAL, nécessite normalement un argument FixNum, mais l'objet Time lui-même est toujours en UTC même si l'affichage ne l'est pas.
Donc, même si j'ai transmis le même entier aux deux méthodes, j'ai apparemment deux résultats différents en raison du fonctionnement de la
#to_s
méthode de la classe . Cependant, comme @Eero a dû me rappeler deux fois:Une comparaison d'égalité entre les deux valeurs de retour renvoie toujours true. Encore une fois, cela est dû au fait que les valeurs sont fondamentalement les mêmes (bien que différentes classes, la
#==
méthode s'en occupe pour vous), mais la#to_s
méthode imprime des chaînes radicalement différentes. Bien que, si nous regardons les chaînes, nous pouvons voir qu'elles sont en effet la même heure, juste imprimées dans des fuseaux horaires différents.Clarification de l'argument de la méthode
Les documents disent également "Si un argument numérique est donné, le résultat est en heure locale." ce qui est logique, mais était un peu déroutant pour moi car ils ne donnent aucun exemple d'arguments non entiers dans les documents. Ainsi, pour certains exemples d'arguments non entiers:
vous ne pouvez pas utiliser un argument String, mais vous pouvez utiliser un argument Time dans
Time.at
et il renverra le résultat dans le fuseau horaire de l'argument:Repères
Après une discussion avec @AdamEberlin sur sa réponse, j'ai décidé de publier des repères légèrement modifiés pour que tout soit le plus égal possible. De plus, je ne veux plus jamais avoir à les reconstruire, c'est donc un endroit aussi bon que n'importe lequel pour les sauver.
Time.at (int) .to_datetime ~ 2,8 fois plus rapide
**** modifié pour ne pas être complètement et totalement incorrect dans tous les sens ****
**** repères ajoutés ****
la source
Time.at(1318996912) == DateTime.strptime("1318996912",'%s')
dans un fuseau horaire non UTC et vous verrez!Time.use_zone "Samoa" do Time.at(1318996912) == DateTime.strptime("1318996912",'%s') end
pour vérifier que les heures sont égales, il n'y a pas d'horodatage LOCAL et dans les deux cas, l'horodatage Unix est interprété comme étant en UTC.Time.at
présente l'objet Time résultant dans le fuseau horaire local etDateTime.strptime
présente l'objet DateTime résultant en UTC, mais quelle que soit la présentation, ils sont égaux, car ils sont le moment équivalent dans le temps.Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
affiche une valeur de retour dans le fuseau horaire LOCAL ne semble pas exacte ... Pouvez-vous vérifier? Je crois que votre déclaration ne serait vraie que si vousTime.zone.at(1318996912)
Une commande pour convertir la date et l'heure au format Unix, puis en chaîne
enfin strftime est utilisé pour formater la date
Exemple:
la source
Time.now.utc.to_i
.Cela vous indique la date du nombre de secondes à partir du moment où vous exécutez le code.
met (temps)
selon l'heure actuelle, je réponds à la question qu'il imprime
047-05-14 05:16:16 +0000
(1 milliard de secondes à l'avenir)ou si vous voulez compter des milliards de secondes à partir d'un moment particulier, c'est au format
Time.mktime(year, month,date,hours,minutes)
met ("je serais âgé de 1 milliard de secondes sur:" + temps)
la source
Si vous vouliez juste une date, vous pouvez faire
Date.strptime(invoice.date.to_s, '%s')
oùinvoice.date
vient sous la forme d'unFixnum
puis converti en unString
.la source
Time.at(1500923406).to_date.to_s
=>"2017-07-24"