我有以下列格式显示日期的字符串:
x minutes/hours/days/months/years ago
我需要使用python将其解析为日期时间。
似乎dateutil无法做到。
有办法吗?
答案 0 :(得分:8)
当然可以做到。您只需要一个timedelta
。
s = "3 days ago"
parsed_s = [s.split()[:2]]
time_dict = dict((fmt,float(amount)) for amount,fmt in parsed_s)
dt = datetime.timedelta(**time_dict)
past_time = datetime.datetime.now() - dt
顺便说一下,看起来dateutil
有一个relativedelta
就像一个timedelta,但构造函数也接受months
和years
的参数(显然参数必须是整数)。
答案 1 :(得分:6)
这可以通过timedelta
s轻松完成:
import datetime
def string_to_delta(string_delta):
value, unit, _ = string_delta.split()
return datetime.timedelta(**{unit: float(value)})
产:
>>> string_to_delta("20 hours ago")
datetime.timedelta(0, 72000)
虽然这需要一些额外的工作来处理数月/年 - 因为在一个日期中添加一个月是一个模糊的操作,但如果你知道你想要它意味着它应该是一个简单的补充。
要获得实际时间,只需将差值从datetime.datetime.now()
开始。
答案 2 :(得分:3)
因为您的论点类似于2天前,3个月前,2年前。下面的函数可能有助于获取参数的确切日期。首先需要导入以下日期工具
import datetime
from dateutil.relativedelta import relativedelta
然后实现下面的功能
def get_past_date(str_days_ago):
TODAY = datetime.date.today()
splitted = str_days_ago.split()
if len(splitted) == 1 and splitted[0].lower() == 'today':
return str(TODAY.isoformat())
elif len(splitted) == 1 and splitted[0].lower() == 'yesterday':
date = TODAY - relativedelta(days=1)
return str(date.isoformat())
elif splitted[1].lower() in ['hour', 'hours', 'hr', 'hrs', 'h']:
date = datetime.datetime.now() - relativedelta(hours=int(splitted[0]))
return str(date.date().isoformat())
elif splitted[1].lower() in ['day', 'days', 'd']:
date = TODAY - relativedelta(days=int(splitted[0]))
return str(date.isoformat())
elif splitted[1].lower() in ['wk', 'wks', 'week', 'weeks', 'w']:
date = TODAY - relativedelta(weeks=int(splitted[0]))
return str(date.isoformat())
elif splitted[1].lower() in ['mon', 'mons', 'month', 'months', 'm']:
date = TODAY - relativedelta(months=int(splitted[0]))
return str(date.isoformat())
elif splitted[1].lower() in ['yrs', 'yr', 'years', 'year', 'y']:
date = TODAY - relativedelta(years=int(splitted[0]))
return str(date.isoformat())
else:
return "Wrong Argument format"
然后您可以像这样调用函数:
print get_past_date('5 hours ago')
print get_past_date('yesterday')
print get_past_date('3 days ago')
print get_past_date('4 months ago')
print get_past_date('2 years ago')
print get_past_date('today')
答案 3 :(得分:2)
@mgilson 的回答在 dateutil.relativedelta 完成工作的地方对我不起作用:
根据@mosc9575 建议进行编辑
import datetime
from dateutil.relativedelta import relativedelta
time_ago = "1 month ago"
val, unit = time_ago.split()[:2]
past_time = datetime.datetime.now() - relativedelta(**{unit:int(val)})
答案 4 :(得分:0)
完全夸张的解决方案,但我需要更灵活的东西:
def string_to_delta(relative):
#using simplistic year (no leap months are 30 days long.
#WARNING: 12 months != 1 year
unit_mapping = [('mic', 'microseconds', 1),
('millis', 'microseconds', 1000),
('sec', 'seconds', 1),
('day', 'days', 1),
('week', 'days', 7),
('mon', 'days', 30),
('year', 'days', 365)]
try:
tokens = relative.lower().split(' ')
past = False
if tokens[-1] == 'ago':
past = True
tokens = tokens[:-1]
elif tokens[0] == 'in':
tokens = tokens[1:]
units = dict(days = 0, seconds = 0, microseconds = 0)
#we should always get pairs, if not we let this die and throw an exception
while len(tokens) > 0:
value = tokens.pop(0)
if value == 'and': #just skip this token
continue
else:
value = float(value)
unit = tokens.pop(0)
for match, time_unit, time_constant in unit_mapping:
if unit.startswith(match):
units[time_unit] += value * time_constant
return datetime.timedelta(**units), past
except Exception as e:
raise ValueError("Don't know how to parse %s: %s" % (relative, e))
这可以解析如下内容:
2 days ago
in 60 seconds
2 DAY and 4 Secs
in 1 year, 1 Month, 2 days and 4 MICRO
2 Weeks 4 secs ago
7 millis ago
巨大的但是:它将月份和年份分别简化为30天和365天。并不总是你想要的,虽然这对某些情况来说已经足够了。
答案 5 :(得分:0)
在Python中将x hours ago
转换为datetime
,x hour, y mins ago
转换为datetime
等的自定义函数。
函数采用使用RegExp解析的字符串类型的单个参数。可以自定义RegExp以匹配功能输入。
有关用法,请参见下面的示例。
import re
from datetime import datetime, timedelta
def convert_datetime(datetime_ago):
matches = re.search(r"(\d+ weeks?,? )?(\d+ days?,? )?(\d+ hours?,? )?(\d+ mins?,? )?(\d+ secs? )?ago", datetime_ago)
if not matches:
return None
date_pieces = {'week': 0, 'day': 0, 'hour': 0, 'min': 0, 'sec': 0}
for i in range(1, len(date_pieces) + 1):
if matches.group(i):
value_unit = matches.group(i).rstrip(', ')
if len(value_unit.split()) == 2:
value, unit = value_unit.split()
date_pieces[unit.rstrip('s')] = int(value)
d = datetime.today() - timedelta(
weeks=date_pieces['week'],
days=date_pieces['day'],
hours=date_pieces['hour'],
minutes=date_pieces['min'],
seconds=date_pieces['sec']
)
return d
用法示例:
dates = [
'1 week, 6 days, 11 hours, 20 mins, 13 secs ago',
'1 week, 10 hours ago',
'1 week, 1 day ago',
'6 days, 11 hours, 20 mins ago',
'1 hour ago',
'11 hours, 20 mins ago',
'20 mins 10 secs ago',
'10 secs ago',
'1 sec ago',
]
for date in dates:
print(convert_datetime(date))
输出:
2019-05-10 06:26:40.937027
2019-05-16 07:46:53.937027
2019-05-15 17:46:53.937027
2019-05-17 06:26:53.937027
2019-05-23 16:46:53.937027
2019-05-23 06:26:53.937027
2019-05-23 17:26:43.937027
2019-05-23 17:46:43.937027
2019-05-23 17:46:52.937027
答案 6 :(得分:0)
确保使用pip3安装依赖项
from datetime import date
from dateutil.relativedelta import relativedelta
import re
baseDate = date.today() #date(2020, 4, 29)
hoursPattern = re.compile(r'(\d\d?\d?) hours? ago')
daysPattern = re.compile(r'(\d\d?\d?) days? ago')
weeksPattern = re.compile(r'(\d\d?\d?) weeks? ago')
monthsPattern = re.compile(r'(\d\d?\d?) months? ago')
yearsPattern = re.compile(r'(\d\d?\d?) years? ago')
days = 0
daysMatch = daysPattern.search(ago)
if daysMatch:
days += int(daysMatch.group(1))
hours = 0
hoursMatch = hoursPattern.search(ago)
if hoursMatch:
hours += int(hoursMatch.group(1))
weeks = 0
weeksMatch = weeksPattern.search(ago)
if weeksMatch:
weeks += int(weeksMatch.group(1))
months = 0
monthsMatch = monthsPattern.search(ago)
if monthsMatch:
months += int(monthsMatch.group(1))
years = 0
yearsMatch = yearsPattern.search(ago)
if yearsMatch:
years += int(yearsMatch.group(1))
yourDate = baseDate - relativedelta(hours=hours, days=days, weeks=weeks, months=months, years=years)
答案 7 :(得分:0)
最简单的方法是使用dateparser:
import dateparser
date_ago="4 months ago"
date=dateparser.parse(date).strftime("%Y-%m-%d")
date
输出:
'2020-01-08'
答案 8 :(得分:0)
datetime 是否有机会使用其他语言(意大利语)“x 天前至今”?
import locale\
locale.setlocale(locale.LC_ALL,'it_IT.UTF-8')
没有任何区别。