Konwertuj datę ciągu na znacznik czasu w Pythonie

219

Jak przekonwertować ciąg w formacie "%d/%m/%Y"na znacznik czasu?

"01/12/2011" -> 1322697600
Shankar Cabus
źródło
Jaki jest drugi numer? Czas epoki uniksowej?
Hasteur
4
@Hasteur, tak. Druga liczba reprezentuje liczbę sekund, które upłynęły między początkiem epoki uniksowej a określoną datą. Ten format jest również określany jako czas POSIX.
eikonomega

Odpowiedzi:

317
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
Katriel
źródło
10
zakłada północ 01.12.2011 w lokalnej strefie czasowej. Jeśli dane wejściowe są w UTC; możesz użyć calendar.timegm()lub.toordinal()
jfs
50
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp()jest nieco krótszy
timdiels
11
@timdiels: ponownie. .timestamp()zakłada czas lokalny zamiast UTC, jeśli nie podano wyraźnej strefy czasowej. Kod w odpowiedzi działa (tworzy oczekiwany 1322697600) tylko na komputerze, na którym lokalna strefa czasowa ma zerowe przesunięcie utc.
jfs
7
to nie działa: datetime.datetime.strptime („2014: 06: 28 11:53:21”, „% Y:% m:% d% H:% M:% S”). timestamp () Traceback ( ostatnie wywołanie ostatnie): Plik „<stdin>”, wiersz 1, w <module> AttributeError: Obiekt „datetime.datetime” nie ma atrybutu „timestamp”
Zdenek Maxa
5
@ZdenekMaxa datetime.timestamp () dostępny tylko dla wersji python> = 3.3. docs.python.org/3/whatsnew/3.3.html
joni jones
48

Używam ciso8601, co jest 62 razy szybsze niż czas datetime.

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

Możesz dowiedzieć się więcej tutaj .

Eyal Ch
źródło
2
to fantastyczna sugestia. właśnie go użyłem i ogoliłem MNÓSTWO czasu na egzekucję.
David
3
Mój Boże, to jest szybkie
Hews
3
I +1 za to, że nie potrzebuję przeliterować, jaki jest format ciągu czasu.
gowenfawr
40

Aby przekonwertować ciąg na obiekt daty:

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

Sposób konwersji obiektu daty na znacznik czasu POSIX zależy od strefy czasowej. Od konwersji datetime.datedo znacznika czasu UTC w Pythonie :

  • Obiekt daty reprezentuje północ w UTC

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
    
  • Obiekt daty reprezentuje północ w czasie lokalnym

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

Znaczniki czasu są różne, chyba że północ w UTC i czas lokalny to ta sama instancja czasu.

jfs
źródło
Kiedy uruchomić przykłady w tym poście, pojawia się błąd: NameError: name 'wckCalendar' is not defined. Używam Python 3.4.1 na maszynie z systemem Windows 32 bity. Dowolny pomysł? Dzięki.
poniedziałek
1
@sedeh w poście nie ma wckCalendar. Sprawdź swój kod.
jfs
@JFSebastian Dokładnie, a ja nie próbowałem zadzwonić bezpośrednio do wckCalendar. Po prostu pojawia się w komunikacie o błędzie. Zobacz mój post tutaj omawiający problem.
poniedziałek
1
@ törzsmókus: Jeśli odpowiedź jest błędna, nie ma znaczenia, jak jest czytelna.
jfs
1
@ törzsmókus: spójrz na moją odpowiedź: może dać dwie różne liczby. Twoja odpowiedź tworzy jeden numer, nie wspominając, który.
jfs
30
>>> int(datetime.datetime.strptime('01/12/2011', '%d/%m/%Y').strftime("%s"))
1322683200
San4ez
źródło
10
"%s"nie jest obsługiwany przez Python . To nie jest przenośne.
jfs,
Liczy się czytelność. Zobacz moją odpowiedź dotyczącą dateutil, aby uzyskać rozwiązanie bardziej czytelne dla człowieka.
törzsmókus
21

Odpowiedź zależy również od strefy czasowej wejścia. Jeśli twoja data jest datą lokalną, możesz użyć mktime (), jak powiedział Katrielalex - tylko nie rozumiem, dlaczego użył datetime zamiast tej krótszej wersji:

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

Ale zauważ, że mój wynik jest inny niż jego, ponieważ prawdopodobnie jestem w innym TZ (a wynikiem jest wolny od strefy czasowej znacznik czasu UNIX)

Teraz, jeśli data wejścia jest już w UTC, to uważam, że właściwym rozwiązaniem jest:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600
Nowakus
źródło
Myślę, że tak jest lepiej. Nie ma potrzeby importowania zarówno „godziny”, jak i „daty i godziny”.
kennyut
17

Po prostu użyj datetime.datetime.strptime:

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

Wynik:

1322697600

Aby użyć UTC zamiast lokalnej strefy czasowej .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()
nm111
źródło
Aby uzyskać pełną odpowiedź, musisz powiedzieć, że jest ona ważna tylko dla Pythona 3.3+
Eduardo
W pierwszym przykładzie wynikiem jest floatnieint
CONVid19
6

Najpierw musisz klasę strptime, aby przekonwertować ciąg do formatu struct_time.

Następnie wystarczy użyć stamtąd mktime, aby uzyskać pływak.

Cryptite
źródło
6

Wiele z tych odpowiedzi nie przeszkadza, że ​​data jest naiwna na początek

Aby być poprawnym, musisz najpierw ustawić naiwną datę jako datę i strefę czasową

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

Również:

Bądź ostrożny, używając pytzdo tzinfow datetime.datetimepracy nie dla wielu stref czasowych. Zobacz datetime w strefie czasowej pytz. Różne przesunięcie w zależności od ustawienia tzinfo

# 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
źródło
6

Sugerowałbym dateutil :

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()
törzsmókus
źródło
To jest złe. OP oczekuje czasu w "%d/%m/%Y"formacie. Porównaj: dateutil.parser.parse("01/02/2001")idatetime.strptime("01/02/2001", "%d/%m/%Y")
jfs
dzięki @jfs, dobry połów. Zaktualizowałem odpowiednio swoją odpowiedź. (jako nie-Amerykanin nie
sądziłbym,
1
nie daje oczekiwanego, 1322697600chyba że twoją lokalną strefą czasową jest UTC. Zobacz mój komentarz od 2014
JFS
4

Wydaje się być dość wydajny:

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

1,61 µs ± 120 ns na pętlę (średnia ± odchylenie standardowe z 7 serii, każda 100000 pętli)

Gerard
źródło
Jaka jest datetimefunkcja datetimez datetimebiblioteki nie obsługuje.timestamp()
Joooeey
@Joooeey: Tak, w Pythonie 3.3 lub nowszym . Nie było dostępne, gdy pytanie zostało opublikowane, ale jest dostępne od września 2012 r.
ShadowRanger
0

wystarczy użyć datetime.timestamp (instancja datetime), instancja datetime zawiera informację o strefie czasowej, więc znacznik czasu będzie standardowym znacznikiem czasu utc. jeśli przekształcisz datetime w harmonogram, straci strefę czasową, więc wynikiem będzie błąd. jeśli chcesz zapewnić interfejs, powinieneś napisać w ten sposób: int (datetime.timestamp (instancja_czasu)) * 1000

użytkownik6689187
źródło
0

możesz przekonwertować na izoformat

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
źródło
-1

Prosta funkcja pozwalająca uzyskać czas UNIX Epoki.

UWAGA : Ta funkcja zakłada, że ​​data i godzina wprowadzenia są w formacie UTC (patrz komentarze tutaj).

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

Zastosowanie :

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600
gihanchanuka
źródło