Using
published_time = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Feedparser can analyze a wide range of date formats, you can find them here .
As you can see in feedparser/feedparser/datetimes/__init__.py , the built-in function from Feedparser _parse_date does the following:
Parses many date formats into 9-bit set in GMT
This means that in parsed_entry.published_parsed you have a time.struct_time object in GMT time zone.
When you convert it to a datetime object using
published_time = datetime.fromtimestamp(mktime(parsed_entry.published_parsed))
The problem is that mktime assumes that the transmitted tuple is in local time, and this is not GMT / UTC! Also, you are not correctly locating the datetime object at the end of the conversion.
You need to replace this conversion with the following, remembering that Feedparser returns GMT struct_time and localizes it using the time zone you like (UTC for simplicity).
- You use
calendar.timegm , which gives the number of seconds between the epoch and the date passed as a parameter, provided that the passed object is in UTC / GMT format (we know from Feedparser). - You use
utcfromtimestamp to get a naive datetime object (which, as we know, is datetime in UTC, but Python is not working at the moment) - With
pytz.utc.localize you correctly localize a datetime object in UTC.
Example:
import calendar from datetime import datetime import pytz localized_dt = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
As long as you agree, it doesn't matter if you fromtimestamp or utcfromtimestamp . If you are using fromtimestamp , you need to tell Python that the created datetime object has a local time zone. If you are in Europe / Berlin, this is also great:
pytz.timezone('Europe/Berlin').localize(datetime.fromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
If parsed_entry.published_parsed in the local time zone, use mktime instead of calendar.timegm .
Alternatively, you can parse the data string that you get from Feedparser parsed_entry['published']
from dateutil import parser localized_dt = parser.parse(parsed_entry['published'])
You can verify that the following returns True :
parser.parse(parsed_entry['published']) == pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Djangoβs TIME_ZONE setting doesn't really matter, as it is used only for visualization purposes or for automatically converting naive datetimes.
When USE_TZ is True, this is the default time zone that Django will use to display data in templates and to interpret dates entered on forms.
It is important to always use the correct localized dates, no matter what time zone is used. Until they are in a naive format, they will be properly handled by Django.