81 votes

Format de temps convivial en Python ?

Python : J'ai besoin d'afficher les temps de modification des fichiers dans le format "il y a un jour", "il y a deux heures".

Il y a quelque chose de prêt pour faire ça ? Ça devrait être en anglais.

140voto

Jed Smith Points 9022

Ce code a été publié à l'origine sur un billet de blog "Python Pretty Date function" ( http://evaisse.com/post/93417709/python-pretty-date-function )

Il est reproduit ici car le compte du blog a été suspendu et la page n'est plus disponible.

def pretty_date(time=False):
    """
    Get a datetime object or a int() Epoch timestamp and return a
    pretty string like 'an hour ago', 'Yesterday', '3 months ago',
    'just now', etc
    """
    from datetime import datetime
    now = datetime.now()
    if type(time) is int:
        diff = now - datetime.fromtimestamp(time)
    elif isinstance(time,datetime):
        diff = now - time
    elif not time:
        diff = now - now
    second_diff = diff.seconds
    day_diff = diff.days

    if day_diff < 0:
        return ''

    if day_diff == 0:
        if second_diff < 10:
            return "just now"
        if second_diff < 60:
            return str(second_diff) + " seconds ago"
        if second_diff < 120:
            return "a minute ago"
        if second_diff < 3600:
            return str(second_diff / 60) + " minutes ago"
        if second_diff < 7200:
            return "an hour ago"
        if second_diff < 86400:
            return str(second_diff / 3600) + " hours ago"
    if day_diff == 1:
        return "Yesterday"
    if day_diff < 7:
        return str(day_diff) + " days ago"
    if day_diff < 31:
        return str(day_diff / 7) + " weeks ago"
    if day_diff < 365:
        return str(day_diff / 30) + " months ago"
    return str(day_diff / 365) + " years ago"

3 votes

Qui est adapté à mes besoins exacts. Merci !

2 votes

Le lien n'existe plus et donne un Forbidden. Il faut un lien permanent ici ou déplacer le contenu dans cet article.

0 votes

@Chris : Merci pour l'info, et il était encore dans Google Cache alors je l'ai accroché.

33voto

plowman Points 5106

Si vous utilisez Django Dans la version 1.4, la nouveauté est la suivante naturaltime filtre de modèle.

Pour l'utiliser, il faut d'abord ajouter 'django.contrib.humanize' à votre INSTALLED_APPS dans settings.py, et {% load humanize %} dans le modèle dans lequel vous utilisez le filtre.

Ensuite, dans votre modèle, si vous avez une variable de temps de date my_date vous pouvez imprimer sa distance par rapport au présent en utilisant la fonction {{ my_date|naturaltime }} qui sera rendu comme quelque chose comme 4 minutes ago .

Autres nouveautés de Django 1.4.

Documentation pour naturaltime et d'autres filtres dans le django.contrib.humanize set.

0 votes

Est-il vraiment nécessaire de l'ajouter à INSTALLED_APPS ? Cela a fonctionné sans cela pour moi, bien que j'ai utilisé le filtre dans python, et non le modèle.

0 votes

Puis-je utiliser cette vue à l'intérieur

15voto

Karim Points 8533

En cherchant la même chose avec l'exigence supplémentaire qu'elle gère les dates futures, j'ai trouvé ceci : http://pypi.python.org/pypi/py-pretty/1

Exemple de code (du site) :

from datetime import datetime, timedelta
now = datetime.now()
hrago = now - timedelta(hours=1)
yesterday = now - timedelta(days=1)
tomorrow = now + timedelta(days=1)
dayafter = now + timedelta(days=2)

import pretty
print pretty.date(now)                      # 'now'
print pretty.date(hrago)                    # 'an hour ago'
print pretty.date(hrago, short=True)        # '1h ago'
print pretty.date(hrago, asdays=True)       # 'today'
print pretty.date(yesterday, short=True)    # 'yest'
print pretty.date(tomorrow)                 # 'tomorrow'

1 votes

Malheureusement, py-pretty ne semble pas permettre l'i18n.

5voto

Chip Hogg Points 330

La réponse dont Jed Smith a donné le lien est bonne, et je l'ai utilisée pendant un an environ, mais je pense qu'elle pourrait être améliorée de plusieurs façons :

  • Il est agréable de pouvoir définir chaque unité de temps en fonction de l'unité précédente, au lieu d'avoir des constantes "magiques" comme 3600, 86400, etc. disséminées dans le code.
  • Après une longue utilisation, je trouve que je ne veux pas passer à l'unité suivante avec autant d'impatience. Exemple : 7 jours et 13 jours sont affichés comme "1 semaine" ; je préférerais voir "7 jours" ou "13 jours" à la place.

Voici ce que j'ai trouvé :

def PrettyRelativeTime(time_diff_secs):
    # Each tuple in the sequence gives the name of a unit, and the number of
    # previous units which go into it.
    weeks_per_month = 365.242 / 12 / 7
    intervals = [('minute', 60), ('hour', 60), ('day', 24), ('week', 7),
                 ('month', weeks_per_month), ('year', 12)]

    unit, number = 'second', abs(time_diff_secs)
    for new_unit, ratio in intervals:
        new_number = float(number) / ratio
        # If the new number is too small, don't go to the next unit.
        if new_number < 2:
            break
        unit, number = new_unit, new_number
    shown_num = int(number)
    return '{} {}'.format(shown_num, unit + ('' if shown_num == 1 else 's'))

Remarquez comment chaque tuple dans intervals est facile à interpréter et à vérifier : une 'minute' est 60 secondes ; un 'hour' est 60 minutes ; etc. Le seul truc est la mise weeks_per_month à sa valeur moyenne ; compte tenu de l'application, cela devrait convenir. (Et notez qu'il est clair au premier coup d'œil que les trois dernières constantes se multiplient par 365,242, le nombre de jours par an).

Un inconvénient de ma fonction est qu'elle ne fait rien en dehors du modèle "## unités" : "Hier", "tout à l'heure", etc. sont exclus. Mais là encore, l'auteur de l'article original n'a pas demandé ces termes compliqués, et je préfère ma fonction pour sa concision et la lisibilité de ses constantes numériques :)

0 votes

Bonne solution. Garder les choses simples permet une plus grande réutilisation. Par exemple, on peut utiliser un suffixe pour le temps relatif. value + " ago" ou durée value + " left"

4voto

Le site il y a un an le fournit. Appelez human sur un datetime pour obtenir une description humainement lisible de la différence.

from ago import human
from datetime import datetime
from datetime import timedelta

ts = datetime.now() - timedelta(days=1, hours=5)

print(human(ts))
# 1 day, 5 hours ago

print(human(ts, precision=1))
# 1 day ago

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X