Python Buat cap waktu unix lima menit di masa depan


297

Saya harus membuat nilai "Kedaluwarsa" 5 menit di masa mendatang, tetapi saya harus menyediakannya dalam format Timestamp UNIX. Saya punya ini sejauh ini, tetapi sepertinya hack.

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

Apakah ada modul atau fungsi yang melakukan konversi stempel waktu untuk saya?


7
Saya sarankan untuk mengubah topik pembicaraan. Pertanyaannya bagus, tetapi ini bukan tentang mengubah datetime menjadi cap waktu Unix. Ini tentang bagaimana mendapatkan cap waktu Unix 5 menit di masa depan.
DA

Saya tidak setuju, @DA Pertanyaannya pada dasarnya mengatakan, "Saya perlu melakukan X dan Y. Inilah yang saya miliki sekarang. Apa cara yang lebih baik untuk melakukan Y?" Mungkin ada cara yang lebih baik untuk melakukan X, tetapi judul dan tubuh jelas bertanya tentang Y.
Rob Kennedy

6
Saya setuju dengan Anda sepenuhnya pada pertanyaan, dan saya pikir itu adalah jawaban yang bagus. Masalahnya adalah "Python datetime ke Unix timestamp" tidak mencerminkan pertanyaan atau jawaban. Saya menemukan posting ini sedang mencari cara untuk melakukan konversi, dan saya kehilangan waktu karena baris subjek yang menyesatkan. Saya menyarankan: "Python, 5 menit di masa depan sebagai UNIX Timestamp"
DA

3
@JimmyKane - Jawaban yang cukup komprehensif tentang cara mendapatkan cap waktu dari tanggal dapat ditemukan di sini: stackoverflow.com/questions/8777753/…
Tim Tisdall

@TimTisdall ya karena judulnya diubah tidak masuk akal
Jimmy Kane

Jawaban:


349

Cara lain adalah dengan menggunakan calendar.timegm:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

Ini juga lebih portabel daripada %smenandai ke strftime(yang tidak berfungsi pada Windows).


Terima kasih D.Shawley. help (datetime.timedelta) tidak menyebutkan pintasan itu. Itu hanya memiliki hari, detik, dan mikrodetik.
Daniel Rhoden

12
Perhatikan bahwa, menggabungkan sebelumnya dua komentar, solusi yang tepat adalah: calendar.timegm(future.utctimetuple()). Ini memastikan bahwa waktu UTC dilewatkan calendar.timegm.
shadowmatter

1
Tidak dapat mengunggulkan komentar @ tumbleweed cukup. Jika Anda mencoba untuk mendapatkan cap waktu UNIX (dan karenanya satu dalam UTC), gunakan calendar.timegm.
Bialecki

@tumbleweed, benar. Jika Anda menggunakan mktime plus gmtime (0) akan menghasilkan delta pulang-pergi bukan nol untuk zona waktu apa pun selain UTC: mis. `Time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple ())` memberikan 21600.0detik (6 jam) bukannya 0,0 untuk TZ mesin unix saya
hobs

Jika Anda ingin mendapatkan UTC timestamp Anda harus menggunakan ini: calendar.timegm(datetime.datetime.utcnow().timetuple()). Metode menggunakan datetime.datetime.now().utctimetuple()tidak berfungsi untuk saya (Python 3.2).
Wookie88

155

Sekarang dengan Python> = 3.3 Anda bisa memanggil metode timestamp () untuk mendapatkan timestamp sebagai float.

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds

4
+1 untuk ini. Itu harus ditampilkan jauh lebih tinggi, karena itu cara bersih bagaimana melakukannya dengan Python 3
Viktor Stískala

2
@ scott654 Saya pikir memilikinya tepat di awal komentar membuatnya cukup jelas, tetapi saya menambahkan beberapa tebal juga.
Tim Tisdall

1
Saya akan membuat catatan sebagai komentar di blok kode karena kita semua hanya memindai kode dalam jawaban terlebih dahulu dan hanya membaca sisanya jika kodenya terlihat bagus. Jawaban yang bagus.
Matius Purdon

2
waktu setempat mungkin ambigu . Contoh ( datetime.now()) buruk karena mendorong penggunaan objek datetime naif yang mewakili waktu lokal dan mungkin gagal selama transisi DST (karena ambiguitas yang melekat). Anda bisa menggunakannya ts = datetime.now(timezone.utc).timestamp()sebagai gantinya.
jfs

@ JSFSebastian - poin bagus. Saya tidak ingin menambah impor, jadi saya mengubahnya ke utcnow(). Saya sudah terbiasa bekerja dengan mesin di mana zona waktu diatur ke UTC, tetapi itu tidak seharusnya diasumsikan dalam cuplikan kode ini.
Tim Tisdall

139

Baru saja menemukan ini, dan bahkan lebih pendek.

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

12
Ini tidak menjawab pertanyaan.
Jesse Dhillon

22
@JesseDhillon menjawab pertanyaan (membuat cap waktu UNIX 5 menit di masa depan), hanya saja bukan judulnya.
dbr

3
time.time()dapat diatur kembali. Untuk membuat nilai "Kedaluwarsa" 5 menit di masa depan, Anda mungkin perlu time.monotonic()analog tergantung pada kasus penggunaan Anda.
jfs

@ jf-sebastian time.monotonic () tidak mengembalikan timestamp UNIX, ia mengembalikan timestamp dengan titik referensi yang tidak ditentukan.
rspeer

@rspeer: ya, seperti yang dikatakan dokumen , hanya perbedaan antara panggilan berurutan yang valid. Apakah monotonicdapat digunakan tergantung pada kasus penggunaan Anda misalnya, subprocessmodul menggunakannya untuk menerapkan timeoutopsi.
jfs

57

Inilah yang Anda butuhkan:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

Bagaimana ini berbeda atau menambah yang disediakan 'Cat Plus Plus'?
David

3
EG ini adalah jawaban untuk pertanyaan "datetime Python ke timestamp Unix" sementara Cat Plus Plus menjawab pertanyaan "datetime Python yang akan berada dalam 5 menit ke timestamp Unix". Jadi yang ini bersih dan jelas.
running.t

@ running.t: itu mengingatkan saya: "setiap masalah memiliki solusi yang sederhana, jelas dan salah ". Lihat kemungkinan masalah denganmktime(dt.timetuple()) . datetime.now(timezone.utc).timestamp()disediakan oleh @Tim Tisdall adalah solusi dalam Python 3.3+. Kalau tidak (dt - epoch).total_seconds()bisa digunakan .
jfs

@ JFSebastian bagaimana jika saya benar-benar ingin semua perhitungan dilakukan dalam waktu lokal? Apakah ini terjadi ketika misalnya. untuk mengurai string naif yang diketahui adalah waktu lokal dan memutuskan apakah ada DST yang berlaku pada waktu tertentu?
n611x007

1
@naxa: ya, beberapa waktu lokal bersifat ambigu atau tidak ada. Juga offset zona waktu mungkin berbeda karena alasan selain DST (Anda memerlukan basis data tz seperti pytz, untuk mengetahui offset yang benar). Waktu setempat berarti apa pun yang dipikirkan politisi lokal adalah ide yang baik untuk mengukur waktu, mungkin sangat tidak teratur.
jfs

48

Anda dapat menggunakan datetime.strftimeuntuk mendapatkan waktu dalam bentuk Epoch, menggunakan %sstring format:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

Catatan: Ini hanya berfungsi di linux, dan metode ini tidak bekerja dengan zona waktu.


32
Ini adalah perilaku yang agak tidak berdokumen ( python.org/doc/current/library/datetime.html ). Tampaknya bekerja di bawah linux dan tidak bekerja di bawah win32 (menghasilkan ValueError: Invalid format string).
Antony Hatchkins

3
Metode ini tidak bekerja dengan zona waktu. Mengubah zona waktu akan memberikan datetime hasil yang sama (2013,12,7, tzinfo = timezone ("America / Chicago")). Strftime ("% s") 1386385200 datetime (2013,12,7, tzinfo = timezone ("Eropa / Riga ")). Strftime ("% s ") 1386385200
Martins Balodis

11

Berikut ini adalah datetimesolusi berbasis -kurang rusak untuk mengkonversi dari objek datetime ke posix timestamp:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return (future - datetime.datetime(1970, 1, 1)).total_seconds()

Lihat lebih detail di Konversi datetime.date ke stempel waktu UTC dengan Python .


6
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()

4

Kuncinya adalah memastikan semua tanggal yang Anda gunakan berada di zona waktu utc sebelum Anda mulai mengonversi. Lihat http://pytz.sourceforge.net/ untuk mempelajari cara melakukannya dengan benar. Dengan menormalkan ke utc, Anda menghilangkan ambiguitas transisi tabungan siang hari. Kemudian Anda dapat menggunakan timedelta dengan aman untuk menghitung jarak dari zaman unix, dan kemudian mengonversi ke detik atau milidetik.

Perhatikan bahwa cap waktu unix yang dihasilkan itu sendiri di zona waktu UTC. Jika Anda ingin melihat cap waktu di zona waktu yang dilokalkan, Anda perlu melakukan konversi lain.

Perhatikan juga bahwa ini hanya akan berfungsi untuk tanggal setelah 1970.

   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms

3
catatan: Saya tidak mengerti "cap waktu [unix] di zona waktu lokal". Stempel waktu sama (berlalu sejak detik 1970-01-01 00:00:00+00:00). Untuk mendapatkan objek datetime naif di zona waktu lokal:datetime.fromtimestamp(ts)
jfs

4

Berikut ini didasarkan pada jawaban di atas (ditambah koreksi untuk milidetik) dan mengemulasi datetime.timestamp()untuk Python 3 sebelum 3,3 ketika zona waktu digunakan.

def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

Untuk benar-benar menjawab pertanyaan saat ditanyakan, Anda ingin:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampadalah bagian dari kencan sederhana . Tetapi jika Anda menggunakan paket itu, Anda mungkin akan mengetik:

SimpleDate(my_datetime).timestamp + 5 * 60

yang menangani lebih banyak format / tipe untuk my_datetime.


tidakkah Anda menambahkan (5 * 60) untuk menambah 5 menit? Saya pikir hanya menambahkan 5 menambahkan hanya 5 detik ke timestamp.
Tim Tisdall

1
def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue

1

Perhatikan bahwa solusi dengan timedelta.total_seconds()bekerja pada python-2.7 +. Gunakan calendar.timegm(future.utctimetuple())untuk versi Python yang lebih rendah.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.