Przetwarzanie niezerowych datowników z wypełnieniem w Pythonie


84

Chcę uzyskać daty z sygnatur czasowych, takich jak: 3/1/2014 9:55with datetime.strptimelub coś równoważnego.

Miesiąc, dzień miesiąca i godzina nie są wypełnione zerami, ale nie wydaje się, aby wymieniono tutaj dyrektywę formatowania, która byłaby w stanie przeanalizować to automatycznie.

Jakie jest najlepsze podejście, aby to zrobić? Dzięki!

Odpowiedzi:


131

strptimejest w stanie analizować wartości bez dopełnienia. Fakt, że są one odnotowane jako dopełniane w tabeli kodów formatowania, odnosi się do strftimewyjścia. Możesz więc po prostu użyć

datetime.strptime(datestr, "%m/%d/%Y %H:%M")

8

strptimeis nie wymaga wartości uzupełnianych 0. Zobacz przykład poniżej

datetime.strptime("3/1/2014 9:55", "%m/%d/%Y %H:%M")
output:   datetime.datetime(2014, 3, 1, 9, 55)

2

Na wypadek, gdyby ta odpowiedź pomogła komuś innemu - przyszedłem tutaj, myśląc, że mam problem z wypełnieniem zerowym, ale tak naprawdę było to z 12:00 vs 00:00 i %Iformatyzatorem.

%IFormatujący ma pasujące do godziny 12-godzinny zegara, ewentualnie zostaje wypełniony zerami. Ale w zależności od źródła danych możesz otrzymać dane, które mówią, że północ lub południe to w rzeczywistości zero, np .:

>>> datetime.strptime('2015/01/01 0:12am', "%Y/%m/%d %I:%M%p")
ValueError: time data '2015/01/01 0:12am' does not match format '%Y/%m/%d %I:%M'

To, czego strptimetak naprawdę chciał, to 12, a nie zero:

>>> datetime.strptime('2015/01/01 12:12am', "%Y/%m/%d %I:%M%p")
datetime.datetime(2015, 1, 1, 0, 12)

Ale nie zawsze kontrolujemy nasze źródła danych! Moim rozwiązaniem dla tego skrajnego przypadku było złapanie wyjątku, spróbuj przeanalizować go za pomocą %H, z szybkim sprawdzeniem, czy znajdujemy się w przypadku skrajnym, w którym myślimy, że się znajdujemy.

def get_datetime(string):
    try:
        timestamp = datetime.strptime(string, "%m/%d/%Y %I:%M%p")
    except ValueError:
        # someone used zero for midnight?
        timestamp = datetime.strptime(string, "%m/%d/%Y %H:%M%p")
        assert string.lower().endswith('am')
        assert timestamp.hour == 0
    return timestamp

0:12amto nieprawidłowe dane wejściowe. Tak powinno być 12:12am. 11:59 pmnastępuje 12:00 am, nie 0:00am. Może istnieć wiele sposobów dostarczania danych w nieprawidłowym formacie czasu, np. Dane wejściowe mogą zawierać dwucyfrowy rok ( %y) zamiast czterocyfrowego roku ( %Y) lub można zamienić dzień / miesiąc (w %m/%dporównaniu z %d/%m) itp. przypadek miesiąca może być niejednoznaczny, np. czy 2015/10/12jest to „12 października” czy „10 grudnia”? btw, powinieneś używać %Y/%m/%dzamiast, %m/%d/%Yaby dopasować swój format wejściowy.
jfs

Dzięki, zdaję sobie sprawę, że to nieprawidłowe dane wejściowe, jak mówię, pochodzi ze źródła danych, którego nie kontroluję.
hwjp

2

Możesz zobaczyć dokument strftime tutaj, ale w rzeczywistości nie wszystkie działają dobrze na wszystkich platformach , na przykład ,%-d,%-mnie działają na win7 przez pythona 2.7 , więc możesz to zrobić w ten sposób

>>> date_str = '{d.year}-{d.month}-{d.day}'.format(d=datetime.datetime.now())  
>>> print(date_str)
2016-5-23

1
W rodzimym systemie Windows hash jest zastępowany przez myślnik: %#d, %#m. Ale zarówno mody myślnikowe, jak i haszujące są potrzebne tylko w formatowaniu ciągów ( strftime), a nie w parsowaniu ( strptime).
Nuno André

1

Sposób bez wzorca to dateutil.parsemoduł use , który pozwala na parsowanie popularnych formatów dat, nawet jeśli nie wiesz, jakich obecnie używa
Ex:

>>> import dateutil.parser
>>> 
>>> utc_time     = '2014-08-13T00:00:00'
>>> verbose_time = '13-Aug-2014'
>>> some_locale  = '3/1/2014 9:55'
>>> dateutil.parser.parse(utc_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(verbose_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(some_locale)
datetime.datetime(2014, 3, 1, 9, 55)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.