2009-03-30 3 views
147

Je suis en mesure d'analyser des chaînes contenant la date/heure avec time.strptimeComment puis-je analyser une chaîne de temps contenant des millisecondes avec python?

>>> import time 
>>> time.strptime('30/03/09 16:31:32', '%d/%m/%y %H:%M:%S') 
(2009, 3, 30, 16, 31, 32, 0, 89, -1) 

Comment puis-je analyser une chaîne de temps qui contient millisecondes?

>>> time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.5/_strptime.py", line 333, in strptime 
    data_string[found.end():]) 
ValueError: unconverted data remains: .123 

Répondre

218

Python 2.6 a ajouté une nouvelle strftime/strptime macro %f, qui fait microsecondes. Je ne sais pas si cela est documenté n'importe où. Mais si vous utilisez 2.6 ou 3.0, vous pouvez le faire:

time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f') 

Edit: Je ne travaille vraiment avec le module time, donc je ne l'ai pas remarqué ce au début, mais il semble que time.struct_time ne stocke pas réellement millisecondes/microsecondes. Vous pouvez être mieux d'utiliser datetime, comme ceci:

>>> from datetime import datetime 
>>> a = datetime.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f') 
>>> a.microsecond 
123000 
+3

Merci http://docs.python.org/library/datetime.html: Nouveauté de la version 2.6: les objets time et datetime prennent en charge un code au format% f qui s'étend au nombre de microsecondes de l'objet, laissé à six endroits. – ilkinulas

+5

Woa Je peux dire que les docs Python ont besoin d'être mis à jour. [Docs pour le module de temps] (http://docs.python.org/library/time.html#time.strftime) ne dit rien à propos de '% f'. – phunehehe

+1

hm, zéro-rembourré sur le * gauche * serait faux, non? –

1

Ma première pensée était d'essayer le passer '30/03/09 16: 31: (. Avec une période au lieu de deux points entre les secondes et les millisecondes) 32,123 Mais cela ne fonctionne pas. Un coup d'œil rapide sur les docs indique que les secondes fractionnaires sont ignorées dans tous les cas ...

Ah, différences de version. C'était reported as a bug et maintenant dans 2.6+ vous pouvez utiliser "% S.% f" pour l'analyser.

+0

Cela ne fonctionne pas; time.strptime ne fait pas de millisecondes. – DNS

+0

Oui, j'ai vu ça quand je l'ai essayé, donc l'édition. – MarkusQ

1

à partir des listes de diffusion python: parsing millisecond thread. Il y a une fonction affichée là-bas qui semble faire le travail, bien que comme mentionné dans les commentaires de l'auteur c'est un peu un hack. Il utilise des expressions régulières pour gérer l'exception qui est levée, puis effectue des calculs.

Vous pouvez aussi essayer les expressions régulières et les calculs avant de les passer à strptime.

+0

oui, je connais ce fil. Mais je cherche un moyen plus simple. Y at-il un module dans la librairie standart python qui fait l'analyse du temps en millisecondes? – ilkinulas

3

Pour donner le code qui fait référence à nstehr's answer (de its source):

def timeparse(t, format): 
    """Parse a time string that might contain fractions of a second. 

    Fractional seconds are supported using a fragile, miserable hack. 
    Given a time string like '02:03:04.234234' and a format string of 
    '%H:%M:%S', time.strptime() will raise a ValueError with this 
    message: 'unconverted data remains: .234234'. If %S is in the 
    format string and the ValueError matches as above, a datetime 
    object will be created from the part that matches and the 
    microseconds in the time string. 
    """ 
    try: 
     return datetime.datetime(*time.strptime(t, format)[0:6]).time() 
    except ValueError, msg: 
     if "%S" in format: 
      msg = str(msg) 
      mat = re.match(r"unconverted data remains:" 
          " \.([0-9]{1,6})$", msg) 
      if mat is not None: 
       # fractional seconds are present - this is the style 
       # used by datetime's isoformat() method 
       frac = "." + mat.group(1) 
       t = t[:-len(frac)] 
       t = datetime.datetime(*time.strptime(t, format)[0:6]) 
       microsecond = int(float(frac)*1e6) 
       return t.replace(microsecond=microsecond) 
      else: 
       mat = re.match(r"unconverted data remains:" 
           " \,([0-9]{3,3})$", msg) 
       if mat is not None: 
        # fractional seconds are present - this is the style 
        # used by the logging module 
        frac = "." + mat.group(1) 
        t = t[:-len(frac)] 
        t = datetime.datetime(*time.strptime(t, format)[0:6]) 
        microsecond = int(float(frac)*1e6) 
        return t.replace(microsecond=microsecond) 

     raise 
12

Je sais c'est une question plus mais je suis encore en utilisant Python et je besoin 2.4.3 pour trouver une meilleure façon de convertir la chaîne de données un datetime.

La solution si datetime ne supporte pas% f et sans avoir besoin d'un try/except est:

(dt, mSecs) = row[5].strip().split(".") 
    dt = datetime.datetime(*time.strptime(dt, "%Y-%m-%d %H:%M:%S")[0:6]) 
    mSeconds = datetime.timedelta(microseconds = int(mSecs)) 
    fullDateTime = dt + mSeconds 

Cela fonctionne pour la chaîne d'entrée "2010-10-06 09: 42: 52,266000"

+1

'dt.replace (microsecond = int (mSecs)) ' – haridsv

+0

Cela s'applique à Python 2.5 et versions antérieures. Python 2.6 supporte strptime '% f' – smci

0

pour python 2 Je l'ai fait

print (time.strftime("%H:%M:%S", time.localtime(time.time())) + "." + str(time.time()).split(".",1)[1]) 

il affiche le temps "% H:% M:% S" (. avant et après), divise le time.time() à deux sous-chaînes et xxxxxxx.xx depuis .xx sont mes millisecondes j'ajoute le second sous corde à mon "% H:% M:% S"

espoir qui fait sens :) Exemple de sortie:

13:31:21.72 Blink 01


13:31:21.81 FIN DE CLIGNOTEMENT 01


13: 31: 26,3 clignements 01


13: 31: 26.39 FIN DE CLIGNOTEMENT 01


13: 31: 34,65 À partir de la voie 01


Questions connexes