Ubah tanggal string menjadi stempel waktu dengan Python

219

Bagaimana cara mengubah string dalam format "%d/%m/%Y"menjadi cap waktu?

"01/12/2011" -> 1322697600
Shankar Cabus
sumber
Apa nomor 2? Waktu Unix Epoch?
Hasteur
4
@Asteur, ya. Angka kedua mewakili jumlah detik yang telah berlalu antara awal zaman unix dan tanggal yang ditentukan. Format ini juga disebut sebagai waktu POSIX.
eikonomega

Jawaban:

316
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
Katriel
sumber
10
mengasumsikan tengah malam 01/12/2011 di zona waktu lokal. Jika input dalam UTC; Anda bisa menggunakan calendar.timegm()atau.toordinal()
jfs
49
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp()sedikit lebih pendek
timdiels
11
@timdiels: lagi. .timestamp()mengasumsikan waktu lokal alih-alih UTC jika tidak ada zona waktu eksplisit yang diberikan. Kode dalam jawaban berfungsi (menghasilkan yang diharapkan 1322697600) hanya pada komputer di mana zona waktu lokal memiliki nol utc offset.
jfs
7
ini tidak berfungsi: datetime.datetime.strptime ("2014: 06: 28 11:53:21", "% Y:% m:% d% H:% M:% S"). timestamp () Traceback () panggilan terakhir terakhir): File "<stdin>", baris 1, dalam <module> AttributeError: objek 'datetime.datetime' tidak memiliki atribut 'cap waktu'
Zdenek Maxa
5
@ZdenekMaxa datetime.timestamp () hanya tersedia untuk python> = versi 3.3. docs.python.org/3/whatsnew/3.3.html
joni jones
48

Saya menggunakan ciso8601, yang 62x lebih cepat dari strptime datetime.

t = "01/12/2011"
ts = ciso8601.parse_datetime(t)
# to get time in seconds:
time.mktime(ts.timetuple())

Anda dapat mempelajari lebih lanjut di sini .

Eyal Ch
sumber
2
ini adalah saran yang fantastis. saya hanya menggunakannya dan mencukur BANYAK waktu dari eksekusi saya.
David
3
Ya Tuhan ini cepat
Hews
3
Dan +1 karena tidak membutuhkan saya untuk menjelaskan format format string waktu.
gowenfawr
40

Untuk mengonversi string menjadi objek tanggal:

from datetime import date, datetime

date_string = "01/12/2011"
date_object = date(*map(int, reversed(date_string.split("/"))))
assert date_object == datetime.strptime(date_string, "%d/%m/%Y").date()

Cara untuk mengubah objek tanggal menjadi cap waktu POSIX tergantung pada zona waktu. Dari Konversi datetime.dateke stempel waktu UTC di Python :

  • objek tanggal mewakili tengah malam dalam UTC

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
    
  • objek tanggal mewakili tengah malam di waktu setempat

    import time
    
    timestamp3 = time.mktime(local_date.timetuple())
    assert timestamp3 != timestamp1 or (time.gmtime() == time.localtime())
    

Stempel waktu berbeda kecuali tengah malam di UTC dan dalam waktu lokal adalah contoh waktu yang sama.

jfs
sumber
Ketika saya menjalankan contoh dalam posting ini, saya mendapatkan error: NameError: name 'wckCalendar' is not defined. Saya menjalankan Python 3.4.1 pada mesin Windows 32 bit. Ada ide? Terima kasih.
sedeh
1
@sedeh tidak ada wckCalendar di pos. Periksa kode Anda.
jfs
@ JFSebastian Tepat, dan saya tidak mencoba menelepon wckCalendar secara langsung. Itu hanya muncul di pesan kesalahan. Lihat posting saya di sini membahas masalah.
sedeh
1
@ törzsmókus: Jika jawabannya salah, Tidak masalah seberapa mudah dibaca.
jfs
1
@ törzsmókus: lihat jawaban saya: mungkin menghasilkan dua angka yang berbeda. Jawaban Anda menghasilkan satu nomor tanpa menyebutkan yang mana.
jfs
30
>>> int(datetime.datetime.strptime('01/12/2011', '%d/%m/%Y').strftime("%s"))
1322683200
San4ez
sumber
10
"%s"tidak didukung oleh Python . Itu tidak portabel.
jfs
Jumlah keterbacaan diperhitungkan. Lihat jawaban saya dengan dateutil untuk solusi yang jauh lebih mudah dibaca oleh manusia.
törzsmókus
21

Jawabannya juga tergantung pada zona waktu tanggal input Anda. Jika kencan Anda adalah tanggal lokal, maka Anda dapat menggunakan mktime () seperti kata katrielalex - hanya saja saya tidak melihat mengapa ia menggunakan datetime alih-alih versi yang lebih pendek ini:

>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

Tetapi amati bahwa hasil saya berbeda dari dia, karena saya mungkin berada di TZ yang berbeda (dan hasilnya adalah timestamp UNIX bebas zona waktu)

Sekarang jika tanggal input sudah dalam UTC, daripada saya percaya solusi yang tepat adalah:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600
Nowakus
sumber
Saya pikir ini lebih baik. Tidak perlu mengimpor 'waktu' dan 'datetime'.
kennyut
17

Cukup gunakan datetime.datetime.strptime:

import datetime
stime = "01/12/2011"
print(datetime.datetime.strptime(stime, "%d/%m/%Y").timestamp())

Hasil:

1322697600

Untuk menggunakan UTC alih-alih menggunakan zona waktu lokal .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()
nm111
sumber
Untuk server lengkap, Anda harus mengatakan bahwa itu hanya berlaku untuk python 3.3+
Eduardo
Pada contoh pertama, hasilnya adalah floattidakint
CONvid19
6

Pertama, Anda harus kelas strptime untuk mengonversi string ke format struct_time.

Maka cukup gunakan mktime dari sana untuk mendapatkan float Anda.

Cryptite
sumber
6

Banyak dari jawaban ini tidak repot untuk menganggap bahwa tanggal itu naif untuk memulai

Agar benar, Anda harus menjadikan tanggal naif sebagai zona waktu yang disadari oleh zona waktu terlebih dahulu

import datetime
import pytz
# naive datetime
d = datetime.datetime.strptime('01/12/2011', '%d/%m/%Y')
>>> datetime.datetime(2011, 12, 1, 0, 0)

# add proper timezone
pst = pytz.timezone('America/Los_Angeles')
d = pst.localize(d)
>>> datetime.datetime(2011, 12, 1, 0, 0,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

# convert to UTC timezone
utc = pytz.UTC
d = d.astimezone(utc)
>>> datetime.datetime(2011, 12, 1, 8, 0, tzinfo=<UTC>)

# epoch is the beginning of time in the UTC timestamp world
epoch = datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.UTC)
>>> datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)

# get the total second difference
ts = (d - epoch).total_seconds()
>>> 1322726400.0

Juga:

Hati-hati, menggunakan pytzuntuk tzinfodalam datetime.datetimepekerjaan tidak bagi banyak zona waktu. Lihat datetime dengan pytz timezone. Offset berbeda tergantung pada bagaimana tzinfo diatur

# Don't do this:
d = datetime.datetime(2011, 12, 1,0,0,0, tzinfo=pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2011, 1, 12, 0, 0, 
tzinfo=<DstTzInfo 'America/Los_Angeles' LMT-1 day, 16:07:00 STD>)
# tzinfo in not PST but LMT here, with a 7min offset !!!

# when converting to UTC:
d = d.astimezone(pytz.UTC)
>>> datetime.datetime(2011, 1, 12, 7, 53, tzinfo=<UTC>)
# you end up with an offset

https://en.wikipedia.org/wiki/Local_mean_time

MrE
sumber
6

Saya akan menyarankan dateutil :

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()
törzsmókus
sumber
Ini salah. OP mengharapkan waktu dalam "%d/%m/%Y"format. Bandingkan: dateutil.parser.parse("01/02/2001")dandatetime.strptime("01/02/2001", "%d/%m/%Y")
jfs
terima kasih @ jfs, tangkapan yang bagus. Saya memperbarui jawaban saya sesuai. (sebagai non-Amerika, saya tidak akan berpikir format M / D / Y tidak logis adalah default untuk parser.)
törzsmókus
1
itu tidak menghasilkan yang diharapkan 1322697600kecuali zona waktu lokal Anda adalah UTC. Lihat komentar saya dari 2014
jfs
4

Tampaknya cukup efisien:

import datetime
day, month, year = '01/12/2011'.split('/')
datetime.datetime(int(year), int(month), int(day)).timestamp()

1,61 µs ± 120 ns per loop (rata-rata ± st. Dev dari 7 run, masing-masing 100000 loop)

Gerard
sumber
Apa datetimefungsinya? datetimedari datetimeperpustakaan tidak mendukung.timestamp()
Joooeey
@ Joooeey: Ya , pada Python 3.3 atau yang lebih baru . Tidak tersedia saat pertanyaan diposting, tetapi sudah tersedia sejak September 2012.
ShadowRanger
0

cukup gunakan datetime.timestamp (datse instanse Anda), instance datetime berisi informasi zona waktu, sehingga stempel waktu akan menjadi stempel waktu utc standar. jika Anda mengubah datetime menjadi timetuple, itu akan kehilangan zona waktu itu, sehingga hasilnya akan menjadi kesalahan. jika Anda ingin menyediakan antarmuka, Anda harus menulis seperti ini: int (datetime.timestamp (time_instance)) * 1000

pengguna6689187
sumber
0

Anda dapat mengonversi ke isoformat

my_date = '2020/08/08'
my_date = my_date.replace('/','-') # just to adapte to your question
date_timestamp = datetime.datetime.fromisoformat(my_date).timestamp()
Aliens Dev
sumber
-1

Fungsi sederhana untuk mendapatkan waktu UNIX Epoch.

CATATAN : Fungsi ini menganggap waktu tanggal input dalam format UTC (Lihat komentar di sini).

def utctimestamp(ts: str, DATETIME_FORMAT: str = "%d/%m/%Y"):
    import datetime, calendar
    ts = datetime.datetime.utcnow() if ts is None else datetime.datetime.strptime(ts, DATETIME_FORMAT)
    return calendar.timegm(ts.utctimetuple())

Penggunaan :

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600
gihanchanuka
sumber