Sử dụng
published_time = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Feedparser thể phân tích một phạm vi rộng lớn các định dạng ngày, bạn có thể tìm thấy chúng here.
Như bạn có thể thấy trong feedparser/feedparser/datetimes/__init__.py
, được xây dựng trong chức năng từ Feedparser _parse_date
nào sau đây:
Parses a variety of date formats into a 9-tuple in GMT
Điều này có nghĩa rằng trong parsed_entry.published_parsed
bạn có một đối tượng time.struct_time
trong giờ múi giờ.
Khi bạn chuyển nó sang một đối tượng sử dụng datetime
published_time = datetime.fromtimestamp(mktime(parsed_entry.published_parsed))
vấn đề là mktime
giả định rằng các tuple qua là trong giờ địa phương, mà không phải là, nó GMT/UTC! Ngoài ra, bạn không bản địa hóa đối tượng datetime
ở cuối chuyển đổi.
Bạn cần phải thay thế chuyển đổi đó bằng những điều sau, nhớ rằng Feedparser trả về GMT struct_time
và bản địa hóa múi giờ đó theo múi giờ bạn thích (UTC vì mục đích đơn giản).
- Bạn sử dụng
calendar.timegm
, mang đến cho số giây giữa thời đại và ngày trôi qua như một tham số, giả định rằng các đối tượng thông qua là trong UTC/GMT (chúng ta đã biết từ Feedparser nó là)
- Bạn sử dụng
utcfromtimestamp
để có được một đối tượng ngây thơ datetime
(mà chúng ta biết là đại diện cho một datetime trong UTC, nhưng Python không có tại thời điểm này)
- Với
pytz.utc.localize
bạn đúng địa phương hóa trong UTC các đối tượng datetime
.
Ví dụ:
import calendar
from datetime import datetime
import pytz
localized_dt = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Chừng nào bạn là phù hợp, nó không quan trọng nếu bạn sử dụng fromtimestamp
hoặc utcfromtimestamp
. Nếu bạn sử dụng fromtimestamp
, bạn cần cho Python biết rằng đối tượng datetime
bạn đã tạo có múi giờ địa phương. Giả sử bạn đang ở Châu Âu/Berlin, đây là cũng tốt:
pytz.timezone('Europe/Berlin').localize(datetime.fromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Were parsed_entry.published_parsed
còn ở múi giờ địa phương, mktime
phải được sử dụng ở vị trí của calendar.timegm
.
Là một thay thế, bạn có thể phân tích cho mình chuỗi dữ liệu bạn nhận được từ Feedparser parsed_entry['published']
from dateutil import parser
localized_dt = parser.parse(parsed_entry['published'])
Bạn có thể kiểm tra xem lợi nhuận sau True
:
parser.parse(parsed_entry['published']) == pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Thiết lập Django TIME_ZONE
không thực sự vấn đề, bởi vì nó chỉ được sử dụng cho các mục đích hình dung hoặc để tự động chuyển đổi các datetimes ngây thơ.
When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms.
Điều quan trọng là luôn sử dụng đúng giờ địa phương, bất kể múi giờ nào được sử dụng. Miễn là chúng không có định dạng ngây thơ, chúng sẽ được Django xử lý đúng cách.
Bạn có quan tâm đến việc chuyển đổi múi giờ hoặc bạn sẽ mở để chỉ cần thêm một giờ với một ngày giờ.timedelta hoạt động? – JwM
Cuối cùng, tôi muốn có thời gian chính xác trong UTC. Mất một giờ đi ngay bây giờ (hai giờ trong ngày tiết kiệm thời gian) có thể là một cách để đi. Tôi chưa nhìn vào nó. Tôi đã tự hỏi nếu có một cách khác. Tôi đã thử ví dụ timezone.activate() và timezone.deactivate() dường như thay đổi current_timezone theo đúng cách, nhưng điều đó không khắc phục được sự cố. – apiljic
Bạn có thể thực hiện nhận biết về ngày giờ hoặc thay đổi múi giờ nếu đã biết nhưng sai. –