Saya punya dt = datetime(2013,9,1,11)
, dan saya ingin mendapatkan cap waktu Unix dari objek datetime ini.
Ketika saya melakukannya (dt - datetime(1970,1,1)).total_seconds()
saya mendapat cap waktu 1378033200
.
Ketika mengubahnya kembali menggunakan datetime.fromtimestamp
saya dapatkan datetime.datetime(2013, 9, 1, 6, 0)
.
Jamnya tidak cocok. Apa yang saya lewatkan di sini?
timestamp
metode ini alih-alih mencoba melakukannya sendiri. Untuk satu hal, itu sepenuhnya menghindari kemungkinan mengurangi waktu naif dari zona waktu yang berbeda.dt
? Apakah ini waktu setempat atau waktu dalam UTC?Jawaban:
Yang Anda lewatkan di sini adalah zona waktu.
Agaknya Anda sudah lima jam libur UTC, jadi 2013-09-01T11: 00: 00 lokal dan 2013-09-01T06: 00: 00Z adalah waktu yang sama.
Anda perlu membaca bagian atas
datetime
dokumen, yang menjelaskan tentang zona waktu dan objek "naif" dan "sadar".Jika waktu naif awal Anda adalah UTC, cara untuk memulihkannya adalah dengan menggunakannya
utcfromtimestamp
sebagai gantifromtimestamp
.Di sisi lain, jika dat naif awal Anda adalah lokal, Anda seharusnya tidak mengurangi stempel waktu UTC darinya; gunakan
datetime.fromtimestamp(0)
saja.Atau, jika Anda memiliki objek data sadar, Anda harus menggunakan zaman lokal (sadar) di kedua sisi, atau secara eksplisit mengkonversi ke dan dari UTC.
Jika Anda memiliki, atau dapat meningkatkan ke, Python 3.3 atau yang lebih baru, Anda dapat menghindari semua masalah ini dengan hanya menggunakan
timestamp
metode alih-alih mencoba mencari cara untuk melakukannya sendiri. Dan bahkan jika tidak, Anda mungkin ingin mempertimbangkan untuk meminjam kode sumbernya .(Dan jika Anda bisa menunggu Python 3.4, sepertinya PEP 341 kemungkinan akan membuatnya menjadi rilis final, yang berarti semua hal yang saya dan JF bicarakan dalam komentar harus dilakukan hanya dengan stdlib, dan bekerja dengan cara yang sama pada Unix dan Windows.)
sumber
dt
berada di zona waktu lokal maka rumus dalam pertanyaan tersebut tidak benardatetime.fromtimestamp(0)
(zaman di zona waktu saat ini) harus digunakan sebagai gantinyadatetime(1970, 1,1)
(unix zaman dalam UTC).fromtimestamp(0)
mungkin gagal jika sistem tidak menyimpan informasi zona waktu historis, misalnya, pada Windows.pytz
dapat digunakan dalam kasus ini.pytz
tidak membantu kecuali Anda sudah tahu zona waktu Anda; untuk melakukannya secara terprogram, Anda memerlukan pustaka yang berbeda yang mendapatkan zona waktu Windows saat ini dan mengubahnya menjadipytz
zona waktu dan / atau mencarinya berdasarkan nama.tzlocal
modul yang juga berfungsi di Windows. Inilah cara Anda dapat mengubah waktu utc ke waktu lokal .solusinya adalah
sumber
d
adalah tanggal / objek waktu naif yang mewakili waktu lokal (mungkin gagal untuk waktu yang ambigu atau untuk tanggal masa lalu / masa depan jika OS tidak memberikan sejarah tz db (offset UTC mungkin berbeda di masa lalu di lokal) zona waktu)). Opsi lainnya .Jika Anda ingin mengkonversi datetime python ke detik sejak zaman Anda harus melakukannya secara eksplisit:
Di Python 3.3+ Anda bisa menggunakan
timestamp()
:sumber
%s
, karena akan dilokalkan ke jam sistem Anda saat ini. Anda hanya boleh menggunakannya.timestamp()
untuk mendapatkan waktu Epoch / UNIX yang benar.%s
tidak bekerja pada sistem Windows (ValueError: Invalid format string
)8
atau9
Daripada ungkapan ini untuk membuat stempel waktu POSIX dari
dt
,Gunakan ini:
Saya mendapatkan jawaban yang benar dalam contoh Anda menggunakan metode kedua.
EDIT: Beberapa tindak lanjut ... Setelah beberapa komentar (lihat di bawah), saya ingin tahu tentang kurangnya dukungan atau dokumentasi untuk
%s
distrftime
. Inilah yang saya temukan:Dalam sumber Python untuk
datetime
dantime
, stringSTRFTIME_FORMAT_CODES
memberitahu kita:Jadi sekarang jika kita
man strftime
(pada sistem BSD seperti Mac OS X), Anda akan menemukan dukungan untuk%s
:Bagaimanapun, itu sebabnya
%s
bekerja pada sistem yang dilakukannya. Tetapi ada solusi yang lebih baik untuk masalah OP (yang memperhitungkan zona waktu). Lihat jawaban yang diterima @ abarnert di sini.sumber
strftime("%s")
dalam dokumentasi, saya hanya mengkonfirmasi ini berfungsi di Mac dan Linux. Terima kasih.time.strftime()
dandatetime.strftime
dokumentasi mendelegasikanstrftime(3)
fungsi platform untuk arahan yang tidak didukung.%s
mungkin gagal bahkan pada Mac OS X misalnya, datetime.strftime ('% s') harus menghormati tzinfo .%s
karena Anda hanya akan menggunakan waktu sistem yang dilokalkan dari sistem yang Anda gunakan. Anda ingin menggunakan.timestamp()
jika Anda mencoba untuk mendapatkan cap waktu UNIX nyata.Untuk bekerja dengan zona waktu UTC:
sumber
Anda telah melewatkan info zona waktu (sudah dijawab, disetujui)
arrow
paket memungkinkan untuk menghindari penyiksaan ini dengan data; Ini sudah ditulis, diuji, diterbitkan-pypi, lintas-python (2.6 - 3.xx).Yang Anda butuhkan:
pip install arrow
(atau tambahkan ke dependensi)Solusi untuk kasus Anda
sumber
Jika objek datetime Anda mewakili waktu UTC, jangan gunakan time.mktime, karena mengasumsikan tuple berada di zona waktu lokal Anda. Sebagai gantinya, gunakan kalender.timegma:
sumber
Nah, ketika mengonversi ke unix timestamp, pada dasarnya python mengasumsikan UTC, tetapi saat mengonversi kembali itu akan memberi Anda tanggal yang dikonversi ke zona waktu lokal Anda.
Lihat pertanyaan / jawaban ini; Dapatkan zona waktu yang digunakan oleh datetime.datetime.fromtimestamp ()
sumber
Jika Anda ingin cap waktu UTC:
time.mktime
hanya untuk dt lokal. Gunakancalendar.timegm
aman tetapi dt harus zona utc jadi ubah zona ke utc. Jika dt di UTC gunakan sajacalendar.timegm
.sumber
sumber
Kelas ini akan mencakup kebutuhan Anda, Anda dapat meneruskan variabel ke ConvertUnixToDatetime & panggil fungsi mana yang Anda inginkan untuk beroperasi berdasarkan.
sumber