2009-01-04 7 views
35

Je voudrais un moyen d'afficher les temps naturels pour les éléments datés en Python. Semblable à la façon dont Twitter affichera un message de "il y a un instant", "il y a quelques minutes", "il y a trois heures", etc. "Jours naturels/relatifs en Python

Django 1.0 a une méthode" humanize "dans django .contrib. Je n'utilise pas le framework Django, et même si c'était le cas, c'est plus limité que ce que je voudrais.

S'il vous plaît laissez-moi (et des générations de futurs chercheurs) savoir s'il existe déjà une bonne solution de travail. Puisque c'est une tâche assez commune, j'imagine qu'il doit y avoir quelque chose.

+0

Je trouve ceci: http://code.google.com/p/parsedatetime/ Mais cela semble être pour analyser différentes formes de dates , alors que je suis simplement intéressé par le formatage d'un objet datetime. – jamtoday

Répondre

16

Bien que cela ne vous soit pas utile en ce moment même, cela peut être le cas pour les futurs chercheurs: Le module babel, qui traite toutes sortes de choses locales, a une fonction pour faire plus ou moins ce que vous voulez. Actuellement, ce n'est que dans leur coffre, pas dans la dernière version publique (version 0.9.4). Une fois que les terres de fonctionnalité dans un communiqué, vous pouvez faire quelque chose comme:

from datetime import timedelta 
from babel.dates import format_timedelta 
delta = timedelta(days=6) 
format_timedelta(delta, locale='en_US') 
u'1 week' 

Ceci est pris directement à partir the babel documentation on time delta formatting. Cela vous permettra au moins d'obtenir des parties du chemin. Il ne fera pas de flou au niveau des "moments passés" et autres, mais il fera "n minutes" etc correctement pluralisé.

Pour ce que ça vaut, le module babel contient également des fonctions pour le formatage des dates et des heures selon les paramètres régionaux, ce qui peut être utile lorsque le delta temporel est grand.

+0

Comment faire pareil dans Python 3 si python3-babel n'est pas disponible dans les dépôts de distribution? Merci. –

7

Ou vous pouvez facilement adapter timesince.py de Django qui n'a que 2 autres dépendances à lui-même: une pour la traduction (dont vous n'avez pas forcément besoin) et une pour les fuseaux horaires (qui peuvent être facilement adaptés). En passant, Django has a BSD license, ce qui est assez flexible, vous pourrez l'utiliser dans n'importe quel projet que vous utilisez actuellement.

35

Les dates Twitter en particulier sont intéressantes car elles ne sont relatives que pour le premier jour. Après 24 heures, ils montrent juste le mois et le jour. Après une année, ils commencent à montrer les deux derniers chiffres de l'année. Voici un exemple de fonction qui fait quelque chose de plus proche des dates relatives de Twitter, bien qu'il montre toujours l'année aussi après 24 heures. Il s'agit uniquement des paramètres régionaux aux États-Unis, mais vous pouvez toujours le modifier au besoin.

# tested in Python 2.7 
import datetime 
def prettydate(d): 
    diff = datetime.datetime.utcnow() - d 
    s = diff.seconds 
    if diff.days > 7 or diff.days < 0: 
     return d.strftime('%d %b %y') 
    elif diff.days == 1: 
     return '1 day ago' 
    elif diff.days > 1: 
     return '{} days ago'.format(diff.days) 
    elif s <= 1: 
     return 'just now' 
    elif s < 60: 
     return '{} seconds ago'.format(s) 
    elif s < 120: 
     return '1 minute ago' 
    elif s < 3600: 
     return '{} minutes ago'.format(s/60) 
    elif s < 7200: 
     return '1 hour ago' 
    else: 
     return '{} hours ago'.format(s/3600) 
+0

Votre solution est de loin la plus petite et la plus élégante. Cela implique simplement que nous devons traduire toutes les chaînes. Mais je vais prendre celui-là, merci! –

7

Il est the humanize package:

>>> import humanize 
>>> import datetime 
>>> humanize.naturalday(datetime.datetime.now()) 
'today' 
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1)) 
'yesterday' 
>>> humanize.naturalday(datetime.date(2007, 6, 5)) 
'Jun 05' 
>>> humanize.naturaldate(datetime.date(2007, 6, 5)) 
'Jun 05 2007' 
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1)) 
'a second ago' 
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600)) 
'an hour ago' 

Exemples pour votre cas d'utilisation:

>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=36000)) 
'10 hours ago' 
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=360000)) 
'4 days ago' 
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600000)) 
'a month ago' 

plus (voir le lien ci-dessus), il prend également en charge l'humanisation de:

  • entiers
  • taille des fichiers
  • flotteurs (à des nombres fractionnaires)