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 ซึ่งจะสอดคล้องกับ "วัตถุที่รับรู้ใช้เพื่อแสดงช่วงเวลาที่เฉพาะเจาะจงซึ่งไม่เปิดให้ตีความ" ตามเอกสารประกอบ