Python 中的自然日/相对日

发布于 2024-07-11 21:20:41 字数 240 浏览 11 评论 0原文

我想要一种在 Python 中显示日期项目的自然时间的方法。 类似于 Twitter 将显示“一会儿前”、“几分钟前”、“两小时前”、“三天前”等消息。Django

1.0 在 django.contrib 中有一个“人性化”方法。 我没有使用 Django 框架,即使我使用了,它也比我想要的更有限。

请让我(以及未来几代搜索者)知道是否已经有一个好的工作解决方案。 既然这是一个很常见的任务,我想一定有什么东西。

I'd like a way to show natural times for dated items in Python. Similar to how Twitter will show a message from "a moment ago", "a few minutes ago", "two hours ago", "three days ago", etc.

Django 1.0 has a "humanize" method in django.contrib. I'm not using the Django framework, and even if I were, it's more limited than what I'd like.

Please let me (and generations of future searchers) know if there is a good working solution already. Since this is a common enough task, I imagine there must be something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

秋日私语 2024-07-18 21:20:41

具体的 Twitter 日期很有趣,因为它们仅与第一天相关。 24 小时后,他们只显示月份和日期。 一年后,它们开始显示年份的最后两位数字。 下面是一个示例函数,它执行的操作与 Twitter 相对日期更相似,但它总是在 24 小时后显示年份。 它仅适用于美国区域设置,但您随时可以根据需要更改它。

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

Twitter dates in specific are interesting because they are relative only for the first day. After 24 hours they just show the month and day. After a year they start showing the last two digits of the year. Here's a sample function that does something more akin to Twitter relative dates, though it always shows the year too after 24 hours. It's US locale only, but you can always alter it as needed.

# 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)
听风吹 2024-07-18 21:20:41

虽然目前对您没有用处,但对未来的搜索者可能有用:
babel 模块处理各种语言环境的东西,有一个函数可以或多或少地做你想做的事情。 目前它只在他们的主干中,而不是在最新的公开版本(版本 0.9.4)中。 一旦该功能发布,您可以执行以下操作:

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

这直接取自 有关时间增量格式化的 babel 文档。 这至少可以帮助你完成部分任务。 它不会将模糊度降低到“片刻之前”等级别,但它会正确地进行“n 分钟”等复数形式。

值得一提的是,babel 模块还包含根据区域设置格式化日期和时间的函数,当时间增量很大时这可能很有用。

While not useful to you at this very moment, it may be so for future searchers:
The babel module, which deals with all sorts of locale stuff, has a function for doing more or less what you want. Currently it's only in their trunk though, not in the latest public release (version 0.9.4). Once the functionality lands in a release, you could do something like:

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

This is taken straight from the babel documentation on time delta formatting. This will at least get you parts of the way. It wont do fuzziness down to the level of "moments ago" and such, but it will do "n minutes" etc. correctly pluralized.

For what it's worth, the babel module also contains functions for formatting dates and times according to locale, Which might be useful when the time delta is large.

胡渣熟男 2024-07-18 21:20:41

人性化包

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

您的用例示例:

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

进一步(参见上面的链接)它还支持

  • 整数
  • 的人性化:文件大小
  • 浮动(小数)

There is 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'

Examples for your use case:

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

Further (see link above) it also supports humanization of:

  • integers
  • file sizes
  • floats (to fractional numbers)
无边思念无边月 2024-07-18 21:20:41

或者您可以轻松地从 Django 改编 timesince.py ,它本身只有 2 个其他依赖项:一个用于翻译(您可能不需要),另一个用于时区(可以轻松调整)。

顺便说一句,Django 有一个相当灵活的 BSD 许可证,你会能够在您当前使用的任何项目中使用它。

Or you could easily adapt timesince.py from Django which only has 2 other dependencies to itself: one for translation (which you might not need) and one for timezones (which can be easily adapted).

By the way, Django has a BSD license which is pretty flexible, you'll be able to use it in whatever project you are currently using.

樱&纷飞 2024-07-18 21:20:41

发现obe可以这样使用maya

pip install maya
>>> maya.when("3 week ago").datetime().strftime("%Y-%m-%d")
'2020-04-27'

Found out that obe can use maya like this

pip install maya
>>> maya.when("3 week ago").datetime().strftime("%Y-%m-%d")
'2020-04-27'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文