จะได้รับเวลา UTC ใน Python ได้อย่างไร?


115

ฉันค้นหาวิธีแก้ปัญหาใน StackExchange เป็นจำนวนมาก แต่ไม่มีอะไรทำในสิ่งที่ฉันต้องการ ใน JavaScript ฉันใช้สิ่งต่อไปนี้เพื่อคำนวณเวลา UTC ตั้งแต่ 1 มกราคม 1970:

function UtcNow() {
    var now = new Date();
    var utc = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds());
    return utc;
}

รหัส Python ที่เทียบเท่าจะเป็นอย่างไร



เดี๋ยวก่อนคุณใช้ Python หรือ JavaScript?
CheetSheatOverlode

คำตอบ:


183

ลองใช้รหัสนี้ที่ใช้datetime.utcnow () :

from datetime import datetime
datetime.utcnow()

เพื่อวัตถุประสงค์ของคุณเมื่อคุณต้องการคำนวณระยะเวลาที่ใช้ระหว่างวันที่สองวันสิ่งที่คุณต้องการคือการลบวันที่สิ้นสุดและวันที่เริ่มต้น ผลลัพธ์ของการย่อยดังกล่าวเป็นวัตถุที่กำหนดเวลา

จากเอกสาร python:

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

และนั่นหมายความว่าโดยค่าเริ่มต้นคุณจะได้รับฟิลด์ใด ๆ ที่กล่าวถึงในคำจำกัดความของมัน - วันวินาทีไมโครวินาทีมิลลิวินาทีนาทีชั่วโมงสัปดาห์ นอกจากนี้อินสแตนซ์ timedelta ยังมีวิธี total_seconds () ที่:

ส่งคืนจำนวนวินาทีทั้งหมดที่มีอยู่ในช่วงเวลานั้น เทียบเท่ากับ (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 * 6) / 10 * 6 คำนวณโดยเปิดใช้งานการหารจริง


2
อาจแปลกใจที่น่ารังเกียจเกี่ยวกับ datetime.utcnow () คือไม่ส่งคืนวัตถุที่ทราบเขตเวลาแม้จะมีชื่อก็ตาม นี่เป็นปัญหาใหญ่ในความคิดของฉันซึ่งเป็นสาเหตุที่ฉันชอบคำตอบด้านล่าง โปรดดู "วัตถุวันที่และเวลาที่ไม่มีเขตเวลาควรถือเป็น" จุดบกพร่อง "ในแอปพลิเคชัน" julien.danjou.info/python-and-timezones
Tim Richardson

1
แนวคิดของวัตถุวันเวลาที่ไร้เดียงสาที่เรียกว่า (กล่าวคือไม่มีการตั้งค่าข้อมูลเขตเวลา) มีจุดประสงค์: ฉันต้องการให้นาฬิกาปลุกของฉันส่งเสียงเวลา 06:00:00 น. ทุกวันไม่ว่าฉันจะอยู่ที่ไหนในโลกก็ตาม นอกจากนี้ยังช่วยให้ "นาฬิกาเสมือน" ในเกมคอมพิวเตอร์พูดได้ด้วย: ตอนนี้เป็นเวลา 17.00 น. ในโลกแฟนตาซีของฉัน การบังคับเขตเวลาบนวัตถุวันที่และเวลาจะเป็นเรื่องที่น่าอึดอัดใจโดยเฉพาะอย่างยิ่งกับคณิตศาสตร์ตามเวลา
DustByte

42

ในรูปแบบที่ใกล้เคียงที่สุดกับต้นฉบับของคุณ:

import datetime

def UtcNow():
    now = datetime.datetime.utcnow()
    return now

หากคุณต้องการทราบจำนวนวินาทีตั้งแต่ 1970-01-01 แทนที่จะเป็น Python ดั้งเดิมdatetimeให้ใช้สิ่งนี้แทน:

return (now - datetime.datetime(1970, 1, 1)).total_seconds()

งูใหญ่มีการตั้งชื่อที่มีความขัดแย้งกับสิ่งที่คุณอาจถูกนำไปใช้ใน Javascript ดูPEP 8 นอกจากนี้ฟังก์ชันที่ส่งกลับผลลัพธ์ของฟังก์ชันอื่นก็ค่อนข้างโง่ หากเป็นเพียงเรื่องของการทำให้สามารถเข้าถึงได้มากขึ้นคุณสามารถสร้างชื่ออื่นสำหรับฟังก์ชันได้โดยเพียงแค่กำหนดชื่อฟังก์ชัน ตัวอย่างแรกด้านบนสามารถแทนที่ได้ด้วย:

utc_now = datetime.datetime.utcnow

1
ฉันชอบคำตอบของคุณดีกว่าคำตอบที่ได้รับคะแนนสูงจากด้านบน ขอบคุณสำหรับความลึกซึ้งที่นี่
Jordan Dea-Mattson

@ จอร์แดนมองย้อนกลับไปดูคำตอบของฉันฉันรู้ว่าฉันทำผิดโวหารโดยใส่การนำเข้าไว้ในฟังก์ชันแทนที่จะเป็นระดับโลกฉันจะแก้ไขในตอนนี้
Mark Ransom

8
บางทีคุณควรพิจารณาการรวม UtcNow () ไว้ในฟังก์ชันอื่น มันง่ายเกินไป และอย่าใช้เครื่องหมายขีดล่าง PEP 8 น่าเบื่อจัง ...
vcarel

1
ไม่จำเป็นต้องเขียนฟังก์ชันเพื่อส่งคืน one-liner แบบธรรมดาอย่างแน่นอน ... datetime.datetime.utcnow ()
cpreid

1
@TimRichardson ฉันไม่เห็นด้วย แต่ในขณะที่เขียนคำตอบนี้ไม่มีทางเลือกอื่น - Python ไม่รวมtzinfoวัตถุใด ๆแม้แต่ UTC
Mark Ransom

35

ไลบรารีมาตรฐานที่เรียบง่ายเท่านั้นสำหรับ python สมัยใหม่ ให้ datetime datetime.utcnow()เขตตระหนักถึงซึ่งแตกต่างจาก datetimesการไม่มีเขตเวลาเป็นอุบัติเหตุที่รอให้เกิดขึ้น

from datetime import datetime,timezone
now_utc = datetime.now(timezone.utc)

5
ตามเอกสาร Python 3 นี่เป็นวิธีที่แนะนำให้ทำ
roskakori

ทำความสะอาดง่าย! ควรเป็นวิธีที่ต้องการ
Marry35

22
import datetime
import pytz

# datetime object with timezone awareness:
datetime.datetime.now(tz=pytz.utc)

# seconds from epoch:
datetime.datetime.now(tz=pytz.utc).timestamp() 

# ms from epoch:
int(datetime.datetime.now(tz=pytz.utc).timestamp() * 1000) 

10

จาก datetime.datetime คุณสามารถเอ็กซ์พอร์ตไปยังการประทับเวลาด้วยวิธี strftime ได้แล้ว ทำตามตัวอย่างฟังก์ชันของคุณ:

import datetime
def UtcNow():
    now = datetime.datetime.utcnow()
    return int(now.strftime("%s"))

หากคุณต้องการไมโครวินาทีคุณต้องเปลี่ยนสตริงการส่งออกและแคสต์ให้ลอยดังนี้: return float(now.strftime("%s.%f"))


อะไรคือจุดของการแปลงเป็นสตริงแล้วกลับไปเป็นตัวเลขเมื่อคุณสามารถรับหมายเลขได้โดยตรง?
Mark Ransom

ประเด็นก็คือคุณอาจต้องการเปลี่ยนแปลงสิ่งต่างๆในฟังก์ชันและด้วยเหตุนี้จึงควรยึดติดกับวัตถุวันที่และเวลาไม่ใช้time.time()คุณยังสามารถใช้ time.mktime (now.timetuple ()) เพื่อแปลงโดยตรงเป็น int อย่างไรก็ตามสำหรับกรณีง่ายๆนี้time.time()ก็เป็นตัวเลือกที่ใช้ได้เช่นกัน สิ่งที่ฉันคิดว่าแปลกคือไปตามกำหนดเวลาเพื่อหาวินาที
hectorcanto

หมายเหตุนั่นstrftime("%s")ขึ้นอยู่กับแพลตฟอร์มและไม่ทำงานบน Windows (อย่างน้อยก็ไม่เหมาะสำหรับฉันใน Windows 10)
Julian Kirsch

8

เขตเวลาที่รับรู้โดยไม่มีการอ้างอิงภายนอก:

from datetime import datetime, timezone

def utc_now():
    return datetime.utcnow().replace(tzinfo=timezone.utc)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.