strftime python




تحويل السلسلة إلى وقت/وقت (12)

قصيرة وبسيطة. لديّ قائمة كبيرة من أوقات التّاريخ كهذه كسلسلة:

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

سأقوم بدفع هذه العودة إلى حقول التاريخ والوقت في قاعدة بيانات لذلك أنا بحاجة إلى السحر لهم في كائنات datetime حقيقية.

أي مساعدة (حتى لو كانت مجرد ركلة في الاتجاه الصحيح) سيكون موضع تقدير.

تحرير: هذا يمر ORM Django لذلك لا أستطيع استخدام SQL للقيام التحويل عند إدراج.


Django Timezone علم كائن التاريخ والوقت.

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)

هذا التحويل مهم جدًا ل Django و Python عندما يكون لديك USE_TZ = True :

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

أنا شخصياً أحب الحل باستخدام وحدة parser ، وهو الرد الثاني على هذا السؤال وجميل ، حيث لا تحتاج إلى إنشاء أي حرفية للسلسلة كي تعمل. ومع ذلك ، هناك جانب سلبي واحد ، وهو 90% أبطأ ثم الإجابة المقبولة مع 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

ما دمت لا تفعل هذا a million مرة مراراً وتكراراً ، أعتقد أن طريقة parser أكثر ملاءمة وستتناول معظم تنسيقات الوقت تلقائياً.


استخدم مكتبة dateutil الطرف الثالث:

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

يمكنه معالجة معظم تنسيقات التاريخ ، بما في ذلك التنسيقات التي تحتاج إلى تحليلها. إنها أكثر ملاءمة من وقت التشغيل لأنها تستطيع تخمين الصيغة الصحيحة في معظم الأوقات.

إنها مفيدة جدًا في كتابة الاختبارات ، حيث تكون القراءة أكثر أهمية من الأداء.

يمكنك تثبيته مع:

pip install python-dateutil

انظر جوابي .

في بيانات العالم الحقيقي هذه مشكلة حقيقية: تنسيقات متعددة ، غير متطابقة ، غير كاملة ، غير متناسقة وتاريخية / متعددة المناطق ، غالباً ما تختلط بحرية في مجموعة بيانات واحدة. ليس من الجيد أن تفشل شفرة الإنتاج ، ناهيك عن السعادة الاستثنائية مثل الثعلب.

نحن بحاجة لمحاولة ... القبض على صيغ datetime متعددة fmt1 ، fmt2 ، ... ، fmtn وقمع / التعامل مع الاستثناءات (من strptime() ) لجميع تلك التي لا تتوافق (وعلى وجه الخصوص ، تجنب الحاجة إلى ny yukky n-deep intented سلم من محاولة .. البنود جرح). انظر الحل الخاص بي


تحقق من وقت strptime في الوحدة time . هذا هو معكوس 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)

تذكر هذا وأنت لست بحاجة إلى الخلط في تحويل التاريخ والوقت مرة أخرى.

سلسلة إلى كائن datetime = strptime

كائن تاريخ / وقت إلى صيغ أخرى = strftime

Jun 1 2005 1:33PM

يساوي

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

٪ b شهر كاسم مختصر للغة (يونيو)

٪ d يوم من الشهر كرقم عشري غير مبطن (1)

٪ Y سنة مع قرن كرقم عشري (2015)

٪ I ساعة (ساعة 12 ساعة) كرقم عشري غير مبطن (01)

٪ م دقيقة كرقم عشري غير مبطن (33)

٪ p تعادل اللغة المحلية لكل من AM أو PM (PM)

لذلك تحتاج إلى strptime أي تحويل string إلى

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

انتاج |

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

ماذا لو كان لديك تنسيق مختلف للتواريخ يمكنك استخدام الباندا أو 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]

انتاج

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

شيء غير مذكور هنا ومفيد: إضافة لاحقة إلى اليوم. قمت بفصل منطق اللاحقة بحيث يمكنك استخدامها لأي رقم تريده وليس فقط التواريخ.

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"))​​​​​​​

فيما يلي حلان يستخدمان Pandas لتحويل التواريخ المنسقة كسلاسل إلى كائنات 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)]

توقيت

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

وإليك كيفية تحويل أمثلة وقت-وقت OR الأصلية:

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

هناك العديد من الخيارات للتحويل من السلاسل إلى Pandas Timestamps باستخدام to_datetime ، لذا تحقق من docs إذا كنت بحاجة إلى أي شيء خاص.

وبالمثل ، تحتوي الطوابع الزمنية على العديد من الخصائص والأساليب التي يمكن الوصول إليها بالإضافة إلى .date


لقد وضعت مشروعًا يمكنه تحويل بعض التعبيرات الأنيقة. تحقق من timestring .

فيما يلي بعض الأمثلة أدناه:

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

وحدة بايثون datetime هو جيد للحصول على وقت التاريخ وتحويل تنسيقات الوقت التاريخ.

import datetime

new_date_format1 = datetime.datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
new_date_format2 = datetime.datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p').strftime('%Y/%m/%d %I:%M%p')
print new_date_format1
print new_date_format2

انتاج :

2005-06-01 13:33:00
2005/06/01 01:33PM

datetime.strptime هو الروتين الرئيسي لاستنتاج السلاسل في datetimes. يمكنه التعامل مع كل أنواع التنسيقات ، بالتنسيق المحدد بواسطة سلسلة التنسيق التي تعطيها:

from datetime import datetime

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

الكائن datetime هو timezone-naive.

الروابط:

ملاحظات:

  • strptime = "وقت تحليل السلسلة"
  • strftime = "وقت تنسيق السلسلة"
  • انطق بصوت عالٍ اليوم ولن تضطر إلى البحث عنه مرة أخرى خلال 6 أشهر.

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




datetime