次の形式で日付を示す文字列があります。
x minutes/hours/days/months/years ago
Pythonを使用してそれを日時に解析する必要があります。
dateutil ではできないようです。
それを行う方法はありますか?
確かにあなたはそれを行うことができます。あなただけが必要です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
余談ですが、timedelta のように機能する があるdateutil
ように見えますが、コンストラクターは引数にandも受け入れます (引数は整数である必要があるようです)。relativedelta
months
years
これは s で簡単に行うことができますtimedelta
:
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()
ます。
完全に誇張されたソリューションですが、もっと柔軟なものが必要でした:
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日に単純化します。場合によっては十分ですが、常にあなたが望むものではありません。
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)