将日期时间字符串解析为 Django DateTimeField

Posted

技术标签:

【中文标题】将日期时间字符串解析为 Django DateTimeField【英文标题】:Parsing a Datetime String into a Django DateTimeField 【发布时间】:2012-01-28 00:51:24 【问题描述】:

我有一个 Django 应用程序,其模型包含 DateTimeField 类型的字段。 我正在以2008-04-10 11:47:58-05 的格式从网上提取数据。 我相信这个例子中的最后 3 个字符是时区。 如何在 DateTimeField 中保留该数据,两者之间是否可以轻松转换?将 DateTimeField 设置为仅包含上述格式的字符串会引发 ValidationError。

谢谢!

【问题讨论】:

【参考方案1】:

Django DateTimeField 的字符串格式为“%Y-%m-%dT%H:%M:%S.%fZ”。 因此,可以使用 strptime() 或 strptime() 使用这种格式来完成彼此之间的转换。

例如。对于字符串格式的值(2016-10-03T19:00:00.999Z),可以转换 以 Django 日期时间对象为:

from datetime import datetime

datetime_str = '2016-10-03T19:00:00.999Z'

datetime_object = datetime.strptime(datetime_str, "%Y-%m-%dT%H:%M:%S.%fZ")

【讨论】:

【参考方案2】:

您也可以使用Django's implementation。事实上,如果 Django 的解析器无法处理该格式,我会更喜欢它并且只使用其他东西。

例如:

>>> from django.utils.dateparse import parse_datetime
>>> parse_datetime('2016-10-03T19:00:00')
datetime.datetime(2016, 10, 3, 19, 0)
>>> parse_datetime('2016-10-03T19:00:00+0200')
datetime.datetime(2016, 10, 3, 19, 0, tzinfo=<django.utils.timezone.FixedOffset object at 0x8072546d8>)

要在不知道时区的情况下将其转换为正确的时区,请使用来自django.utils.timezone 的 make_aware。

所以最终,您的解析器实用程序将是:

from django.utils.dateparse import parse_datetime
from django.utils.timezone import is_aware, make_aware

def get_aware_datetime(date_str):
    ret = parse_datetime(date_str)
    if not is_aware(ret):
        ret = make_aware(ret)
    return ret

【讨论】:

我当然希望文档准确地指定“格式正确”的日期是什么!我希望这意味着 RFC 1123,但它似乎不喜欢我的浏览器发回的内容...... 这个答案不正确,因为没有返回时区感知日期时间,至少在 1.8.4 中没有。您可以自己尝试一下from django.utils import timezone, dateparse; timezone.is_aware(dateparse.parse_datetime('2015-09-04 19:22:17')),还可以在source 中看到返回的 datetime.datetime。 @TheCardCheat 你是对的,它没有 make_aware() (github 告诉我它从来没有这样做过,但我使用的代码在某处意识到了)。但是,如果输入字符串包含可识别的时区偏移量,则它确实返回一个感知日期时间。【参考方案3】:

我一直在用这个:

from django.utils.timezone import get_current_timezone
from datetime import datetime
tz = get_current_timezone()
dt = tz.localize(datetime.strptime(str_date, '%m/%d/%Y'))

【讨论】:

【参考方案4】:

你可以使用

import dateutil.parser
dateutil.parser.parse('2008-04-10 11:47:58-05')

它返回一个日期时间(可以分配给 DateTimeField)。

【讨论】:

这听起来不错,但在我的 python 2.6.5 中没有 datetime.parser 或 datetime.datetime.parser 模块(我得到一个 ImportError)。我错过了什么? 请注意,dateutil 是第三方模块(请参阅 PyPI 上的 python-dateutil),默认情况下您可能没有安装。 完美,谢谢!它找出了我的字符串日期格式,非常节省时间。 我如何解析 '1990 年 11 月 1 日' 到目前为止,先生,我是 python 新手?【参考方案5】:

如果您使用的是 Django 表单,则可以将 input_formats 指定为您的 DateField。见DateField documentation

如果您想解析任意日期信息,您可以使用parsedatetime 之类的东西,并实现一个Django 调用的方法,以便在它到达验证器之前进行解析。 (请参阅this SO answer,了解验证的工作原理以及何时插入它们)

【讨论】:

以上是关于将日期时间字符串解析为 Django DateTimeField的主要内容,如果未能解决你的问题,请参考以下文章

将自纪元以来的天数转换为日期

[翻译]C#.我该如何分析和转换日期时间的到RFC 822的日期,时间格式(How do I parse and convert DateTi

Django中的日期处理注意事项和自定义时间格式转换

从 SQL Server 2005 中的用户定义函数中“捕获”错误

Django 自动将日期时间字符串转换为本地时区

将带有日期的字符串解析为日期时间对象[重复]