Múi giờ là một vấn đề khó khăn. DST thậm chí còn là một vấn đề khó khăn hơn. Tôi thấy mình vướng vào các vấn đề và rắc rối khi bắt đầu sử dụng datetime trong Python đúng cách. Vì vậy, tôi quyết định viết một blog để chia sẻ kinh nghiệm của tôi
“Ngây thơ” và “Nhận thức”
Điều đầu tiên cần biết là trong Python có. offset ngây thơ và offset-biết. Bù đắp ngây thơ có nghĩa là ngày giờ không có thông tin múi giờ. Nó có thể rất dễ bị lỗi nếu bạn chưa quen với Python. Nếu bạn trộn một datetime ngây thơ và datetime nhận biết, bạn sẽ gặp lỗi. Và Python không hỗ trợ múi giờ tích hợp, bạn cần sử dụng pytz, một mô-đun để biết thông tin múi giờ
import pytz
from datetime import datetimetznaive_datetime = datetime[2018, 1, 1, 12, 0]
tzaware_datetime = datetime[2018, 1, 1, 12, 0, tzinfo=pytz.utc]# this will raise an error
tznaive_datetime == tzaware_datetime
Để tránh loại sự cố này, bạn sẽ phải đảm bảo rằng các đối tượng ngày giờ của bạn luôn là đối tượng không có giá trị bù hoặc luôn nhận biết được giá trị bù. Nhưng chúng ta không thể tránh xử lý múi giờ, vì vậy cách tốt nhất của tôi là luôn làm việc với ngày giờ nhận biết bù trừ
Python mặc định là datetime ngây thơ.
import datetime3 trả về ngày giờ ngây thơ theo múi giờ địa phương của bạn và
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
import datetime4 cũng trả về ngày giờ ngây thơ, thậm chí hàm đã chỉ ra múi giờ UTC. Bạn sẽ cần mô-đun
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
import datetime5 và cả mô-đun
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
import datetime0 để hoàn thành tốt mọi việc. Dưới đây là cách tôi có được thời gian với múi giờ phù hợp
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
import datetime
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
Phân tích ngày giờ với múi giờ
Cập nhật. Đây chỉ là một vấn đề trong Python 2
Một điều ngạc nhiên khác là trình phân tích cú pháp python
import datetime1 không hoạt động với múi giờ. Đoạn mã dưới đây sẽ thất bại
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
>>> from datetime import datetime
>>> datetime.strptime['2017-11-15T12:00:00-0700', '%Y-%m-%dT%H:%M:%S%z']ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%m:%S%z'
Để phân tích cú pháp ngày giờ với múi giờ, bạn sẽ cần một mô-đun khác
import datetime2. Mô-đun này cung cấp trình phân tích cú pháp sẽ hoạt động với múi giờ. Bây giờ bạn có thể phân tích ngày giờ với múi giờ
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
>>> from dateutil import parser
>>> parser.parse['2017-11-15T12:00:00-07']datetime.datetime[2017, 11, 15, 12, 0, tzinfo=tzoffset[None, -25200]]
Đồng hồ bấm giờ và DST
Điều cuối cùng bạn cần cẩn thận khi thao tác với thời gian nhận biết offset.
import datetime5 sẽ giúp bạn biết liệu một ngày có chịu ảnh hưởng của DST hay không bằng cách kiểm tra phương pháp
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
import datetime4________số 8
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
Ghi chú. DST cho năm 2017 đã kết thúc vào ngày 5 tháng 11. Vì vậy, bất kỳ ngày nào sau ngày 5 tháng 11 sẽ có
import datetime5
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
Nhưng thông tin
import datetime4 không được cập nhật khi bạn thao tác ngày giờ
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
import datetime1
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
Những gì bạn thực sự có thể làm là chuyển đổi trở lại thời gian bù đắp ngây thơ, sau đó áp dụng lệnh delta…
import datetime2
import pytz
import tzlocaldef utcnow[]:
return pytz.utc.localize[datetime.utcnow[]]def now[]:
return tzlocal.get_localzone[].localize[datetime.now[]]
Tóm lược
Làm việc với Datetime trong Python dễ bị lỗi. Là do Python không hỗ trợ tốt datetime và timezone. Bạn sẽ phải sử dụng rất nhiều mô-đun bổ sung. Tuy nhiên, thực sự có một viên đạn bạc, bạn chỉ cần sử dụng mũi tên. Mô-đun này cung cấp một sự thay thế cho mô-đun datetime của python và nó luôn nhận biết được độ lệch và nó cũng giải quyết tất cả các vấn đề mà tôi đã đề cập ở trên. Điều duy nhất tôi có thể lo lắng là việc tích hợp với các ứng dụng bên ngoài khác như Spark