54

I have a Django app with a model that contains a field of type DateTimeField.
I am pulling data from the web in the format of 2008-04-10 11:47:58-05.
I believe that the last 3 characters in this example are the timezone.
How can I preserve that data in the DateTimeField, and is there an easy conversion between the two? Setting the DateTimeField to simply contain a string of the above format throws a ValidationError.

Thank you!

6 Answers 6

110

You can also use Django's implementation. I would in fact prefer it and only use something else, if Django's parser cannot handle the format.

For example:

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

To have it converted to the right timezone when none is known, use make_aware from django.utils.timezone.

So ultimately, your parser utility would be:

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
Sign up to request clarification or add additional context in comments.

3 Comments

I sure wish the docs specified exactly what a 'well formatted' date is, though! I would expect that to mean RFC 1123, but it doesn't seem to like what my browser is sending back...
This answer is not correct in that a timezone aware datetime is not returned, at least not in 1.8.4. You can try this for yourself from django.utils import timezone, dateparse; timezone.is_aware(dateparse.parse_datetime('2015-09-04 19:22:17')) and also see in the source that a datetime.datetime is returned.
@TheCardCheat You're right that it doesn't make_aware() (github tells me it never did and yet code I used became aware somewhere). But, if an input string contains a timezone offset that is recognized then it does return an aware datetime.
61

You can use

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

Which returns a datetime (that can be assigned to the DateTimeField).

4 Comments

this sounds great, but in my python 2.6.5 there is no datetime.parser or datetime.datetime.parser modules (I get an ImportError). What am I missing?
Note that dateutil is a third-party module (see python-dateutil on PyPI), which you may not have installed by default.
perfect, thanks! It figured out my string date format, great time saver.
How can i parse the 'November 1, 1990' to date sir i am new to python?
18

I've been using this:

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

Comments

8

String format of Django DateTimeField is "%Y-%m-%dT%H:%M:%S.%fZ". Hence, conversion between eachother can be done using strptime() or strptime() using this format.

eg. for string formatted value (2016-10-03T19:00:00.999Z), it can be converted to Django datetime object as :

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

Comments

3

If you're using Django Forms, you can specify input_formats to your DateField. See the DateField documentation

If you are wanting to parse arbitrary date information, you could use something like parsedatetime and implement a method that Django calls to do the parsing before it hits the validators. (See this SO answer for a good summary of how validations work and when to insert them)

Comments

3

To make standard format:

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

You will see something like this:

2022-02-09 12:58:52

Be successful

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.