Tôi đang phân tích cú pháp nguồn cấp cảnh báo của Dịch vụ thời tiết quốc gia thành ứng dụng web. Tôi muốn thanh lọc các cảnh báo khi họ đạt đến thời gian hết hạn. Tôi cũng muốn hiển thị thời gian hết hạn theo định dạng giờ địa phương cho khu vực địa lý mà chúng liên quan đến.Chuyển đổi chuỗi ngày nhận biết múi giờ thành UTC và quay lại bằng Python
Các cảnh báo bao gồm toàn bộ Hoa Kỳ, vì vậy tôi nghĩ cách tốt nhất là lưu trữ và so sánh thời gian trong dấu thời gian UTC. Thời gian hết hạn đến trong nguồn cấp dữ liệu dưới dạng chuỗi như sau: 2011-09-09T22:12:00-04:00
.
Tôi đang sử dụng Labix dateutils gói để phân tích chuỗi một cách múi giờ-aware:
>>> from dateutil.parser import parse
>>> d = parse("2011-09-18T15:52:00-04:00")
>>> d
datetime.datetime(2011, 9, 18, 15, 52, tzinfo=tzoffset(None, -14400))
Tôi cũng có thể nắm bắt được tính theo giờ UTC bù đắp trong giờ:
>>> offset_hours = (d.utcoffset().days * 86400 + d.utcoffset().seconds)/3600
>>> offset_hours
-4
Sử dụng phương thức datetime.utctimetuple()
và time.mktime()
, tôi có thể chuyển đổi ngày được phân tích thành dấu thời gian UTC:
>>> import time
>>> expiration_utc_ts = time.mktime(d.utctimetuple())
>>> expiration_utc_ts
1316393520.0
Tại thời điểm này, tôi cảm thấy khá tốt rằng tôi có thể chuyển đổi các chuỗi thô thành một dấu thời gian biểu thị thời gian hết hạn trong UTC. Tôi có thể so sánh thời điểm hiện tại như một UTC dấu thời gian để kết thúc thời hạn và xác định xem nó cần phải được thanh lọc:
>>> now_utc_ts = time.mktime(time.gmtime())
>>> now_utc_ts
1316398744.0
>>> now_utc_ts >= expiration_tc_ts
True
Khó khăn tôi đang gặp đang cố gắng để chuyển đổi lưu trữ UTC timestamp của tôi trở lại với bản gốc định dạng bản địa hóa. Tôi có những giờ bù đắp được lưu trữ từ việc chuyển đổi ban đầu và một chuỗi Tôi phân tích cú pháp để lưu trữ các nhãn múi giờ:
>>> print offset_hours
-4
>>> print timezone
EDT
Tôi muốn chuyển đổi UTC timestamp trở lại trong một thời gian định dạng tại địa phương, nhưng chuyển đổi nó trở lại một datetime
dường như không có tác dụng:
>>> import datetime
>>> datetime.datetime.fromtimestamp(expiration_utc_ts) + datetime.timedelta(hours=offset_hours)
datetime.datetime(2011, 9, 18, 16, 52) # The hour is 16 but it should be 15
dường như đó là tắt bởi một tiếng đồng hồ. Tôi không chắc chắn nơi lỗi được giới thiệu? Tôi đặt cùng một thử nghiệm khác và có kết quả tương tự:
>>> # Running this at 21:29pm EDT
>>> utc_now = datetime.datetime.utcnow()
>>> utc_now_ts = time.mktime(right_now.utctimetuple())
>>> datetime.datetime.fromtimestamp(utc_now_ts)
datetime.datetime(2011, 9, 18, 22, 29, 47) # Off by 1 hour
Ai đó có thể giúp tôi tìm thấy lỗi của mình không? Tôi không chắc đó có phải là vấn đề tiết kiệm ánh sáng ban ngày không? Tôi bắt gặp một số thứ khiến tôi tin rằng nó có thể đang cố gắng bản địa hoá ngày tháng và thời gian của tôi nhưng vào thời điểm này tôi khá là bối rối. Tôi đã hy vọng làm tất cả những tính toán/so sánh này theo cách thức bất khả tri theo thời gian.
thể trùng lặp của [Issue với python/pytz Chuyển đổi từ múi giờ địa phương để UTC sau đó trở lại] (http://stackoverflow.com/questions/7465181/issue-with-python-pytz-converting- từ-local-timezone-to-utc-then-back) – agf
Tôi đã nghĩ bạn có thể làm tất cả điều này với các đối tượng datetime, và không chuyển đổi thành tuple hoặc timestamps. Nếu bạn thực hiện đối tượng datetime "now" nhận biết múi giờ thì chỉ cần thực hiện "if x
Tôi hy vọng như vậy, nhưng PostgreSQL vẫn muốn bản địa hoá giá trị datetime. (Tôi chắc chắn có một cách xung quanh đó, nhưng tôi thấy nó sẽ được dễ dàng hơn ngay bây giờ để chỉ lưu trữ thời gian UTC) – Scott