我正在寻找一种将异常的时间戳字符串解析为Python datetime
对象的方法。这里的问题是,该字符串包含相应的四分之一,datetime.strptime
函数似乎不支持该四分之一。字符串的格式如下:YYYY/qq/mm/dd/HH/MM
,例如1970/Q1/01/01/00/00
。我正在寻找一个函数,该函数可以让我以这种格式解析字符串,包括有效性检查(如果季度的日期正确)。
答案 0 :(得分:1)
问题:带Python的四分之一的日期时间字符串
datetime
这实现了OOP解决方案,该解决方案使用指令datetime
扩展了Python %Q
。
可能的值:Q1|Q2|Q3|Q4
,例如:
data_string = '1970/Q1/01/01/00/00'
# '%Y/%Q/%m/%d/%H/%M'
注意:这取决于
module _strptime class TimeRE
,如果内部实现发生变化,则可能会失败!
from datetime import datetime
class Qdatetime(datetime):
re_compile = None
@classmethod
def _strptime(cls):
import _strptime
_class = _strptime.TimeRE
if not 'strptime_compile' in _class.__dict__:
setattr(_class, 'strptime_compile', getattr(_class, 'compile'))
setattr(_class, 'compile', cls.compile)
def compile(self, format):
import _strptime
self = _strptime._TimeRE_cache
# Add directive %Q
if not 'Q' in self:
self.update({'Q': r"(?P<Q>Q[1-4])"})
Qdatetime.re_compile = self.strptime_compile(format)
return Qdatetime.re_compile
def validate(self, quarter):
# 1970, 1, 1 is the lowest date used in timestamp
month = [1, 4, 7, 10][quarter - 1]
day = [31, 30, 30, 31][quarter - 1]
q_start = datetime(self.year, month, 1).timestamp()
q_end = datetime(self.year, month + 2, day).timestamp()
dtt = self.timestamp()
return dtt >= q_start and dtt<= q_end
@property
def quarter(self): return self._quarter
@quarter.setter
def quarter(self, data):
found_dict = Qdatetime.re_compile.match(data).groupdict()
self._quarter = int(found_dict['Q'][1])
@property
def datetime(self):
return datetime(self.year, self.month, self.day,
hour=self.hour, minute=self.minute, second=self.second)
def __str__(self):
return 'Q{} {}'.format(self.quarter, super().__str__())
@classmethod
def strptime(cls, data_string, _format):
cls._strptime()
dt = super().strptime(data_string, _format)
dt.quarter = data_string
if not dt.validate(dt.quarter):
raise ValueError("time data '{}' does not match quarter 'Q{}'"\
.format(data_string, dt.quarter))
return dt
用法:
for data_string in ['1970/Q1/01/01/00/00',
'1970/Q3/12/31/00/00',
'1970/Q2/05/05/00/00',
'1970/Q3/07/01/00/00',
'1970/Q4/12/31/00/00',
]:
try:
d = Qdatetime.strptime(data_string, '%Y/%Q/%m/%d/%H/%M')
except ValueError as e:
print(e)
else:
print(d, d.datetime)
输出:
Q1 1970-01-01 00:00:00 1970-01-01 00:00:00 time data '1970/Q3/12/31/00/00' does not match quarter 'Q3' Q2 1970-05-05 00:00:00 1970-05-05 00:00:00 Q3 1970-07-01 00:00:00 1970-07-01 00:00:00 Q4 1970-12-31 00:00:00 1970-12-31 00:00:00
使用Python测试:3.6-已通过Python 3.8源进行验证