简短而简单。我有一个巨大的日期时间列表,如字符串:
Jun 1 2005 1:33PM
Aug 28 1999 12:00AM
我将把它们推回到数据库中的正确日期时间字段中,因此我需要将它们变成真正的日期时间对象。
任何帮助(即使只是向正确的方向踢)都将不胜感激。
编辑:这是通过Django的ORM进行的,所以我不能使用SQL来进行插入转换。
答案 0 :(得分:2965)
datetime.strptime
是将字符串解析为日期时间的主要例程。它可以处理各种格式,格式由您提供的格式字符串确定:
from datetime import datetime
datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
生成的datetime
对象是时区的。
链接:
strftime.org对于strftime来说也是一个非常好的参考
注意:
strptime
=“字符串解析时间”strftime
=“字符串格式时间”答案 1 :(得分:721)
使用第三方dateutil库:
from dateutil import parser
dt = parser.parse("Aug 28 1999 12:00AM")
它可以处理大多数日期格式,包括您需要解析的格式。它比strptime更方便,因为它可以在大多数时间猜测正确的格式。
对于编写测试非常有用,其中可读性比性能更重要。
您可以使用以下方式安装:
pip install python-dateutil
答案 2 :(得分:472)
在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)
答案 3 :(得分:104)
我已经整理了一个可以转换一些非常简洁的表达式的项目。查看 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))
答案 4 :(得分:41)
记住这一点,你不需要再次对日期时间转换感到困惑。
String to datetime object = strptime
日期时间对象为其他格式= 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 i-e将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
如果你有不同的日期格式,你可以使用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)]
答案 5 :(得分:31)
许多时间戳都有隐含的时区。为了确保您的代码在每个时区都有效,您应该在内部使用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)))
答案 6 :(得分:23)
这里没有提到并且有用的东西:为当天添加后缀。我将后缀逻辑分离,以便您可以将它用于您喜欢的任何数字,而不仅仅是日期。
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"))
答案 7 :(得分:19)
我个人喜欢使用parser
模块的解决方案,这是这个问题的第二个答案并且非常漂亮,因为您不必构建任何字符串文字来使其正常工作。 但是,一个缺点是 比使用strptime
的答案慢<90%。
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
方法更方便,并且会自动处理大部分时间格式。< / p>
答案 8 :(得分:14)
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
:
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
答案 9 :(得分:13)
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
答案 10 :(得分:12)
在Python> = 3.7.0中,
要将 YYYY-MM-DD字符串转换为日期时间对象,可以使用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
答案 11 :(得分:9)
创建一个小实用程序函数,如:
def date(datestr="", format="%Y-%m-%d"):
from datetime import datetime
if not datestr:
return datetime.today().date()
return datetime.strptime(datestr, format).date()
这足够多才多艺:
答案 12 :(得分:7)
箭头为日期和时间提供了许多有用的功能。这段代码提供了问题的答案,并显示箭头还能够轻松地格式化日期并显示其他区域设置的信息。
args
答案 13 :(得分:5)
您可以使用easy_date轻松实现:
import date_converter
converted_date = date_converter.string_to_datetime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
答案 14 :(得分:4)
它将有助于将字符串转换为日期时间以及时区
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)
答案 15 :(得分:4)
您还可以签出dateparser
dateparser
提供了一些模块,可轻松解析几乎 网页上常见的任何字符串格式。
安装:
$ pip install dateparser
我认为,这是解析日期的最简单方法。
最直接的方法是使用
dateparser.parse
函数, 包含了模块中的大多数功能。
示例代码:
import dateparser
t1 = 'Jun 1 2005 1:33PM'
t2 = 'Aug 28 1999 12:00AM'
dt1 = dateparser.parse(t1)
dt2 = dateparser.parse(t2)
print(dt1)
print(dt2)
输出:
2005-06-01 13:33:00
1999-08-28 00:00:00
答案 16 :(得分:3)
如果您只想要日期格式,则可以通过传递以下各个字段来手动转换它:
>>> import datetime
>>> date = datetime.date(int('2017'),int('12'),int('21'))
>>> date
datetime.date(2017, 12, 21)
>>> type(date)
<type 'datetime.date'>
您可以传递拆分字符串值,将其转换为日期类型,如:
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]))
您将以日期格式获得结果值。
答案 17 :(得分:2)
如果您的字符串采用ISO8601格式,并且具有Python 3.7+,则可以使用以下简单代码:
import datetime.date
aDate = datetime.date.fromisoformat('2020-10-04')
日期和
import datetime.datetime
aDateTime = datetime.datetime.fromisoformat('2020-10-04 22:47:00')
用于包含日期和时间的字符串。如果包含时间戳记,则函数datetime.datetime.isoformat()
支持以下格式
YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]
答案 18 :(得分:1)
将 yyyy-mm-dd 日期字符串映射到 datetime.date 对象的简短示例:
from datetime import date
date_from_yyyy_mm_dd = lambda δ : date(*[int(_) for _ in δ.split('-')])
date_object = date_from_yyyy_mm_dd('2021-02-15')
答案 19 :(得分:0)
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
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
Start Date 1000 non-null object Last Login Time 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
通过使用parse_dates
中的read_csv
选项,您可以将字符串datetime转换为pandas datetime格式。
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
Start Date 1000 non-null datetime64[ns] Last Login Time 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
答案 20 :(得分:0)
使用pandas Timestamp似乎是最快的
import pandas as pd
N = 1000
l = ['Jun 1 2005 1:33PM'] * N
list(pd.to_datetime(l, format=format))
%timeit _ = list(pd.to_datetime(l, format=format))
1.58 ms ± 21.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
其他解决方案
from datetime import datetime
%timeit _ = list(map(lambda x: datetime.strptime(x, format), l))
9.41 ms ± 95.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
from dateutil.parser import parse
%timeit _ = list(map(lambda x: parse(x), l))
73.8 ms ± 1.14 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
如果字符串为ISO8601字符串,请使用csio8601
import ciso8601
l = ['2014-01-09'] * N
%timeit _ = list(map(lambda x: ciso8601.parse_datetime(x), l))
186 µs ± 4.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
答案 21 :(得分:0)
当您在整个列表中没有特定模式但如果您有一个模式并且您想将原始字符串转换为日期时间对象时,它会变得复杂。那么下面的代码可能会有所帮助,尽管其他朋友也提到了它。 将熊猫导入为 pd
dates = ['2021-10-15', '2022-10-16', '2024-10-16']
dates_1 = [d.date() for d in pd.to_datetime(dates)]
for date in dates_1:
print(date)
确保一切正常。您可能需要创建一个解析器。
答案 22 :(得分:-2)
请参阅my answer。
在实际数据中,这是一个真正的问题:多个,不匹配,不完整,不一致和多语言/区域日期格式,通常在一个数据集中自由混合。生产代码失败并不好,更不用说像狐狸一样快乐。
我们需要尝试...捕获多个日期时间格式fmt1,fmt2,...,fmtn并抑制/处理所有不匹配的异常(来自strptime()
)(特别是,避免需要yukky n-deep inrows ladder of try..catch clauses)。来自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