Konversi python datetime ke zaman dengan strftime

209

Saya punya waktu di UTC dari mana saya ingin jumlah detik sejak zaman.

Saya menggunakan strftime untuk mengubahnya menjadi jumlah detik. Mengambil 1 April 2012 sebagai contoh.

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

1 April 2012 UTC dari zaman adalah 1333238400 tetapi ini di atas mengembalikan 1333234800 yang berbeda dengan 1 jam.

Jadi sepertinya strftime mengambil waktu sistem saya ke dalam akun dan menerapkan pergeseran zona waktu di suatu tempat. Saya pikir datetime itu benar-benar naif?

Bagaimana saya bisa mengatasi itu? Jika mungkin menghindari untuk mengimpor perpustakaan lain kecuali standar. (Saya memiliki masalah portabilitas).

Noel
sumber
11
Apakah saya satu-satunya yang mencatat bahwa Anda menggunakan literal oktal dalam angka?
Fish Monitor
3
Memiliki Python 3.3+ lebih barudatetime.datetime.timestamp(datetime.datetime.utcnow())
MarkHu

Jawaban:

390

Jika Anda ingin mengkonversi datetime python ke detik sejak zaman Anda dapat melakukannya secara eksplisit:

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

Di Python 3.3+ Anda bisa menggunakan timestamp():

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

Mengapa Anda tidak menggunakannya? datetime.strftime('%s')

Python sebenarnya tidak mendukung% s sebagai argumen untuk strftime (jika Anda memeriksa di http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior tidak ada dalam daftar), satu-satunya alasan kerjanya adalah karena Python meneruskan informasi ke strftime sistem Anda, yang menggunakan zona waktu lokal Anda.

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'
jleahy
sumber
7
Saya sudah gila mencoba untuk mencari tahu mengapa saya sering melihat strftime ("% s"), tetapi itu tidak ada dalam dokumen. Terima kasih atas ini!
Jonathan Vanasco
54
jangan gunakan .strftime("%s"): tidak didukung, tidak portabel, diam-diam dapat menghasilkan hasil yang salah untuk objek sadar waktu, gagal jika input dalam UTC (seperti dalam pertanyaan) tetapi zona waktu lokal bukan UTC
jfs
2
@earthmeLon bracketing Anda salah. Timedeltas (dibuat dengan mengurangi dua datetimes) memiliki total_seconds, tetapi datetimes tidak.
jleahy
2
Ini tidak berfungsi untuk saya:AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'
Michael
3
@Michael Fungsi itu baru dalam Python 2.7, Anda harus menggunakan versi yang lebih lama. Untuk versi sebelum 2.7 bisa Anda lakukan td.seconds + td.days*24*3600. Ini membuang bagian mikrodetik.
jleahy
100

Saya memiliki masalah serius dengan Zona Waktu dan semacamnya. Cara Python menangani semua itu sangat membingungkan (bagi saya). Hal-hal tampaknya berfungsi dengan baik menggunakan modul kalender (lihat tautan 1 , 2 , 3 dan 4 ).

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400
BorrajaX
sumber
7
Memberi +1 karena ini adalah satu-satunya jawaban yang berfungsi untuk masukan dalam pertanyaan.
jfs
apakah ini portabel?
benjaminz
1
Ini harus ditandai sebagai jawaban yang benar, karena ini menjawab kekhawatiran yang dimaksud. vnice kudos
Leo Prince
2
Ini 'berfungsi', tetapi perhatikan pertanyaan yang menyatakan: "Saya punya waktu di UTC" Metode ini akan selalu menggunakan zona waktu lokal sistem. Tidak ada cara untuk menentukan zona waktu. Jika aprilFirstdalam contoh ini adalah contoh 'sadar' dan menggunakan zona waktu yang berbeda dari zona waktu sistem, hasilnya tidak akan benar (zona waktu hilang dalam timetuple()panggilan). Untuk mendapatkan jawaban yang tepat untuk datetime 'sadar' yang dapat Anda gunakan awaredt.timestamp()pada Python 3 terbaru. Untuk Python 2 lebih sulit; salah satu caranya adalah dengan menggunakan arrowperpustakaan. arrow.get(awaredt).timestampakan melakukannya dengan benar.
Adam Williamson
1
Poin bagus, @AdamWilliamson, tetapi kode dalam contoh ini tidak melokalisasi datetimeobjek, jadi saya berasumsi bahwa "Saya punya waktu di UTC" berarti bahwa OP memiliki datetimeobjek yang tidak disadari yang diasumsikan berada dalam UTC yang ia inginkan untuk mendapatkan epoch(jika datetimekebetulan TZ-sadar ini mungkin, memang, mengubah keadaan). Juga, ingatlah bahwa jawaban ini hampir 8 tahun dan banyak hal telah terjadi sejak ( arrowdirilis pada 2013, misalnya)
BorrajaX
35
import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())
menyeberang
sumber
1
itu adalah cara yang salah untuk menulis time.time()( mktime()mungkin gagal selama transisi DST sambil time.time()terus bekerja). Dan itu tidak menjawab pertanyaan kecuali zona waktu lokal adalah UTC (input dalam pertanyaan adalah dalam UTC). Bahkan jika input akan mewakili waktu lokal maka mktime()mungkin juga gagal untuk tanggal masa lalu / masa depan jika tidak menggunakan database tz dan jika zona waktu lokal mungkin memiliki offset utc yang berbeda selama bertahun-tahun misalnya, Eropa / Moskow pada 2010-2015 - - gunakan waktu UTC (seperti dalam pertanyaan) atau objek datetime sadar-waktu sebagai gantinya.
jfs
di sini ada lebih banyak masalah dengan mengonversi waktu lokal (seperti dikembalikan oleh .now()) ke cap waktu zaman (dikembalikan oleh mktime()) . Jika Anda membacanya; Anda memahami mengapa input UTC (digunakan dalam pertanyaan) lebih disukai daripada objek datetime naif yang mewakili waktu lokal
jfs
14
import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(Maaf, itu tidak akan membiarkan saya mengomentari jawaban yang ada)

Charles Plager
sumber
Itu karena time.mktime tidak mempertimbangkan bagian mikrodetik, kan?
Eduardo
1
Benar. Waktu tuple struct (berdasarkan pada strut C) tidak memiliki ruang untuk mikrodetik, jadi kita perlu mengambil info dari objek datetime dan menambahkannya di akhir.
Charles Plager
Di komputer saya, ini berfungsi dengan benar meskipun zona waktu saya adalah ET.
Charles Plager
1
Ini akan memberi Anda cap waktu yang berbeda pada sistem yang berbeda berdasarkan waktu lokal sistem.
Yousaf
6

jika Anda hanya perlu cap waktu dalam waktu unix / zaman, baris yang satu ini berfungsi:

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

dan hanya bergantung pada datetime karya di python2 dan python3

Marc Maxmeister
sumber
2

Ini berfungsi di Python 2 dan 3:

>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998

Cukup mengikuti dokumen resmi ... https://docs.python.org/2/library/time.html#module-time

Luis Pollo
sumber
1) Ini mengasumsikan Anda ingin mengonversi sekarang, bukan objek datetime acak. 2) Anda tidak perlu kalender. time.mktime (randomDateTime.timetuple ()) + randomDateTime.microsecond * 1e-6
Charles Plager
@CharlesPlager time.mktime salah; itu menafsirkan argumen di zona waktu lokal, sedangkan OP ingin waktu diinterpretasikan dalam UTC (seperti yang dilakukan calendar.timegm).
stewbasic
Ini jawaban paling akurat untuk saya, jika Anda ingin mengonversi waktu Anda dalam GMT dan Anda ingin tetap seperti itu pada konversi ke cap waktu zaman.
Yousaf
Cukup mengikuti jawaban Anda, calendar.timegm (datetime.strptime ("2019-05-03T05: 40: 09.770494 + 00: 00" [: 16], '% Y-% m-% dT% H:% M'). timetuple ()) Saya memiliki timestamp di utc dan tidak peduli sistem apa yang Anda jalankan memberi saya cap waktu yang benar, triknya adalah dengan menggunakan strptime.timetumple
Yousaf
2

Untuk solusi bebas zona waktu eksplisit, gunakan perpustakaan pytz.

import datetime
import pytz

pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()

Output (float): 1333238400.0

Moobie
sumber
melihat jawaban yang sama di stackoverflow.com/a/21145908/4355695 , tetapi yang ini sebagai satu-liner sangat bagus untuk kasus penggunaan saya di mana data yang masuk adalah dalam UTC dan hanya .timestamp () menganggapnya dalam waktu lokal .
Nikhil VJ
Ini berfungsi untuk kencan kurang dari 1970. Terima kasih. Jawaban yang diterima tidak berfungsi untuk tanggal yang kurang dari 1970. (Python 3.7.3 64-bit Anaconda3)
canbax
-1

Dalam Python 3.7

Kembalikan datetime yang sesuai dengan date_string di salah satu format yang dipancarkan oleh date.isoformat () dan datetime.isoformat (). Secara khusus, fungsi ini mendukung string dalam format YYYY-MM-DD [* HH [: MM [: SS [.fff [fff]]]] [+ HH: MM [: SS [.ffffff]]]]] , di mana * dapat mencocokkan karakter tunggal apa pun.

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat

SuperNova
sumber
1
Sadarilah bahwa ini diperkenalkan dalam Python 3.7.
keithpjolley