Pertanyaan Mengubah string menjadi datetime


Singkat dan sederhana. Saya punya daftar besar waktu-tanggal seperti ini sebagai string:

Jun 1 2005  1:33PM
Aug 28 1999 12:00AM

Saya akan mendorong ini kembali ke bidang datetime tepat dalam database sehingga saya perlu sihir mereka ke objek datetime nyata.

Bantuan apa pun (meskipun hanya tendangan ke arah yang benar) akan dihargai.

Edit: Ini akan melalui ORM Django sehingga saya tidak dapat menggunakan SQL untuk melakukan konversi pada insert.


1458
2018-01-21 18:00


asal


Jawaban:


datetime.strptime adalah rutin utama untuk menguraikan string ke dalam datetimes. Ini dapat menangani segala macam format, dengan format yang ditentukan oleh string format yang Anda berikan:

from datetime import datetime

datetime_object = datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')

Hasilnya datetime objek adalah naif-zona waktu.

Tautan:

Catatan:

  • strptime = "waktu string parse"
  • strftime = "format string waktu"
  • Ucapkan dengan keras hari ini & Anda tidak perlu mencarinya lagi dalam 6 bulan.

2396
2018-01-21 18:08



Gunakan pihak ketiga dateutil Perpustakaan:

from dateutil import parser
dt = parser.parse("Aug 28 1999 12:00AM")

Ini dapat menangani sebagian besar format tanggal, termasuk format yang perlu Anda parse. Ini lebih mudah daripada strptime karena dapat menebak format yang tepat sebagian besar waktu.

Ini sangat berguna untuk menulis tes, di mana keterbacaan lebih penting daripada kinerja.

Anda dapat menginstalnya dengan:

pip install python-dateutil

623
2018-01-22 18:27



Periksa strptime dalam waktu modul. Ini adalah kebalikan dari strftime.

$ python
>>> import time
>>> time.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
time.struct_time(tm_year=2005, tm_mon=6, tm_mday=1,
                 tm_hour=13, tm_min=33, tm_sec=0,
                 tm_wday=2, tm_yday=152, tm_isdst=-1)

460
2018-01-21 18:07



Saya telah menyusun sebuah proyek yang dapat mengubah beberapa ekspresi yang benar-benar rapi. Periksa timesting.

Berikut beberapa contoh di bawah ini:

pip install timestring
>>> import timestring
>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm')
<timestring.Date 2015-08-15 20:40:00 4491909392>
>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm').date
datetime.datetime(2015, 8, 15, 20, 40)
>>> timestring.Range('next week')
<timestring.Range From 03/10/14 00:00:00 to 03/03/14 00:00:00 4496004880>
>>> (timestring.Range('next week').start.date, timestring.Range('next week').end.date)
(datetime.datetime(2014, 3, 10, 0, 0), datetime.datetime(2014, 3, 14, 0, 0))

87
2018-03-02 14:22



Ingat ini dan Anda tidak perlu bingung dalam konversi datetime lagi.

String ke objek datetime = strptime

objek datetime ke format lain = strftime

Jun 1 2005 1:33PM

sama dengan

%b %d %Y %I:%M%p

% b Bulan sebagai nama disingkat lokal (Jun)

% d Hari dalam sebulan sebagai angka desimal nol-empuk (1)

% Y Tahun dengan abad sebagai angka desimal (2015)

% I Hour (jam 12-jam) sebagai angka desimal nol-empuk (01)

% M Menit sebagai angka desimal nol-empuk (33)

% p Lokal setara dengan AM atau PM (PM)

jadi Anda perlu strptime i-e converting string untuk

>>> dates = []
>>> dates.append('Jun 1 2005  1:33PM')
>>> dates.append('Aug 28 1999 12:00AM')
>>> from datetime import datetime
>>> for d in dates:
...     date = datetime.strptime(d, '%b %d %Y %I:%M%p')
...     print type(date)
...     print date
... 

Keluaran

<type 'datetime.datetime'>
2005-06-01 13:33:00
<type 'datetime.datetime'>
1999-08-28 00:00:00

Bagaimana jika Anda memiliki format tanggal yang berbeda, Anda dapat menggunakan panda atau dateutil.parse

>>> import dateutil
>>> dates = []
>>> dates.append('12 1 2017')
>>> dates.append('1 1 2017')
>>> dates.append('1 12 2017')
>>> dates.append('June 1 2017 1:30:00AM')
>>> [parser.parse(x) for x in dates]

Keluaran

[datetime.datetime(2017, 12, 1, 0, 0), datetime.datetime(2017, 1, 1, 0, 0), datetime.datetime(2017, 1, 12, 0, 0), datetime.datetime(2017, 6, 1, 1, 30)]

33
2017-12-10 13:00



Banyak cap waktu memiliki zona waktu tersirat. Untuk memastikan bahwa kode Anda akan bekerja di setiap zona waktu, Anda harus menggunakan UTC secara internal dan melampirkan zona waktu setiap kali objek asing memasuki sistem.

Python 3.2+:

>>> datetime.datetime.strptime(
...     "March 5, 2014, 20:13:50", "%B %d, %Y, %H:%M:%S"
... ).replace(tzinfo=datetime.timezone(datetime.timedelta(hours=-3)))

30
2018-03-06 11:53



Sesuatu yang tidak disebutkan di sini dan berguna: menambahkan akhiran untuk hari itu. Saya memisahkan logika sufiks sehingga Anda dapat menggunakannya untuk nomor apa pun yang Anda suka, bukan hanya tanggal.

import time

def num_suffix(n):
    '''
    Returns the suffix for any given int
    '''
    suf = ('th','st', 'nd', 'rd')
    n = abs(n) # wise guy
    tens = int(str(n)[-2:])
    units = n % 10
    if tens > 10 and tens < 20:
        return suf[0] # teens with 'th'
    elif units <= 3:
        return suf[units]
    else:
        return suf[0] # 'th'

def day_suffix(t):
    '''
    Returns the suffix of the given struct_time day
    '''
    return num_suffix(t.tm_mday)

# Examples
print num_suffix(123)
print num_suffix(3431)
print num_suffix(1234)
print ''
print day_suffix(time.strptime("1 Dec 00", "%d %b %y"))
print day_suffix(time.strptime("2 Nov 01", "%d %b %y"))
print day_suffix(time.strptime("3 Oct 02", "%d %b %y"))
print day_suffix(time.strptime("4 Sep 03", "%d %b %y"))
print day_suffix(time.strptime("13 Nov 90", "%d %b %y"))
print day_suffix(time.strptime("14 Oct 10", "%d %b %y"))​​​​​​​

21
2017-10-14 00:13



Berikut adalah dua solusi menggunakan Pandas untuk mengonversi tanggal yang diformat sebagai string ke dalam objek datetime.date.

import pandas as pd

dates = ['2015-12-25', '2015-12-26']

# 1) Use a list comprehension.
>>> [d.date() for d in pd.to_datetime(dates)]
[datetime.date(2015, 12, 25), datetime.date(2015, 12, 26)]

# 2) Convert the dates to a DatetimeIndex and extract the python dates.
>>> pd.DatetimeIndex(dates).date.tolist()
[datetime.date(2015, 12, 25), datetime.date(2015, 12, 26)]

Pengaturan waktu

dates = pd.DatetimeIndex(start='2000-1-1', end='2010-1-1', freq='d').date.tolist()

>>> %timeit [d.date() for d in pd.to_datetime(dates)]
# 100 loops, best of 3: 3.11 ms per loop

>>> %timeit pd.DatetimeIndex(dates).date.tolist()
# 100 loops, best of 3: 6.85 ms per loop

Dan di sini adalah cara mengonversi contoh tanggal-waktu asli OP:

datetimes = ['Jun 1 2005  1:33PM', 'Aug 28 1999 12:00AM']

>>> pd.to_datetime(datetimes).to_pydatetime().tolist()
[datetime.datetime(2005, 6, 1, 13, 33), 
 datetime.datetime(1999, 8, 28, 0, 0)]

Ada banyak pilihan untuk mengkonversi dari string ke Pandas Timestamps menggunakan to_datetime, jadi periksa dokumen jika Anda butuh sesuatu yang istimewa.

Demikian juga, cap waktu memiliki banyak properti dan metode yang bisa diakses selain .date


19
2017-12-20 03:03



Django Timezone menyadari contoh objek datetime.

import datetime
from django.utils.timezone import get_current_timezone
tz = get_current_timezone()

format = '%b %d %Y %I:%M%p'
date_object = datetime.datetime.strptime('Jun 1 2005  1:33PM', format)
date_obj = tz.localize(date_object)

Konversi ini sangat penting untuk Django dan Python ketika Anda memilikinya USE_TZ = True:

RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.

12
2017-11-20 17:58



In [34]: import datetime

In [35]: _now = datetime.datetime.now()

In [36]: _now
Out[36]: datetime.datetime(2016, 1, 19, 9, 47, 0, 432000)

In [37]: print _now
2016-01-19 09:47:00.432000

In [38]: _parsed = datetime.datetime.strptime(str(_now),"%Y-%m-%d %H:%M:%S.%f")

In [39]: _parsed
Out[39]: datetime.datetime(2016, 1, 19, 9, 47, 0, 432000)

In [40]: assert _now == _parsed

11
2018-01-19 07:48