短而简单。我有一个像这样的日期-时间的字符串列表:
1 2 | Jun 1 2005 1:33PM Aug 28 1999 12:00AM |
我将把这些返回到数据库中适当的datetime字段中,因此我需要将它们转换为实际的datetime对象。
任何帮助(即使只是朝正确的方向踢一脚)都将受到感激。
编辑:这是通过Django的ORM进行的,所以我不能使用SQL在insert上进行转换。
1 2 3 | from datetime import datetime datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p') |
得到的
链接:
用于
用于
org对于strftime也是一个很好的参考
注:
使用第三方dateutil库:
1 2 | from dateutil import parser dt = parser.parse("Aug 28 1999 12:00AM") |
它可以处理大多数日期格式,包括需要解析的格式。它比strptime更方便,因为大多数时候它都能猜出正确的格式。
它对于编写测试非常有用,因为可读性比性能更重要。
你可以安装它与:
1 | pip install python-dateutil |
在时间模块中查看strptime。它是strftime的倒数。
1 2 3 4 5 6 | $ 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) |
我做了一个项目,可以转换一些非常简洁的表达式。查看timestring。
下面是一些例子:1 2 3 4 5 6 7 8 9 | >>> 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转换中再次感到困惑。
datetime对象的字符串=
其他格式的datetime对象=
等于
%b Month as locale’s abbreviated name(Jun)
%d Day of the month as a zero-padded decimal number(1)
%Y Year with century as a decimal number(2015)
%I Hour (12-hour clock) as a zero-padded decimal number(01)
%M Minute as a zero-padded decimal number(33)
%p Locale’s equivalent of either AM or PM(PM)
因此,需要将strptime i-e转换为
1 2 3 4 5 6 7 8 9 | >>> 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 ... |
输出
1 2 3 4 | <type 'datetime.datetime'> 2005-06-01 13:33:00 <type 'datetime.datetime'> 1999-08-28 00:00:00 |
如果您有不同格式的日期,您可以使用panda或dateutil.parse
1 2 3 4 5 6 7 | >>> 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] |
输出
1 | [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)] |
许多时间戳都有一个隐含的时区。为了确保您的代码能够在每个时区工作,您应该在内部使用UTC,并在每次外部对象进入系统时附加一个时区。
Python 3.2 +:
1 2 3 | >>> datetime.datetime.strptime( ... "March 5, 2014, 20:13:50","%B %d, %Y, %H:%M:%S" ... ).replace(tzinfo=datetime.timezone(datetime.timedelta(hours=-3))) |
这里没有提到但很有用的东西:在一天中添加后缀。我解耦了后缀逻辑,所以你可以用它来表示任何你喜欢的数字,而不仅仅是日期。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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"))??????? |
下面是两个使用panda将格式化为字符串的日期转换为datetime的解决方案。日期对象。
1 2 3 4 5 6 7 8 9 10 11 | 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)] |
计时
1 2 3 4 5 6 7 | 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 |
下面是如何转换OP的原始日期-时间示例:
1 2 3 4 5 | 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)] |
使用
同样,除了
我个人喜欢使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
只要您不重复做一百万次,我仍然认为
Django时区感知的datetime对象示例。
1 2 3 4 5 6 7 | 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) |
当您有
1 | RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
适用于unix / mysql格式2018-10-15 20:59:29
1 2 3 | from datetime import datetime datetime_object = datetime.strptime('2018-10-15 20:59:29', '%Y-%m-%d %H:%M:%S') |
创建一个小的实用函数,如:
1 2 3 4 5 | def date(datestr="", format="%Y-%m-%d"): from datetime import datetime if not datestr: return datetime.today().date() return datetime.strptime(datestr, format).date() |
这是多才多艺的:
如果您不传递任何参数,它将返回今天的日期。有一个默认的日期格式,您可以覆盖它。您可以轻松地修改它以返回一个datetime。datetime Python模块非常适合获取日期时间和转换日期时间格式。
1 2 3 4 5 6 | 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 |
输出:
1 2 | 2005-06-01 13:33:00 2005/06/01 01:33PM |
arrow为日期和时间提供了许多有用的函数。这段代码为这个问题提供了一个答案,并显示出arrow还能够方便地格式化日期和显示其他地区的信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | >>> 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' |
见http://arrow.readthedocs。io / en /最近/。
在Python中>= 3.7.0,
要将YYYY-MM-DD字符串转换为datetime对象,可以使用
1 2 3 4 5 | >>> from datetime import datetime >>> date_string ="2012-12-12 10:10:10" >>> print (datetime.fromisoformat(date_string)) >>> 2012-12-12 10:10:10 |
你可以使用easy_date来简化:
1 2 | import date_converter converted_date = date_converter.string_to_datetime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p') |
如果你只想要日期格式,你可以手动转换它通过传递你的个人字段如下:
1 2 3 4 5 6 | >>> import datetime >>> date = datetime.date(int('2017'),int('12'),int('21')) >>> date datetime.date(2017, 12, 21) >>> type(date) <type 'datetime.date'> |
您可以传递拆分字符串值,将其转换为日期类型,如下所示:
1 2 | 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])) |
您将得到日期格式的结果值。
它将有助于将字符串转换为datetime和时区
1 2 3 4 5 6 7 8 9 10 11 | 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) |
1 2 | emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv") emp.info() |
它显示"开始日期时间"列和"最后登录时间"都是数据帧中的"object = string"
1 2 3 4 5 | <class 'pandas.core.frame.DataFrame'> RangeIndex: 1000 entries, 0 to 999 Data columns (total 8 columns): First Name 933 non-null object Gender 855 non-null object |
1
2
3 Start Date 1000 non-null object
Last Login Time 1000 non-null object
1 2 3 4 5 6 | 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 |
通过使用
1 2 3 4 5 6 7 8 9 | emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv", parse_dates=["Start Date","Last Login Time"]) emp.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 1000 entries, 0 to 999 Data columns (total 8 columns): First Name 933 non-null object Gender 855 non-null object |
1
2 Start Date 1000 non-null datetime64[ns]
Last Login Time 1000 non-null datetime64[ns]
1 2 3 4 5 6 | 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 |
看到我的答案。
在实际数据中,这是一个真正的问题:多个、不匹配的、不完整的、不一致的和多语言/区域的数据格式,常常在一个数据集中自由混合。生产代码失败是不好的,更不用说像狐狸一样快乐了。
我们需要试一试……捕获多个日期时间格式fmt1、fmt2、…,fmtn和抑制/处理所有那些不匹配的异常(来自
1 2 3 4 5 6 7 8 | 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 |