Python中的用户友好时间格式?

时间:2022-11-24 22:55:54

Python: I need to show file modification times in the "1 day ago", "two hours ago", format.

Python:我需要在“1天前”、“2小时前”格式中显示文件修改时间。

Is there something ready to do that? It should be in English.

有什么东西准备好了吗?应该是英语。

11 个解决方案

#1


100  

The code was originally published on a blog post "Python Pretty Date function" (http://evaisse.com/post/93417709/python-pretty-date-function)

代码最初发布在“Python Pretty Date函数”的博客文章中(http://evaisse.com/post/93417709/ Python - prettydate函数)

It is reproduced here as the blog account has been suspended and the page is no longer available.

它在这里被复制,因为博客帐户被暂停,页面不再可用。

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"

#2


28  

If you happen to be using Django, then new in version 1.4 is the naturaltime template filter.

如果您碰巧正在使用Django,那么1.4版本中的新版本是naturaltime模板过滤器。

To use it, first add 'django.contrib.humanize' to your INSTALLED_APPS setting in settings.py, and {% load humanize %} into the template you're using the filter in.

要使用它,请首先添加“django.managb”。把你的INSTALLED_APPS设置人性化。py和{%}将humanize %}加载到正在使用筛选器的模板中。

Then, in your template, if you have a datetime variable my_date, you can print its distance from the present by using {{ my_date|naturaltime }}, which will be rendered as something like 4 minutes ago.

然后,在模板中,如果您有一个datetime变量my_date,您可以使用{{my_date|naturaltime}来打印它与当前的距离,该}将在4分钟前呈现。

Other new things in Django 1.4.

Django 1.4中的其他新内容。

Documentation for naturaltime and other filters in the django.contrib.humanize set.

自然时间和其他过滤器的文件。人性化设置。

#3


14  

In looking for the same thing with the additional requirement that it handle future dates, I found this: http://pypi.python.org/pypi/py-pretty/1

在查找它处理未来日期的附加要求时,我发现:http://pypi.python.org/pypi/py-pretty/1

Example code (from 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'

#4


5  

The answer Jed Smith linked to is good, and I used it for a year or so, but I think it could be improved in a few ways:

Jed Smith联系到的答案是好的,我用了一年左右,但是我认为它可以在几个方面得到改进:

  • It's nice to be able to define each time unit in terms of the preceding unit, instead of having "magic" constants like 3600, 86400, etc. sprinkled throughout the code.
  • 很高兴能够根据前面的单元定义每个时间单元,而不是像3600、86400这样的“神奇”常量分布在代码中。
  • After much use, I find I don't want to go to the next unit quite so eagerly. Example: both 7 days and 13 days will show as "1 week"; I'd rather see "7 days" or "13 days" instead.
  • 经过大量的使用,我发现我不想如此急切地去下一个单元。例如:7天和13天将显示为“1周”;我宁愿看“7天”或“13天”。

Here's what I came up with:

以下是我的想法:

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'))

Notice how every tuple in intervals is easy to interpret and check: a 'minute' is 60 seconds; an 'hour' is 60 minutes; etc. The only fudge is setting weeks_per_month to its average value; given the application, that should be fine. (And note that it's clear at a glance that the last three constants multiply out to 365.242, the number of days per year.)

注意,每一个元组在间隔内是如何容易解释和检查的:一分钟是60秒;一小时是60分钟;等等。唯一的问题是将weeks_per_month设置为其平均值;考虑到应用程序,这应该没问题。(请注意,一眼就能看出,最后三个常数的乘积是365.242,即每年的天数。)

One downside to my function is that it doesn't do anything outside the "## units" pattern: "Yesterday", "just now", etc. are right out. Then again, the original poster didn't ask for these fancy terms, so I prefer my function for its succinctness and the readability of its numerical constants. :)

我的函数的一个缺点是它不做任何超出“## unit”模式之外的事情:“昨天”、“现在”等等。同样,最初的海报也没有要求这些花哨的术语,所以我更喜欢我的函数,因为它的简洁和数值常数的可读性。:)

#5


4  

You can also do that with arrow package

你也可以用箭头包来做

From github page:

从github页面:

>>> import arrow
>>> utc = arrow.utcnow()
>>> utc = utc.replace(hours=-1)
>>> local.humanize()
'an hour ago'

#6


4  

The ago package provides this. Call human on a datetime object to get a human readable description of the difference.

ago包提供了这一点。调用datetime对象上的human来获得对差异的可读描述。

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

#7


2  

There is humanize package:

有人性化的包:

>>> from datetime import datetime, timedelta
>>> import humanize # $ pip install humanize
>>> humanize.naturaltime(datetime.now() - timedelta(days=1))
'a day ago'
>>> humanize.naturaltime(datetime.now() - timedelta(hours=2))
'2 hours ago'

It supports localization , internationalization :

支持本地化l10n,国际化i18n:

>>> _ = humanize.i18n.activate('ru_RU')
>>> print humanize.naturaltime(datetime.now() - timedelta(days=1))
день назад
>>> print humanize.naturaltime(datetime.now() - timedelta(hours=2))
2 часа назад

#8


1  

I have written a detailed blog post for the solution on http://sunilarora.org/17329071 I am posting a quick snippet here as well.

我在http://sunilarora.org/17329071为解决方案写了一篇详细的博客文章,我也在这里发布了一个简短的片段。

from datetime import datetime
from dateutil.relativedelta import relativedelta

def get_fancy_time(d, display_full_version = False):
    """Returns a user friendly date format
    d: some datetime instace in the past
    display_second_unit: True/False
    """
    #some helpers lambda's
    plural = lambda x: 's' if x > 1 else ''
    singular = lambda x: x[:-1]
    #convert pluran (years) --> to singular (year)
    display_unit = lambda unit, name: '%s %s%s'%(unit, name, plural(unit)) if unit > 0 else ''

    #time units we are interested in descending order of significance
    tm_units = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']

    rdelta = relativedelta(datetime.utcnow(), d) #capture the date difference
    for idx, tm_unit in enumerate(tm_units):
        first_unit_val = getattr(rdelta, tm_unit)
        if first_unit_val > 0:
            primary_unit = display_unit(first_unit_val, singular(tm_unit))
            if display_full_version and idx < len(tm_units)-1:
                next_unit = tm_units[idx + 1]
                second_unit_val = getattr(rdelta, next_unit)
                if second_unit_val > 0:
                    secondary_unit = display_unit(second_unit_val, singular(next_unit))
                    return primary_unit + ', '  + secondary_unit
            return primary_unit
    return None

#9


0  

This is the gist of @sunil 's post

这是@sunil的文章的主旨

>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta
>>> then = datetime(2003, 9, 17, 20, 54, 47, 282310)
>>> relativedelta(then, datetime.now())
relativedelta(years=-11, months=-3, days=-9, hours=-18, minutes=-17, seconds=-8, microseconds=+912664)

#10


0  

Using datetime objects with tzinfo:

使用带有tzinfo的datetime对象:

def time_elapsed(etime):
    # need to add tzinfo to datetime.utcnow
    now = datetime.datetime.utcnow().replace(tzinfo=etime.tzinfo)
    opened_for = (now - etime).total_seconds()
    names = ["seconds","minutes","hours","days","weeks","months"]
    modulos = [ 1,60,3600,3600*24,3600*24*7,3660*24*30]
    values = []
    for m in modulos[::-1]:
    values.append(int(opened_for / m))
    opened_for -= values[-1]*m
pretty = [] 
for i,nm in enumerate(names[::-1]):
    if values[i]!=0:
        pretty.append("%i %s" % (values[i],nm))
return " ".join(pretty)

#11


0  

You can download and install from below link. It should be more helpful for you. It has been providing user friendly message from second to year.

您可以从下面的链接下载和安装。它应该对你更有帮助。它每年都会提供用户友好的信息。

It's well tested.

这是很好的测试。

https://github.com/nareshchaudhary37/timestamp_content

https://github.com/nareshchaudhary37/timestamp_content

Below steps to install into your virtual env.

以下步骤将安装到虚拟环境中。

git clone https://github.com/nareshchaudhary37/timestamp_content
cd timestamp-content
python setup.py

#1


100  

The code was originally published on a blog post "Python Pretty Date function" (http://evaisse.com/post/93417709/python-pretty-date-function)

代码最初发布在“Python Pretty Date函数”的博客文章中(http://evaisse.com/post/93417709/ Python - prettydate函数)

It is reproduced here as the blog account has been suspended and the page is no longer available.

它在这里被复制,因为博客帐户被暂停,页面不再可用。

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"

#2


28  

If you happen to be using Django, then new in version 1.4 is the naturaltime template filter.

如果您碰巧正在使用Django,那么1.4版本中的新版本是naturaltime模板过滤器。

To use it, first add 'django.contrib.humanize' to your INSTALLED_APPS setting in settings.py, and {% load humanize %} into the template you're using the filter in.

要使用它,请首先添加“django.managb”。把你的INSTALLED_APPS设置人性化。py和{%}将humanize %}加载到正在使用筛选器的模板中。

Then, in your template, if you have a datetime variable my_date, you can print its distance from the present by using {{ my_date|naturaltime }}, which will be rendered as something like 4 minutes ago.

然后,在模板中,如果您有一个datetime变量my_date,您可以使用{{my_date|naturaltime}来打印它与当前的距离,该}将在4分钟前呈现。

Other new things in Django 1.4.

Django 1.4中的其他新内容。

Documentation for naturaltime and other filters in the django.contrib.humanize set.

自然时间和其他过滤器的文件。人性化设置。

#3


14  

In looking for the same thing with the additional requirement that it handle future dates, I found this: http://pypi.python.org/pypi/py-pretty/1

在查找它处理未来日期的附加要求时,我发现:http://pypi.python.org/pypi/py-pretty/1

Example code (from 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'

#4


5  

The answer Jed Smith linked to is good, and I used it for a year or so, but I think it could be improved in a few ways:

Jed Smith联系到的答案是好的,我用了一年左右,但是我认为它可以在几个方面得到改进:

  • It's nice to be able to define each time unit in terms of the preceding unit, instead of having "magic" constants like 3600, 86400, etc. sprinkled throughout the code.
  • 很高兴能够根据前面的单元定义每个时间单元,而不是像3600、86400这样的“神奇”常量分布在代码中。
  • After much use, I find I don't want to go to the next unit quite so eagerly. Example: both 7 days and 13 days will show as "1 week"; I'd rather see "7 days" or "13 days" instead.
  • 经过大量的使用,我发现我不想如此急切地去下一个单元。例如:7天和13天将显示为“1周”;我宁愿看“7天”或“13天”。

Here's what I came up with:

以下是我的想法:

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'))

Notice how every tuple in intervals is easy to interpret and check: a 'minute' is 60 seconds; an 'hour' is 60 minutes; etc. The only fudge is setting weeks_per_month to its average value; given the application, that should be fine. (And note that it's clear at a glance that the last three constants multiply out to 365.242, the number of days per year.)

注意,每一个元组在间隔内是如何容易解释和检查的:一分钟是60秒;一小时是60分钟;等等。唯一的问题是将weeks_per_month设置为其平均值;考虑到应用程序,这应该没问题。(请注意,一眼就能看出,最后三个常数的乘积是365.242,即每年的天数。)

One downside to my function is that it doesn't do anything outside the "## units" pattern: "Yesterday", "just now", etc. are right out. Then again, the original poster didn't ask for these fancy terms, so I prefer my function for its succinctness and the readability of its numerical constants. :)

我的函数的一个缺点是它不做任何超出“## unit”模式之外的事情:“昨天”、“现在”等等。同样,最初的海报也没有要求这些花哨的术语,所以我更喜欢我的函数,因为它的简洁和数值常数的可读性。:)

#5


4  

You can also do that with arrow package

你也可以用箭头包来做

From github page:

从github页面:

>>> import arrow
>>> utc = arrow.utcnow()
>>> utc = utc.replace(hours=-1)
>>> local.humanize()
'an hour ago'

#6


4  

The ago package provides this. Call human on a datetime object to get a human readable description of the difference.

ago包提供了这一点。调用datetime对象上的human来获得对差异的可读描述。

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

#7


2  

There is humanize package:

有人性化的包:

>>> from datetime import datetime, timedelta
>>> import humanize # $ pip install humanize
>>> humanize.naturaltime(datetime.now() - timedelta(days=1))
'a day ago'
>>> humanize.naturaltime(datetime.now() - timedelta(hours=2))
'2 hours ago'

It supports localization , internationalization :

支持本地化l10n,国际化i18n:

>>> _ = humanize.i18n.activate('ru_RU')
>>> print humanize.naturaltime(datetime.now() - timedelta(days=1))
день назад
>>> print humanize.naturaltime(datetime.now() - timedelta(hours=2))
2 часа назад

#8


1  

I have written a detailed blog post for the solution on http://sunilarora.org/17329071 I am posting a quick snippet here as well.

我在http://sunilarora.org/17329071为解决方案写了一篇详细的博客文章,我也在这里发布了一个简短的片段。

from datetime import datetime
from dateutil.relativedelta import relativedelta

def get_fancy_time(d, display_full_version = False):
    """Returns a user friendly date format
    d: some datetime instace in the past
    display_second_unit: True/False
    """
    #some helpers lambda's
    plural = lambda x: 's' if x > 1 else ''
    singular = lambda x: x[:-1]
    #convert pluran (years) --> to singular (year)
    display_unit = lambda unit, name: '%s %s%s'%(unit, name, plural(unit)) if unit > 0 else ''

    #time units we are interested in descending order of significance
    tm_units = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']

    rdelta = relativedelta(datetime.utcnow(), d) #capture the date difference
    for idx, tm_unit in enumerate(tm_units):
        first_unit_val = getattr(rdelta, tm_unit)
        if first_unit_val > 0:
            primary_unit = display_unit(first_unit_val, singular(tm_unit))
            if display_full_version and idx < len(tm_units)-1:
                next_unit = tm_units[idx + 1]
                second_unit_val = getattr(rdelta, next_unit)
                if second_unit_val > 0:
                    secondary_unit = display_unit(second_unit_val, singular(next_unit))
                    return primary_unit + ', '  + secondary_unit
            return primary_unit
    return None

#9


0  

This is the gist of @sunil 's post

这是@sunil的文章的主旨

>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta
>>> then = datetime(2003, 9, 17, 20, 54, 47, 282310)
>>> relativedelta(then, datetime.now())
relativedelta(years=-11, months=-3, days=-9, hours=-18, minutes=-17, seconds=-8, microseconds=+912664)

#10


0  

Using datetime objects with tzinfo:

使用带有tzinfo的datetime对象:

def time_elapsed(etime):
    # need to add tzinfo to datetime.utcnow
    now = datetime.datetime.utcnow().replace(tzinfo=etime.tzinfo)
    opened_for = (now - etime).total_seconds()
    names = ["seconds","minutes","hours","days","weeks","months"]
    modulos = [ 1,60,3600,3600*24,3600*24*7,3660*24*30]
    values = []
    for m in modulos[::-1]:
    values.append(int(opened_for / m))
    opened_for -= values[-1]*m
pretty = [] 
for i,nm in enumerate(names[::-1]):
    if values[i]!=0:
        pretty.append("%i %s" % (values[i],nm))
return " ".join(pretty)

#11


0  

You can download and install from below link. It should be more helpful for you. It has been providing user friendly message from second to year.

您可以从下面的链接下载和安装。它应该对你更有帮助。它每年都会提供用户友好的信息。

It's well tested.

这是很好的测试。

https://github.com/nareshchaudhary37/timestamp_content

https://github.com/nareshchaudhary37/timestamp_content

Below steps to install into your virtual env.

以下步骤将安装到虚拟环境中。

git clone https://github.com/nareshchaudhary37/timestamp_content
cd timestamp-content
python setup.py