简短而简单.我有一个巨大的日期时间列表,像这样的字符串:
Jun 1 2005 1:33PM Aug 28 1999 12:00AM
我将把它们推回到数据库中的正确日期时间字段中,因此我需要将它们变成真正的日期时间对象.
任何帮助(即使它只是在正确的方向踢)将不胜感激.
编辑:这是通过Django的ORM,所以我不能使用SQL来进行插入转换.
datetime.strptime
是将字符串解析为日期时间的主要例程.它可以处理各种格式,格式由您提供的格式字符串确定:
from datetime import datetime datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
结果datetime
对象是时区的.
链接:
Python文档strptime
:Python 2,Python 3
strptime
/ strftime
format字符串的Python文档:Python 2,Python 3
strftime.org也是strftime的一个非常好的参考
笔记:
strptime
="字符串解析时间"
strftime
="字符串格式时间"
今天大声发音,你将不必在6个月内再次搜索它.
使用第三方dateutil库:
from dateutil import parser parser.parse("Aug 28 1999 12:00AM") # datetime.datetime(1999, 8, 28, 0, 0)
它可以处理大多数日期格式,包括您需要解析的格式.它比strptime更方便,因为它可以在大多数时间猜测正确的格式.
它对于编写测试非常有用,其中可读性比性能更重要.
你可以安装它:
pip install python-dateutil
退房strptime中时间模块.这是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)
我已经组建了一个可以转换一些非常简洁的表达式的项目.检查时间串.
pip install 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))
记住这一点,你不需要再次混淆日期时间转换.
字符串到datetime对象= strptime
datetime对象为其他格式= strftime
Jun 1 2005 1:33PM
等于
%b %d %Y %I:%M%p
%b月份作为语言环境的缩写名称(Jun)
%d作为零填充十进制数的月中的某一天(1)
%Y年份以世纪为十进制数(2015年)
%I小时(12小时制)作为零填充十进制数(01)
%M分钟为零填充十进制数(33)
%p Locale相当于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 ...
产量
2005-06-01 13:33:00 1999-08-28 00:00:00
如果你有不同的日期格式,你可以使用panda或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)]
许多时间戳都有隐含的时区.为了确保您的代码在每个时区都有效,您应该在内部使用UTC,并在每次外来对象进入系统时附加时区.
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)))
在Python> = 3.7.0中,
转换YYYY-MM-DD字符串DateTime对象,datetime.fromisoformat
都可以使用。
>>> from datetime import datetime >>> date_string = "2012-12-12 10:10:10" >>> print (datetime.fromisoformat(date_string)) >>> 2012-12-12 10:10:10
以下是使用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
以下是如何转换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)]
有很多选项可以使用字符串转换为Pandas Timestamps to_datetime
,因此如果您需要任何特殊内容,请查看文档.
同样,Timestamps还有许多可以访问的属性和方法.date
这里没有提到的东西很有用:为当天添加后缀.我将后缀逻辑分离,以便您可以将它用于您喜欢的任何数字,而不仅仅是日期.
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"))???????
我个人喜欢使用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
只要你不是一遍又一遍地做这一百万次,我仍然认为这种parser
方法更方便,并且会自动处理大部分时间格式.
Django时区感知日期时间对象示例.
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)
当您拥有USE_TZ = True
以下内容时,此转换对于Django和Python非常重要:
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
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
创建一个小实用程序函数,如:
def date(datestr="", format="%Y-%m-%d"): from datetime import datetime if not datestr: return datetime.today().date() return datetime.strptime(datestr, format).date()
这是多才多艺的:
如果你没有传递任何参数,它将返回今天的日期.
默认情况下,您可以覆盖日期格式.
您可以轻松修改它以返回日期时间.
arrow为日期和时间提供了许多有用的功能.这段代码提供了问题的答案,并显示箭头还能够轻松地格式化日期并显示其他区域设置的信息.
>>> 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/latest/.
它将有助于将字符串转换为日期时间以及时区
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)
您可以使用easy_date轻松实现:
import date_converter converted_date = date_converter.string_to_datetime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')