datetime.datetime.utcnow()
ทำไมนี้datetime
ไม่ได้ข้อมูลเขตเวลาใดก็ตามที่มันเป็นอย่างชัดเจน UTC เราจะต้องdatetime
?
tzinfo
ผมจะคาดหวังว่าเรื่องนี้จะประกอบด้วย
datetime.datetime.utcnow()
ทำไมนี้datetime
ไม่ได้ข้อมูลเขตเวลาใดก็ตามที่มันเป็นอย่างชัดเจน UTC เราจะต้องdatetime
?
tzinfo
ผมจะคาดหวังว่าเรื่องนี้จะประกอบด้วย
คำตอบ:
นั่นหมายความว่ามันเป็นเขตเวลาไร้เดียงสาดังนั้นคุณจึงไม่สามารถใช้กับ datetime.astimezone
คุณสามารถให้เขตเวลาเป็นแบบนี้ได้
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
ตอนนี้คุณสามารถเปลี่ยนเขตเวลา
print(u.astimezone(pytz.timezone("America/New_York")))
หากต้องการรับเวลาปัจจุบันในเขตเวลาที่กำหนดคุณสามารถส่ง tzinfo ไปที่datetime.now()
โดยตรง:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
ใช้งานได้กับเขตเวลาใดก็ได้รวมถึงเขตเวลาที่สังเกตว่าการปรับเวลาตามฤดูกาล (DST) คือการทำงานสำหรับเขตเวลาที่อาจมีการชดเชย UTC ที่แตกต่างกันในเวลาที่ต่างกัน อย่าใช้tz.localize(datetime.now())
- มันอาจล้มเหลวในระหว่างการเปลี่ยนแปลงเมื่อสิ้นสุดเวลา DST เมื่อเวลาท้องถิ่นไม่ชัดเจน
astimezone
อินเตอร์เฟซในทางที่คาดหวังเพื่อให้คุณสามารถรับข้อผิดพลาดถ้าคุณพยายามที่จะใช้บางส่วนของเขตเมือง ดังนั้นวันที่และเวลาไม่เพียง แต่ไม่มีเขตเวลาดั้งเดิมเท่านั้น แต่การใช้งาน tzinfo ที่มีอยู่อย่างกว้างขวางเท่านั้นไม่สอดคล้องกับมาตรฐานที่ควรจะเป็น
u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; ใช้datetime.now(tz)
แทน
โปรดทราบว่าสำหรับงูหลาม 3.2 เป็นต้นไปโมดูลมีdatetime
datetime.timezone
เอกสารสำหรับdatetime.utcnow()
พูดว่า:
ตระหนัก datetime UTC ปัจจุบันสามารถหาได้โดยการโทร
datetime.now
(
timezone.utc
)
ดังนั้นคุณสามารถทำได้:
>>> 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)
หรือdatetime.utcnow(timezone.utc)
?
datetime.utcnow()
ไม่มีข้อโต้แย้ง datetime.now(timezone.utc)
ดังนั้นจึงจะต้องมีการ
datetime.now()
จะคืนค่าเวลาของเครื่อง แต่datetime.utcnow()
จะส่งคืนเวลา UTC ที่แท้จริง
datetime.utcnow()
ไม่ได้ตั้งค่าtzinfo
เพื่อระบุว่าเป็น UTC แต่datetime.now(datetime.timezone.utc)
ส่งคืนเวลา UTC ด้วยการ tzinfo
ตั้งค่า
tz
วัตถุในตัวสร้างตอนนี้มันจะคืนค่าเวลาของเขตเวลานั้นหรือไม่ ตกลง! ขอบคุณสำหรับการชี้ให้เห็น
ไลบรารี Python มาตรฐานไม่มีคลาส tzinfo ใด ๆ (แต่ดู pep 431 ) ฉันสามารถเดาได้จากเหตุผลเท่านั้น โดยส่วนตัวฉันคิดว่ามันเป็นความผิดพลาดที่จะไม่รวมคลาส tzinfo สำหรับ UTC เพราะนั่นเป็นเรื่องที่ไม่น่าโต้เถียงมากพอที่จะใช้งานมาตรฐาน
แก้ไข:แม้ว่าจะไม่มีการดำเนินการในห้องสมุดมีหนึ่งให้เป็นตัวอย่างในเอกสารtzinfo
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()
วิธีใช้เพื่อรับเวลาปัจจุบันเป็นวัตถุ datetime ที่รับรู้:
from datetime import datetime
now = datetime.now(utc)
มีdatetime.timezone.utc
ใน Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
datetime
วัตถุที่สร้างขึ้นโดยutcnow()
) ...
timezone.utc
ในที่สุดวัตถุเขตเวลาได้ถูกเพิ่มไปยัง Python 3.2 ความเข้ากันได้ย้อนหลังutcnow()
ยังคงส่งกลับวัตถุเวลาเขตเวลาน้อย now(timezone.utc)
แต่คุณจะได้รับสิ่งที่คุณต้องการโดยการเรียก
struct
โมดูลจะทำการแปลงอัตโนมัติจาก Unicode เป็นการทดสอบและการตัดสินใจขั้นสุดท้ายคือการหยุดความเข้ากันได้กับ Python 3 รุ่นก่อนหน้าเพื่อป้องกันไม่ให้การตัดสินใจที่ไม่ดีก้าวไปข้างหน้า
tzinfo
เอกสารของ Python มีตัวอย่างของโค้ดที่จะนำไปใช้ แต่มันไม่ได้รวมฟังก์ชั่นนั้นไว้ใน datetime เอง! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc
pytz
เป็นแหล่งข้อมูลที่ยอดเยี่ยม เมื่อถึงเวลาที่ฉันได้แก้ไขคำตอบของฉันให้ใส่รหัสตัวอย่างบางคนได้แนะนำไปแล้วและฉันไม่ต้องการขโมยฟ้าร้องของพวกเขา
pytz
โมดูลเป็นทางเลือกหนึ่งและมีอีกpython-dateutil
ซึ่งแม้จะยังเป็นแพคเกจของบุคคลที่สามแล้วอาจจะขึ้นอยู่กับการอ้างอิงอื่น ๆ ของคุณและระบบปฏิบัติการ
ฉันแค่ต้องการรวมวิธีการนี้ไว้สำหรับอ้างอิงถ้าคุณติดตั้งไว้แล้วpython-dateutil
เพื่อจุดประสงค์อื่นคุณสามารถใช้วิธีนี้tzinfo
แทนการทำซ้ำpytz
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())
ฉันมักจะเห็นด้วยว่าการเรียกร้องให้utcnow
ควรรวมข้อมูลเขตเวลา UTC ไว้ด้วย ฉันสงสัยว่าสิ่งนี้ไม่รวมอยู่เพราะไลบราลี่ datetime ดั้งเดิมจะใช้ค่าเริ่มต้นที่ไร้เดียงสาสำหรับการทำงานร่วมกันข้าม
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
ที่ใช้งานได้เสมอ อาจล้มเหลวในระหว่างการเปลี่ยนเวลาdatetime.now(dateutil.tz.tzlocal())
PEP 495 - ความไม่ลงรอยกันเวลาท้องถิ่นอาจช่วยให้dateutil
สถานการณ์ดีขึ้นในอนาคต
utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(หมายเหตุ: dateutil
มีไม่คง UTC ชดเชย (เช่นdateutil.tz.tzlocal()
) อาจล้มเหลวที่นี่ใช้แก้ปัญหาชั่นแทน ) pytz
dateutil
มาdateutil.parser
แล้วฉันชอบวิธีนี้มากที่สุด utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
มันเป็นง่ายๆเป็น: Viola !!
Julien Danjou เขียนบทความที่ดีอธิบายว่าทำไมคุณไม่ควรจัดการกับเขตเวลา ข้อความที่ตัดตอนมา:
แท้จริงแล้ว Python datetime API จะส่งคืนออบเจ็กต์ที่ไม่รู้จักซึ่งมักจะโชคไม่ดี อันที่จริงแล้วทันทีที่คุณได้รับหนึ่งในวัตถุนี้ไม่มีวิธีที่จะรู้ว่าเขตเวลาคืออะไรดังนั้นวัตถุเหล่านี้จะค่อนข้าง "ไร้ประโยชน์" ด้วยตนเอง
อนิจจาแม้ว่าคุณอาจใช้utcnow()
คุณยังคงไม่เห็นข้อมูลเขตเวลาตามที่คุณค้นพบ
คำแนะนำ:
ใช้
datetime
วัตถุที่รับรู้เสมอเช่นข้อมูลเขตเวลา ซึ่งทำให้แน่ใจว่าคุณสามารถเปรียบเทียบพวกเขาโดยตรง (datetime
วัตถุที่รับรู้และไม่รู้จักนั้นไม่สามารถเทียบเคียงได้) และจะส่งกลับไปยังผู้ใช้อย่างถูกต้อง ใช้ประโยชน์จากpytzให้มีวัตถุเขตเวลาใช้ISO 8601เป็นรูปแบบสตริงอินพุตและเอาต์พุต ใช้
datetime.datetime.isoformat()
เพื่อส่งคืนการประทับเวลาเป็นสตริงที่จัดรูปแบบโดยใช้รูปแบบนั้นซึ่งรวมถึงข้อมูลเขตเวลาหากคุณต้องการแยกสตริงที่มีการประทับเวลาที่จัดรูปแบบ ISO 8601 คุณสามารถพึ่งพา
iso8601
ซึ่งจะส่งคืนการประทับเวลาด้วยข้อมูลเขตเวลาที่ถูกต้อง สิ่งนี้ทำให้การเปรียบเทียบเวลาประทับโดยตรง
เพื่อเพิ่มtimezone
ข้อมูลใน 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 (ค่าเริ่มต้น, 19 ม.ค. 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]
วันที่ UTC ไม่ต้องการข้อมูลเขตเวลาใด ๆ เนื่องจากเป็น UTC ซึ่งตามคำจำกัดความหมายความว่าไม่มีการชดเชย
pytz.utc
) โปรดทราบว่ามีความแตกต่างอย่างมากระหว่างค่าที่ไม่ทราบค่าออฟเซ็ตจาก UTC และค่าที่ทราบว่าเป็น 0 ค่าหลังคือสิ่งที่utcnow()
ควรส่งคืน IMO ซึ่งจะสอดคล้องกับ "วัตถุที่รับรู้ใช้เพื่อแสดงช่วงเวลาที่เฉพาะเจาะจงซึ่งไม่เปิดให้ตีความ" ตามเอกสารประกอบ