Mengkonversi string ke datetime

I've punya daftar besar dari saat-saat seperti ini sebagai string:

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

I'm akan mendorong mereka kembali ke tepat datetime bidang dalam database, jadi saya perlu untuk sihir mereka ke real datetime benda-benda.

Ini akan melalui Django's ORM sehingga saya bisa't menggunakan SQL untuk melakukan konversi pada insert.

Mengomentari pertanyaan (2)
Larutan

datetime.strptime adalah rutinitas utama untuk parsing string ke datetimes. Hal ini dapat menangani berbagai macam format, dengan format yang ditentukan oleh format string yang anda berikan:

from datetime import datetime

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

Yang dihasilkan datetime objek timezone-naif.

Link:

Catatan:

  • strptime = "string mengurai waktu"
  • strftime = "string format waktu"
  • Ucapkan dengan keras hari ini & anda tidak't harus mencari lagi dalam 6 bulan.
Komentar (14)

Gunakan pihak ketiga dateutil perpustakaan:

from dateutil import parser
parser.parse("Aug 28 1999 12:00AM")  # datetime.datetime(1999, 8, 28, 0, 0)

Hal ini dapat menangani sebagian besar format tanggal, termasuk salah satu yang anda butuhkan untuk mengurai. It's lebih nyaman dari strptime seperti itu bisa menebak format yang benar sebagian besar waktu.

It's sangat berguna untuk menulis tes, dimana pembacaan lebih penting dari kinerja.

Anda dapat menginstalnya dengan:

pip install python-dateutil
Komentar (8)

Check out strptime pada 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)
Komentar (6)

Saya telah mengumpulkan sebuah proyek yang dapat mengkonversi beberapa benar-benar rapi ekspresi. Check out timestring.

Berikut ini adalah beberapa contoh di bawah ini:

pip menginstal timestring

>>> import timestring
>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm')

>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm').date
datetime.datetime(2015, 8, 15, 20, 40)
>>> timestring.Range('next week')

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

Ingat ini dan anda didn't perlu bingung dalam datetime konversi lagi.

String datetime objek = strptime

datetime objek ke format lain = strftime

Jun 1 2005 1:33PM

adalah sama dengan

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

%b Bulan sebagai lokal disingkat nama(Jun)

%d Hari bulan sebagai zero-padded angka desimal(1)

%Per Tahun dengan century sebagai angka desimal(2015)

%I Jam (12 jam) sebagai zero-padded angka desimal(01)

%M Menit sebagai zero-padded angka desimal(33)

%p Lokal setara baik AM atau PM(PM)

jadi, anda perlu strptime i-e mengkonversi 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
... 

Output


2005-06-01 13:33:00

1999-08-28 00:00:00

Bagaimana jika anda memiliki format yang berbeda dari tanggal anda dapat menggunakan panda atau dateutil.mengurai

>>> 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]

OutPut

[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)]
Komentar (2)

Banyak waktu telah tersirat timezone. Untuk memastikan bahwa kode anda akan bekerja di setiap zona waktu, anda harus menggunakan UTC internal dan melampirkan timezone setiap kali benda 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)))
Komentar (1)

Di Python >= 3.7.0,

untuk mengkonversi YYYY-MM-DD string datetime objek, datetime.fromisoformat dapat digunakan.

>>> from datetime import datetime

>>> date_string = "2012-12-12 10:10:10"
>>> print (datetime.fromisoformat(date_string))
>>> 2012-12-12 10:10:10
Komentar (0)

Berikut adalah dua solusi menggunakan Panda untuk mengkonversi tanggal yang diformat sebagai string ke datetime.saat benda-benda.

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

Timing

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 bagaimana untuk mengkonversi OP's asli tanggal-waktu contoh:

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 mengubah dari string ke Panda Cap menggunakan to_datetime, jadi cek docs jika anda perlu sesuatu yang istimewa.

Demikian juga, Waktu telah banyak properties dan metode yang dapat diakses di samping .tanggal

Komentar (0)

Sesuatu yang isn't yang disebutkan di sini dan lebih berguna: menambahkan akhiran hari. Aku dipisahkan akhiran logika sehingga anda dapat menggunakannya untuk setiap nomor yang anda suka, tidak 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 
Komentar (0)

Saya pribadi suka solusi menggunakan parser modul, yang merupakan Jawaban kedua pertanyaan ini dan lebih indah, karena anda don't harus membangun string literal untuk membuatnya bekerja. TAPI, salah satu kelemahan adalah bahwa itu adalah 90% lebih lambat dari jawaban yang diterima dengan strptime.

from dateutil import parser
from datetime import datetime
import timeit

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

print(timeit.timeit(stmt=dt, number=10**5))
print(timeit.timeit(stmt=strptime, number=10**5))
>10.70296801342902
>1.3627995655316933

Selama anda tidak melakukan hal ini juta kali lagi dan lagi, saya masih berpikir parser metode ini lebih mudah dan akan menangani sebagian besar waktu format secara otomatis.

Komentar (0)

Django Timezone menyadari datetime objek contoh.

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 memiliki USE_TZ = True:

RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
Komentar (1)
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
Komentar (0)

Membuat sebuah utilitas kecil yang berfungsi seperti:

def date(datestr="", format="%Y-%m-%d"):
    from datetime import datetime
    if not datestr:
        return datetime.today().date()
    return datetime.strptime(datestr, format).date()

Ini cukup fleksibel:

  • Jika anda don't lulus argumen itu akan kembali hari ini's upload.
  • Ada's upload format default yang anda dapat menimpa.
  • Anda dapat dengan mudah memodifikasinya untuk kembali ke datetime.
Komentar (1)

panah menawarkan banyak fungsi yang berguna untuk tanggal dan waktu. Ini sedikit kode yang memberikan jawaban atas pertanyaan dan menunjukkan panah itu juga mampu format tanggal dengan mudah dan menampilkan informasi lokal lainnya.

>>> import arrow
>>> dateStrings = [ 'Jun 1  2005 1:33PM', 'Aug 28 1999 12:00AM' ]
>>> for dateString in dateStrings:
...     dateString
...     arrow.get(dateString.replace('  ',' '), 'MMM D YYYY H:mmA').datetime
...     arrow.get(dateString.replace('  ',' '), 'MMM D YYYY H:mmA').format('ddd, Do MMM YYYY HH:mm')
...     arrow.get(dateString.replace('  ',' '), 'MMM D YYYY H:mmA').humanize(locale='de')
...
'Jun 1  2005 1:33PM'
datetime.datetime(2005, 6, 1, 13, 33, tzinfo=tzutc())
'Wed, 1st Jun 2005 13:33'
'vor 11 Jahren'
'Aug 28 1999 12:00AM'
datetime.datetime(1999, 8, 28, 0, 0, tzinfo=tzutc())
'Sat, 28th Aug 1999 00:00'
'vor 17 Jahren'

Lihat http://arrow.readthedocs.io/en/latest/ untuk lebih lanjut.

Komentar (0)

Ini akan membantu untuk mengkonversi string ke datetime dan juga dengan zona waktu

def convert_string_to_time(date_string, timezone):
    from datetime import datetime
    import pytz
    date_time_obj = datetime.strptime(date_string[:26], '%Y-%m-%d %H:%M:%S.%f')
    date_time_obj_timezone = pytz.timezone(timezone).localize(date_time_obj)

    return date_time_obj_timezone

date = '2018-08-14 13:09:24.543953+00:00'
TIME_ZONE = 'UTC'
date_time_obj_timezone = convert_string_to_time(date, TIME_ZONE)
Komentar (0)

Anda dapat menggunakan easy_date untuk memudahkan:

import date_converter
converted_date = date_converter.string_to_datetime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
Komentar (0)

Jika anda ingin hanya format tanggal maka anda dapat secara manual mengubah itu dengan melewati bidang masing-masing seperti:

>>> import datetime
>>> date = datetime.date(int('2017'),int('12'),int('21'))
>>> date
datetime.date(2017, 12, 21)
>>> type(date)

Anda dapat melewati split untuk mengkonversi nilai string menjadi tanggal jenis seperti:

selected_month_rec = '2017-09-01'
date_formate = datetime.date(int(selected_month_rec.split('-')[0]),int(selected_month_rec.split('-')[1]),int(selected_month_rec.split('-')[2]))

Anda akan mendapatkan nilai yang dihasilkan dalam format tanggal.

Komentar (0)
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
emp.info()

hal ini menunjukkan "Mulai Tanggal Waktu" Kolom dan "Login Terakhir Waktu" baik "objek = string" data-frame


RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
First Name           933 non-null object
Gender               855 non-null object

Tanggal Mulai 1000 non-null object

Login Terakhir Waktu 1000 non-null object

Salary               1000 non-null int64
Bonus %              1000 non-null float64
Senior Management    933 non-null object
Team                 957 non-null object
dtypes: float64(1), int64(1), object(6)
memory usage: 62.6+ KB

Dengan menggunakan parse_dates di read_csv lagi anda dapat mengkonversi string datetime ke panda format datetime.

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv", parse_dates=["Start Date", "Last Login Time"])
emp.info()


RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
First Name           933 non-null object
Gender               855 non-null object

Tanggal Mulai 1000 non-null datetime64[ns] Login Terakhir Waktu 1000 non-null datetime64[ns]

Salary               1000 non-null int64
Bonus %              1000 non-null float64
Senior Management    933 non-null object
Team                 957 non-null object
dtypes: datetime64[ns](2), float64(1), int64(1), object(4)
memory usage: 62.6+ KB
Komentar (0)

Lihat saya answer.

Di dunia nyata data ini adalah masalah nyata: beberapa, tidak cocok, tidak lengkap, tidak konsisten dan multilanguage/wilayah date format, sering dicampur dengan bebas dalam satu dataset. It's tidak ok untuk kode produksi gagal, apalagi pergi pengecualian-senang seperti rubah.

Kita perlu mencoba...menangkap beberapa datetime format fmt1,fmt2,...,fmtn dan menekan/menangani pengecualian (dari strptime()) bagi semua orang yang tidak cocok (dan khususnya, hindari membutuhkan yukky n-jauh menjorok tangga try..catch klausa). Dari my solution

def try_strptime(s, fmts=['%d-%b-%y','%m/%d/%Y']):
    for fmt in fmts:
        try:
            return datetime.strptime(s, fmt)
        except:
            continue

    return None # or reraise the ValueError if no format matched, if you prefer
Komentar (5)