datetime.datetime.utcnow()
Tại sao điều này datetime
không có bất kỳ thông tin múi giờ nào cho rằng nó rõ ràng là một UTCdatetime
?
Tôi hy vọng rằng điều này sẽ chứa tzinfo
.
datetime.datetime.utcnow()
Tại sao điều này datetime
không có bất kỳ thông tin múi giờ nào cho rằng nó rõ ràng là một UTCdatetime
?
Tôi hy vọng rằng điều này sẽ chứa tzinfo
.
Câu trả lời:
Điều đó có nghĩa là nó là múi giờ ngây thơ, vì vậy bạn không thể sử dụng nó với datetime.astimezone
bạn có thể cho nó một múi giờ như thế này
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
bây giờ bạn có thể thay đổi múi giờ
print(u.astimezone(pytz.timezone("America/New_York")))
Để có được thời gian hiện tại trong một múi giờ nhất định, bạn có thể chuyển datetime.now()
trực tiếp tzinfo :
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Nó hoạt động cho bất kỳ múi giờ nào, kể cả những múi giờ quan sát thời gian tiết kiệm ánh sáng ban ngày (DST), nghĩa là nó hoạt động cho các múi giờ có thể có các độ lệch utc khác nhau tại các thời điểm khác nhau (bù utc không cố định). Không sử dụng tz.localize(datetime.now())
- nó có thể thất bại trong quá trình chuyển đổi cuối DST khi giờ địa phương không rõ ràng.
astimezone
. Vì vậy, datetime không chỉ không có múi giờ riêng, mà việc triển khai tzinfo duy nhất có sẵn rộng rãi là không tuân thủ tiêu chuẩn được cho là.
u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; sử dụng datetime.now(tz)
thay thế.
Lưu ý rằng đối với Python 3.2 trở đi, datetime
mô-đun chứa datetime.timezone
. Các tài liệu cho datetime.utcnow()
biết:
Một datetime UTC hiện tại có thể nhận được bằng cách gọi .
datetime.now
(
timezone.utc
)
Vì vậy, bạn có thể làm:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.now(timezone.utc)
hay datetime.utcnow(timezone.utc)
?
datetime.utcnow()
không có đối số. Vì vậy, nó sẽ phải được datetime.now(timezone.utc)
.
datetime.now()
sẽ trả về thời gian của máy nhưng datetime.utcnow()
sẽ trả về thời gian UTC thực tế.
datetime.utcnow()
không được đặt tzinfo
để chỉ ra rằng đó là UTC. Nhưng datetime.now(datetime.timezone.utc)
không trả lại thời gian UTC với tzinfo
thiết lập.
tz
đối tượng trong hàm tạo bây giờ thì nó sẽ trả về thời gian của múi giờ đó? Đồng ý! Cảm ơn đã chỉ ra.
Các thư viện Python chuẩn không bao gồm bất kỳ lớp tzinfo nào (nhưng xem pep 431 ). Tôi chỉ có thể đoán tại các lý do. Cá nhân tôi nghĩ rằng đó là một sai lầm khi không bao gồm một lớp tzinfo cho UTC, bởi vì đó là một điều không đủ tranh cãi để có một triển khai tiêu chuẩn.
Chỉnh sửa: Mặc dù không có triển khai trong thư viện, nhưng có một ví dụ được đưa ra làm tzinfo
tài liệu .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Để sử dụng nó, để lấy thời gian hiện tại làm đối tượng datetime nhận thức:
from datetime import datetime
now = datetime.now(utc)
Có datetime.timezone.utc
trong Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
datetime
các đối tượng được tạo bởi utcnow()
) ...
timezone.utc
cuối cùng đã được thêm vào Python 3.2. Để tương thích ngược, utcnow()
vẫn trả về một đối tượng thời gian không có múi giờ, nhưng bạn có thể nhận được những gì bạn muốn bằng cách gọi now(timezone.utc)
.
struct
mô-đun sẽ thực hiện chuyển đổi tự động từ Unicode sang bytestring và quyết định cuối cùng là phá vỡ tính tương thích với các phiên bản Python 3 trước đó để ngăn chặn quyết định tồi tệ.
tzinfo
tài liệu của Python bao gồm các ví dụ về mã để triển khai nó, nhưng chúng không bao gồm chức năng đó trong chính datetime! docs.python.org/2/l Library / datetime.html
pytz
là một tài nguyên tuyệt vời. Vào thời điểm tôi đã chỉnh sửa câu trả lời của mình để đưa vào mã ví dụ, một người khác đã gợi ý và tôi không muốn đánh cắp sấm sét của họ.
Các pytz
mô-đun là một lựa chọn, và có mộtpython-dateutil
, mà mặc dù cũng là gói của bên thứ ba, có thể đã có sẵn tùy thuộc vào phụ thuộc khác của bạn và hệ điều hành.
Tôi chỉ muốn đưa phương pháp này vào tham khảo - nếu bạn đã cài đặt python-dateutil
cho các mục đích khác, bạn có thể sử dụng phương pháp này tzinfo
thay vì sao chép vớipytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())
# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())
# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Tôi có xu hướng đồng ý rằng các cuộc gọi utcnow
nên bao gồm thông tin múi giờ UTC. Tôi nghi ngờ rằng điều này không được bao gồm bởi vì thư viện datetime gốc mặc định cho các datetimes ngây thơ cho khả năng tương thích chéo.
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
luôn luôn hoạt động; datetime.now(dateutil.tz.tzlocal())
có thể thất bại trong quá trình chuyển đổi DST . PEP 495 - Định hướng thời gian địa phương có thể cải thiện dateutil
tình hình trong tương lai.
utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(lưu ý: dateutil
với một utc không cố định bù đắp (như dateutil.tz.tzlocal()
) có thể thất bại ở đây , sử dụng một pytz
giải pháp dựa trên thay vì ).
dateutil
cho dateutil.parser
, tôi thích giải pháp này tốt nhất. Nó đơn giản như : utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Viola !!
Julien Danjou đã viết một bài báo hay giải thích lý do tại sao bạn không bao giờ nên đối phó với các múi giờ . Một đoạn trích:
Thật vậy, API datetime của Python luôn trả về các đối tượng datetime không biết, điều này rất đáng tiếc. Thật vậy, ngay khi bạn có được một trong những vật thể này, không có cách nào để biết múi giờ là gì, do đó những vật thể này khá "vô dụng".
Than ôi, mặc dù bạn có thể sử dụng utcnow()
, bạn vẫn sẽ không thấy thông tin múi giờ, như bạn đã khám phá.
Khuyến nghị:
Luôn luôn sử dụng
datetime
các đối tượng nhận thức , tức là với thông tin múi giờ. Điều đó đảm bảo rằng bạn có thể so sánh chúng trực tiếp (datetime
các đối tượng nhận biết và không biết không thể so sánh được) và sẽ trả lại chúng một cách chính xác cho người dùng. Tận dụng pytz để có các đối tượng múi giờ.Sử dụng ISO 8601 làm định dạng chuỗi đầu vào và đầu ra. Sử dụng
datetime.datetime.isoformat()
để trả về dấu thời gian dưới dạng chuỗi được định dạng bằng định dạng đó, bao gồm thông tin múi giờ.Nếu bạn cần phân tích các chuỗi có chứa dấu thời gian được định dạng ISO 8601, bạn có thể dựa vào
iso8601
đó, trả về dấu thời gian với thông tin múi giờ chính xác. Điều này làm cho dấu thời gian trực tiếp so sánh.
Để thêm timezone
thông tin trong Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (mặc định, ngày 19 tháng 1 năm 2017, 14:48:08)
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
Ngày UTC không cần bất kỳ thông tin múi giờ nào vì chúng là UTC, theo định nghĩa có nghĩa là chúng không có bù.
pytz.utc
). Lưu ý rằng có một sự khác biệt lớn giữa một giá trị mà bù đắp từ UTC là không rõ và một trong những nơi được biết đến là 0. Sau đó là những gì utcnow()
nên trở về, IMO. Điều đó sẽ phù hợp với "Một đối tượng nhận thức được sử dụng để thể hiện một thời điểm cụ thể không mở để giải thích" theo tài liệu.