Python'da dize tarihini zaman damgasına dönüştürme


220

Biçimdeki bir dizeyi "%d/%m/%Y"zaman damgasına nasıl dönüştürebilirim ?

"01/12/2011" -> 1322697600

İkinci sayı nedir? Unix Epoch zamanı?
Hasteur

4
@ Hasret, evet. İkinci sayı, unix çağının başlangıcı ile belirtilen tarih arasında geçen saniye sayısını temsil eder. Bu biçime POSIX zamanı da denir.
eikonomega

Yanıtlar:


318
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0

10
yerel saat diliminde 01/12/2011 gece yarısı varsayılır. Giriş UTC'deyse; kullanabilirsiniz calendar.timegm()veya.toordinal()
jfs

50
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp()biraz daha kısa
timdiels

11
@timdiels: tekrar. açık bir saat dilimi belirtilmezse UTC yerine yerel saati .timestamp()varsayar . Yanıttaki kod yalnızca yerel saat diliminin sıfır utc ofsetine sahip olduğu bir bilgisayarda çalışır (beklenen üretimler ). 1322697600
jfs

7
bu çalışmaz: datetime.datetime.strptime ("2014: 06: 28 11:53:21", "% Y:% m:% d% H:% M:% S"). timestamp () Traceback () en son çağrı)): <module> AttributeError: '
dastetime.datetime

5
@ZdenekMaxa datetime.timestamp () yalnızca python> = 3.3 sürümleri için kullanılabilir. docs.python.org/3/whatsnew/3.3.html
jones

49

Ben ciso8601datetime'ın çalma süresinden 62 kat daha hızlı kullanıyorum .

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

Burada daha fazla bilgi edinebilirsiniz .


2
Bu harika bir öneri. Ben sadece kullandım ve benim yürütme kapalı TON zaman traş.
David

3
Tanrım bu hızlı
Hews

3
Ve +1, zaman dizesi biçiminin ne olduğunu açıklamamı gerektirmediği için.
gowenfawr

40

Dizeyi bir tarih nesnesine dönüştürmek için:

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()

Tarih nesnesini POSIX zaman damgasına dönüştürmenin yolu saat dilimine bağlıdır. Gönderen dönüştürme datetime.datePython UTC zaman damgasına :

  • date nesnesi UTC'de gece yarısını temsil eder

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
    
  • date nesnesi yerel saatte gece yarısını temsil eder

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

UTC'de gece yarısı ve yerel saat aynı saat örneği olmadığı sürece zaman damgaları farklıdır.


Ben bu yazı örnekleri çalıştırdığınızda, ben hatayı alıyorum: NameError: name 'wckCalendar' is not defined. Windows 32 bit makinede Python 3.4.1 kullanıyorum. Herhangi bir fikir? Teşekkürler.
sedeh

1
@sedeh yayında wckCalendar yok. Kodunuzu kontrol edin.
jfs

@JFSebastian Kesinlikle ve doğrudan wckCalendar aramaya çalışmıyordum. Sadece hata mesajında ​​görünür. Benim sonrası bakın burada sorunu tartışırken.
sedeh

1
@ törzsmókus: Cevap yanlışsa, ne kadar okunabilir olduğu önemli değil.
jfs

1
@ törzsmókus: cevabıma bak: iki farklı sayı üretebilir . Cevabınız hangisini belirtmeden bir rakam üretir .
jfs


21

Cevap, giriş tarihi saat diliminize de bağlıdır. Tarih yerel bir tarih ise, o zaman katrielalex dedi gibi mktime () kullanabilirsiniz - sadece neden bu kısa sürüm yerine datetime kullandığını görmüyorum:

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

Ama muhtemelen farklı bir TZ'de olduğum için sonucumun kendisinden farklı olduğunu gözlemleyin (ve sonuç saat dilimi içermeyen UNIX zaman damgasıdır)

Şimdi giriş tarihi zaten UTC ise, doğru çözüm olduğuna inanıyorum daha:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600

Bence bu daha iyi. Hem 'zaman'ı hem de' tarih saatini 'içe aktarmaya gerek yoktur.
kennyut

17

Basitçe kullanın datetime.datetime.strptime:

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

Sonuç:

1322697600

Yerel saat dilimi yerine UTC kullanmak için .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()

Tam bir anwser için sadece python 3.3+ için geçerli olduğunu söylemelisiniz
Eduardo

İlk örnekte sonuç bir floatdeğilint
CONvid19

6

İlk önce dizeyi bir struct_time biçimine dönüştürmek için strptime sınıfına ihtiyacınız vardır.

Sonra sadece şamandıra almak için mktime kullanın .


6

Bu cevapların birçoğu, tarihin başlamak için naif olduğunu düşünmekle uğraşmıyor

Doğru olmak için, önce naif tarihi bir saat diliminde bilinçli hale getirmeniz gerekir

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

Ayrıca:

Kullanarak dikkatli olun pytziçin tzinfobir de datetime.datetimepek çok saat dilimlerinde için YAPAR DEĞİL İŞ. Pytz saat dilimi ile tarih saatine bakın . Tzinfo'nun nasıl ayarlandığına bağlı olarak farklı ofset

# 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


6

Dateutil öneririm :

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()

Bu yanlış. OP zaman "%d/%m/%Y"biçiminde bekliyor . Karşılaştırma: dateutil.parser.parse("01/02/2001")vedatetime.strptime("01/02/2001", "%d/%m/%Y")
jfs

teşekkürler @jfs, iyi yakalayın. Cevabımı buna göre güncelledim. (Amerikalı olmayan olarak, mantıksız M / D / Y biçiminin ayrıştırıcı için varsayılan olduğunu
düşünmezdim

1
1322697600yerel saat diliminiz UTC olmadığı sürece beklenen değeri üretmez . Bkz 2014 yorumumu
jfs

4

Oldukça verimli görünüyor:

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

1.61 µs ± 120 ns döngü başına (ortalama ± std. 7 çalıştırma, her biri 100000 döngü)


Ne var datetimeişlevi? datetimedan datetimekütüphane desteklemiyor.timestamp()
Joooeey

@Joooeey: Python 3.3 veya daha yeni sürümlerde . Soru gönderildiğinde mevcut değildi, ancak 2012 Eylül ayından bu yana kullanılabilir.
ShadowRanger

0

datetime.timestamp (datetime instanse) kullanın, datetime örneği saat dilimi bilgilerini içerir, bu nedenle zaman damgası standart bir utc zaman damgası olur. datetime değerini zaman-dizisine dönüştürürseniz, saat dilimini kaybeder, dolayısıyla sonuç hata olur. bir arayüz sağlamak istiyorsanız, şöyle yazmalısınız: int (datetime.timestamp (time_instance)) * 1000



0

isoformat'a dönüştürebilirsiniz

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

-1

UNIX Epoch zamanını almak için basit bir işlev.

NOT : Bu işlev, giriş tarihi saatinin UTC biçiminde olduğunu varsayar ( Buradaki yorumlara bakın ).

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())

Kullanımı :

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600
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.