2010-09-29 4 views
2

Je suis assez nouveau sur Python, donc j'espère que le problème que j'ai est une solution simple. Au travail, nous utilisons toujours Shell (ksh) ou Perl pour tous nos travaux de script. Depuis que Python est livré avec Solaris depuis un certain temps, il a (finalement) reçu le feu vert comme plate-forme de script. J'ai commencé à prototyper quelques améliorations à nos scripts en utilisant Python. Ce que j'essaie de faire est de prendre un horodatage et une chaîne représentant un horodatage et de créer un objet datetime pour une date arithmétique.Python datetime TypeError, integer attendu

Mon code exemple suivant:

#!/bin/python 

import datetime 

fileTime="201009211100" 
format = "YYYYmmdd" 

yIdxS = format.find('Y') 
yIdxE = format.rfind('Y') 

if not fileTime[yIdxS:yIdxE+1].isdigit(): 
    print "ERROR: Year in wrong format" 
    exit 
else: 
    print "Year [" + fileTime[yIdxS:yIdxE+1] + "]" 

mIdxS = format.find('m') 
mIdxE = format.rfind('m') 

if not fileTime[mIdxS:mIdxE+1].isdigit(): 
    print "ERROR: Month in wrong format" 
    exit 
else: 
    print "Month [" + fileTime[mIdxS:mIdxE+1] + "]" 

dIdxS = format.find('d') 
dIdxE = format.rfind('d') 

if not fileTime[dIdxS:dIdxE+1].isdigit(): 
    print "ERROR: Day in wrong format" 
    exit 
else: 
    print "Day [" + fileTime[dIdxS:dIdxE+1] + "]" 


old = datetime.date(fileTime[yIdxS:yIdxE+1], \ 
        fileTime[mIdxS:mIdxE+1], \ 
        fileTime[dIdxS:dIdxE+1]); 

Je reçois la sortie suivante/erreur:

Year [2010] 
Month [09] 
Day [21] 
Traceback (most recent call last): 
    File "./example.py", line 37, in <module> 
    fileTime[dIdxS:dIdxE+1]); 
TypeError: an integer is required 

Je ne comprends pas pourquoi je reçois cette exception TypeError. Ma compréhension du typage dynamique de Python est que je n'aurais pas besoin de convertir une chaîne en un entier si la chaîne est tous des chiffres.

Donc, le problème semble être soit je manque quelque chose dont j'ai besoin, ou ma compréhension de la langue est erronée.

Toute aide serait grandement appréciée. Merci.

+0

Une petite convention couramment utilisée: utiliser pour la première ligne '#/usr/bin/python' env!. Voir [cette question] (http://stackoverflow.com/questions/2429511/why-do-people-write-usr-bin-env-python-on-the-first-line-of-a-python-script) . – snapshoe

Répondre

5

envisager fortement d'utiliser datetime.datetime.strptime:

import datetime 

tests=["201009211100","201009211199"] 
for fileTime in tests: 
    try: 
     date=datetime.datetime.strptime(fileTime,'%Y%m%d%H%M') 
     print(date) 
    except ValueError as err: 
     print(fileTime,err) 

# 2010-09-21 11:00:00 
# ('201009211199', ValueError('unconverted data remains: 9',)) 

Ou, si vous installez le module tiers, dateutil, vous pouvez l'analyser comme ceci:

In [106]: import dateutil.parser as dparser 

In [107]: dparser.parse('201009211100') 
Out[107]: datetime.datetime(2010, 9, 21, 11, 0) 

Notez que dateutil tente d'analyser la chaîne sans vous déclarer explicitement le format. Cela doit être utilisé avec précaution (avec test et contrôle sur les chaînes d'entrée admissibles) car sinon, il existe des dates ambiguës que dateutil peut analyser de façon incorrecte.

+0

Ceci est certainement la bonne façon de le faire - briser les chaînes par position est certainement l'une de ces choses que vous iriez à Python pour s'éloigner de – Gaius

+0

Awesome, Thanks! Cela fonctionne également très bien pour tous ces horodatages différemment formatés comme YYYY-mm-jj, YYYYmmddHHMM, etc.C'est là que je me dirigeais finalement. – LukeFu

0

Python est plus fortement typé; il ne convertit pas automatiquement les chaînes en entier. La fonction globale int est nécessaire pour effectuer la conversion.

+0

Voulez-vous dire atoi? – Gaius

1

datetime.date veut des entiers. Modifier la dernière ligne de votre code comme celui-ci pour obtenir les résultats souhaités:

old = datetime.date(int(fileTime[yIdxS:yIdxE+1]), \ 
       int(fileTime[mIdxS:mIdxE+1]), \ 
       int(fileTime[dIdxS:dIdxE+1])); 

Cependant, il y a un moyen plus facile et peut-être plus pythonique aussi:

old = datetime.datetime.strptime(fileTime, '%Y%m%d%H%M') 

Faire cela en haut de votre script, vous obtenez la facilité d'extraction des différentes pièces comme si:

print 'Month: %d' % old.month