2009-02-04 8 views
2

J'ai deux méthodes que je suis en utilisant comme des balises personnalisées dans un moteur de template:Divers problèmes datetime Python

# Renders a <select> form field 
def select_field(options, selected_item, field_name): 
    options = [(str(v),str(v)) for v in options] 
    html = ['<select name="%s">' % field_name] 
    for k,v in options: 
     tmp = '<option ' 
     if k == selected_item: 
      tmp += 'selected ' 
     tmp += 'value="%s">%s</option>' % (k,v) 
     html.append(tmp) 
    html.append('</select>') 
    return '\n'.join(html) 

# Renders a collection of <select> fields for datetime values 
def datetime_field(current_dt, field_name): 
    if current_dt == None: 
     current_dt = datetime.datetime.now() 
    day = select_field(range(1, 32), current_dt.day, field_name + "_day") 
    month = select_field(range(1, 13), current_dt.month, field_name + "_month") 
    year = select_field(range(datetime.datetime.now().year, datetime.datetime.now().year + 10), current_dt.year, field_name + "_year") 
    hour = select_field(range(1, 13), current_dt.hour, field_name + "_hour") 
    minute = select_field(range(1, 60), current_dt.minute, field_name + "_minute") 
    period = select_field(['AM', 'PM'], 'AM', field_name + "_period") 
    return "\n".join([day, '/', month, '/', year, ' at ', hour, ':', minute, period]) 

Comme vous pouvez le voir dans les commentaires, je tente de générer sélectionner les champs pour la construction d'une valeur date et heure.

Ma première question est, comment faire pour que les plages du jour, du mois, de l'heure et des minutes utilisent deux chiffres? Par exemple, le code génère "1, 2, 3 ..." tandis que je voudrais "01, 02, 03". Ensuite, lorsque les champs sont générés, les valeurs du datetime fourni ne sont pas sélectionnées automatiquement, même si je demande à la méthode select_field d'ajouter un attribut "selected" lorsque la valeur est égale à la valeur du datetime fourni.

Enfin, comment puis-je obtenir l'identificateur de période de 12 heures (AM/PM) pour le datetime fourni? Pour le moment, je sélectionne simplement 'AM' par défaut, mais je voudrais fournir cette valeur à partir du datetime lui-même.

Répondre

5

Pour activer une gamme entière en deux chaînes de chiffres:

>>> range(13) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 
>>> [ '%02d' % i for i in range(13) ] 
['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] 

ensuite pour obtenir l'indicateur AM/PM:

>>> import datetime 
>>> current_dt = datetime.datetime.now() 
>>> current_dt 
datetime.datetime(2009, 2, 4, 22, 2, 14, 390000) 
>>> ['AM','PM'][current_dt.hour>=12] 
'PM' 

Voila!

+0

ce code était cool. ['AM', 'PM'] [current_dt.hour> = 12] – Merlin

1

Question 1:

>>> '%02d' % 2 
'02' 
>>> '%02d' % 59 
'59' 
0
  1. Fournissez une chaîne de format à la méthode select_field pour afficher les premiers zéros.

    >>> print "%02i" % (1,) 
    01 
    
  2. datetime.hour est 0-23, donc vous devez l'adapter lors du réglage du champ. C'est aussi la réponse sur la façon de détecter AM/PM. Assurez-vous de le convertir correctement.

1

Pour ajouter à ma réponse précédente, quelques commentaires sur la sélection de l'option sélectionnée.

D'abord, votre code de génération HTML serait plus robuste si plutôt que de diviser le début et la fin des balises HTML ...

html = ['<select name="%s">' % field_name] 
for k,v in options: 
    tmp = '<option ' 
    if k == selected_item: 
      tmp += 'selected ' 
    tmp += 'value="%s">%s</option>' % (k,v) 
    html.append(tmp) 
html.append('</select>') 

... vous les généré comme totalités atomiques:

opt_bits = ('<option %s value="%s">'% (['','selected'][str(v)==selected_item], str(v)) for v in options) 
# If running Python2.5, it's better to use: 'selected' if str(v)==selected_item else '' 
html = '<select name=%s>%s</select>' % '\n'.join(opt_bits) 

Deuxièmement, je ne sais pas pourquoi vous doublez la liste des options plutôt que de réutiliser le même nom de variable, comme je l'ai fait ci-dessus:

options = [(str(v),str(v)) for v in options] # ???? 

Cela est inutile, à moins que des options est vraiment un dict et vous quelque chose comme but:

[ (k,v) for k,v in options.iteritems() ] 

Enfin, votre code cassera si les éléments de liste contiennent des citations. Regardez dans la documentation Python pour les fonctions standard d'échappement HTML.

Bonne chance!

+0

Oui, bobince

Questions connexes