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

51
我有一个Django应用程序,其中包含一个类型为DateTimeField的字段。
我以2008-04-10 11:47:58-05格式从Web中获取数据。
我认为这个例子中的最后3个字符是时区。
我如何保留DateTimeField中的那些数据,并且这两种格式之间是否有简单的转换?将DateTimeField设置为仅包含上述格式的字符串会引发ValidationError错误。

谢谢!

6个回答

107

你也可以使用Django的实现。事实上,我更喜欢它,并且只有在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

2
我真希望文档能明确指定什么是“格式良好”的日期!虽然我期望它意味着RFC 1123,但它似乎不喜欢我的浏览器发送的内容... - Michael Scheper
1
这个答案是不正确的,因为至少在1.8.4版本中并没有返回一个时区感知(datetime)的日期时间。你可以自己尝试一下,使用以下代码: from django.utils import timezone, dateparse; timezone.is_aware(dateparse.parse_datetime('2015-09-04 19:22:17')) 同时也可以在中查看返回的是datetime.datetime类型。 - Jmills
2
@TheCardCheat 你说得对,它不会 make_aware()(Github 告诉我它从未这样做过,但是我使用的代码在某个地方变得有意识了)。但是,如果输入字符串包含被识别的时区偏移量,则它会返回一个有意识的日期时间。 - user1600649

59
你可以使用
import dateutil.parser
dateutil.parser.parse('2008-04-10 11:47:58-05')

此函数返回一个日期时间(可分配给DateTimeField)。


这听起来很不错,但在我的 Python 2.6.5 中,没有 datetime.parser 或 datetime.datetime.parser 模块(我收到 ImportError)。我漏掉了什么? - user1094786
26
请注意,dateutil 是一个第三方模块(见 PyPI 上的 python-dateutil),默认情况下您可能没有安装它。 - Pi Delport
完美,谢谢!它找出了我的字符串日期格式,真是个很好的时间节省器。 - Bogatyr
我如何将“November 1, 1990”解析为日期?先生,我是Python的新手。 - Shift 'n Tab

17

我一直在使用这个:

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

6

Django DateTimeField字段的字符串格式为"%Y-%m-%dT%H:%M:%S.%fZ"。因此,可以使用strptime()或使用该格式的strftime()之间进行转换。

例如,对于格式化的字符串值(2016-10-03T19:00:00.999Z),可以将其转换为Django datetime对象:

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

3
如果您正在使用Django表单,可以为DateField指定input_formats。请参见DateField文档
如果您想解析任意日期信息,可以使用类似parsedatetime的东西,并实现Django调用的方法来进行解析,以在其命中验证器之前进行解析。(有关验证工作原理及何时插入验证的良好摘要,请参见this SO answer

2

制作标准格式:

from django.utils.dateparse import parse_datetime
formatted_datetime = parse_datetime(YOUR_STRING_DATETIME).strftime('%Y-%m-%d %H:%M:%S')
print(f"formatted_datetime: {formatted_datetime}")

你将会看到类似这样的内容:
2022-02-09 12:58:52

取得成功


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接