Python Gelecekte beş dakika içinde unix zaman damgası oluşturun


297

Gelecekte 5 dakika bir "Sona erme" değeri oluşturmak zorundayım, ancak bunu UNIX Zaman Damgası biçiminde sağlamak zorundayım. Şimdiye kadar var, ama bir kesmek gibi görünüyor.

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

Zaman damgasını benim için dönüştüren bir modül veya işlev var mı?


7
Bu sorunun konusunu değiştirmenizi tavsiye ederim. Soru iyi, ama tarih saatini Unix zaman damgasına dönüştürmekle ilgili değil. Gelecekte 5 dakika Unix zaman damgasının nasıl alınacağı ile ilgilidir.
DA

Katılmıyorum, @DA Soru aslında "X ve Y yapmam gerekiyor. Şimdi sahip olduğum şey. Y yapmanın daha iyi bir yolu nedir?" Belki X yapmak için daha iyi yollar var, ancak başlık ve vücut açıkça Y hakkında soruyor
Rob Kennedy

6
Soruya tamamen katılıyorum ve bence iyi bir cevabı olan iyi bir soru. Sorun "Python datetime to Unix zaman damgası" soruyu veya cevabı yansıtmıyor. Bu gönderiyi dönüşümün bir yolunu ararken buldum ve yanıltıcı konu satırı nedeniyle zaman kaybettim. Ben önermek: "Python, UNIX Zaman Damgası olarak gelecekte 5 dakika"
DA

3
@JimmyKane - Bir tarih zamanından nasıl zaman damgası alacağınıza dair oldukça kapsamlı bir cevap burada bulunabilir: stackoverflow.com/questions/8777753/…
Tim Tisdall

@TimTisdall evet başlık değiştirildiğinden beri mantıklı değil
Jimmy Kane

Yanıtlar:


349

Başka bir yol da kullanmaktır calendar.timegm:

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

Ayrıca %sbayraktan daha taşınabilir strftime(Windows'ta çalışmaz).


Teşekkürler D.Shawley. yardım (datetime.timedelta) bu kısayoldan bahsetmedi. Sadece günler, saniyeler ve mikrosaniyeler vardı.
Daniel Rhoden

12
Önceki iki yorumlarınızı birleştirerek unutmayın doğru çözümdür: calendar.timegm(future.utctimetuple()). Bu, UTC saatinin geçmesini sağlar calendar.timegm.
shadowmatter

1
@ Tumbleweed adlı kullanıcının yorumu yeterince oylanamıyor. UNIX zaman damgası (ve dolayısıyla UTC'de bir tane) almaya çalışıyorsanız calendar.timegm komutunu kullanın.
Bialecki

@tumbleweed, doğru. Mktime artı gmtime (0) kullanırsanız UTC dışında herhangi bir saat dilimi için sıfır olmayan gidiş dönüş deltasıyla sonuçlanır: örneğin `time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple ())` 21600.0benim unix makinemin TZ için 0.0 yerine saniye (6 saat) verir
hobs

Eğer almak istiyorsanız UTC damgası bunu kullanmalısınız: calendar.timegm(datetime.datetime.utcnow().timetuple()). Yöntem kullanmak datetime.datetime.now().utctimetuple()benim için işe yaramıyor (Python 3.2).
Wookie88

155

Şimdi Python> = 3.3'te zaman damgasını kayan nokta olarak almak için timestamp () yöntemini çağırabilirsiniz .

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
Bunun için +1. Çok daha yüksek görüntülenmelidir, çünkü Python 3'te bunu yapmanın temiz yolu
Viktor Stískala

2
@ scott654 Yorumun başında doğru yapmayı düşündüm, yeterince netleştirdim, ama ben de buna biraz kalın ekledim.
Tim Tisdall

1
Ben kod bloğunda bir yorum olarak not yapmak çünkü hepimiz sadece cevapları ilk önce kodu tarayın ve sadece kod iyi görünüyorsa geri kalanını okuyun. Yine de iyi bir cevap.
Matthew Purdon

2
yerel saat belirsiz olabilir . Example ( datetime.now()) kötüdür, çünkü yerel saati temsil eden naif datetime nesnelerinin kullanımını teşvik eder ve DST geçişleri sırasında (doğal belirsizlik nedeniyle) başarısız olabilir. Bunun ts = datetime.now(timezone.utc).timestamp()yerine kullanabilirsiniz .
jfs

@JFSebastian - iyi bir nokta. Ancak ithalata eklemek istemedim, bu yüzden değiştirdim utcnow(). Saat dilimi UTC olarak ayarlanmış makinelerde çalışmaya alışkınım, ancak bu kod snippet'inde varsayılmamalıdır.
Tim Tisdall

139

Sadece bunu buldum ve daha da kısa.

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

12
Bu soruya cevap vermiyor.
Jesse Dhillon

22
@JesseDhillon soruyu cevaplar (UNIX zaman damgasını gelecekte 5 dakika yapın), başlığı değil.
dbr

3
time.time()geri ayarlanabilir. Gelecekte 5 dakika sonra bir "Sona Erer" değeri oluşturmak için time.monotonic(), kullanım durumunuza bağlı olarak analoga ihtiyacınız olabilir .
jfs

@ jf-sebastian time.monotonic () bir UNIX zaman damgası döndürmez, tanımlanmamış bir referans noktası olan bir zaman damgası döndürür.
rspeer

@rspeer: evet, belgelerin dediği gibi , yalnızca ardışık aramalar arasındaki fark geçerlidir. İster monotonickullanılabilir kullanımınız durum örneğin bağlıdır, subprocessmodül uygulamak için kullanabilirsiniz yapar timeoutseçeneği.
jfs

57

İhtiyacın olan şey bu:

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

Bu nasıl farklıdır veya sağlanan 'Cat Plus Plus' a ekler mi?
David

3
EG bu, "Plus, Unix zaman damgasına Python datetime" sorusunun yanıtını verirken Cat Plus Plus, "Unix zaman damgasına 5 dakika içinde olacak" Python datetime "sorusunu yanıtladı. Yani bu temiz ve açık.
koşu.

@ running.t: hatırlatıyor: "her sorunun basit, açık ve yanlış bir çözümü var". İle ilgili olası sorunlaramktime(dt.timetuple()) bakın . datetime.now(timezone.utc).timestamp()@Tim Tisdall tarafından sağlanan Python 3.3+ çözümdür. Aksi takdirde (dt - epoch).total_seconds()kullanılabilir .
jfs

@JFSebastian Tüm hesaplamanın yerel saatte yapılmasını gerçekten istiyorsam ne olur? Örneğin böyle. yerel bir saat olduğunu bildiği saf bir dizeyi ayrıştırmak ve belirli bir zamanda geçerli DST olup olmadığına karar vermek için?
n611x007

1
@ naxa: evet, bazı yerel zamanlar belirsiz veya yok. Ayrıca saat dilimi ofseti DST dışındaki nedenlerle farklı olabilir (doğru ofseti bulmak için pytz gibi bir tz veritabanına ihtiyacınız vardır). Yerel zaman, yerel politikacının ne düşündüğünün ne olduğu anlamına gelir, yani zamanı ölçmek için iyi bir fikirdir, oldukça düzensiz olabilir.
jfs

48

Format dizesini datetime.strftimekullanarak saati Epoch formunda almak için kullanabilirsiniz %s:

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

Not: Bu yalnızca linux altında çalışır ve bu yöntem saat dilimleriyle çalışmaz.


32
Bu biraz belgelenmemiş bir davranıştır ( python.org/doc/current/library/datetime.html ). Linux altında çalışıyor ve win32 (üretiyor ValueError: Invalid format string) altında çalışmıyor gibi görünüyor .
Antony Hatchkins

3
Bu yöntem zaman dilimleri ile çalışmaz. Saat diliminin değiştirilmesi aynı sonucu datetime (2013,12,7, tzinfo = timezone ("America / Chicago")). Strftime ("% s") 1386385200 datetime (2013,12,7, tzinfo = timezone ("Europe / Riga ")). Strftime ("% s ") 1386385200
Martins Balodis


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

4

Anahtar, dönüştürmeye başlamadan önce kullandığınız tüm tarihlerin utc saat diliminde olduğundan emin olmaktır. Bkz. Http://pytz.sourceforge.net/Bunu nasıl doğru bir şekilde yapacağınızı öğrenmek için adresine . Utc'ye normalleştirerek, gün ışığından yararlanma geçişlerinin belirsizliğini ortadan kaldırmış olursunuz. Daha sonra, unix çağından mesafeyi hesaplamak için timedelta'yı güvenle kullanabilir ve ardından saniye veya milisaniyeye dönüştürebilirsiniz.

Ortaya çıkan unix zaman damgasının kendisinin UTC saat diliminde olduğunu unutmayın. Zaman damgasını yerelleştirilmiş bir saat diliminde görmek istiyorsanız, başka bir dönüşüm yapmanız gerekir.

Ayrıca, bunun yalnızca 1970'den sonraki tarihler için geçerli olacağını da unutmayın.

   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
not: "Yerelleştirilmiş bir saat dilimindeki [unix] zaman damgasını" anlamıyorum. Zaman damgası aynıdır (o zamandan beri geçen saniye 1970-01-01 00:00:00+00:00). Yerel saat diliminde saf bir tarih nesnesi almak için:datetime.fromtimestamp(ts)
jfs

4

Aşağıdakiler yukarıdaki cevaplara dayanmaktadır (artı milisaniye için bir düzeltme) ve datetime.timestamp()zaman dilimleri kullanıldığında 3.3'ten önce Python 3 için öykünür .

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

Soruyu sorulduğu gibi kesinlikle cevaplamak için:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampbasit tarihin bir parçasıdır . Ancak bu paketi kullanıyorsanız muhtemelen şunu yazabilirsiniz:

SimpleDate(my_datetime).timestamp + 5 * 60

my_datetime için daha birçok biçimi / türü işler.


5 dakika eklemek için (5 * 60) eklememelisiniz? Ben sadece 5 eklemek zaman damgasına sadece 5 saniye eklediğini düşünüyorum.
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

timedelta.total_seconds()Python-2.7 + üzerinde çalışan çözümlerin olduğunu unutmayın . calendar.timegm(future.utctimetuple())Python'un daha düşük sürümleri için kullanın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.