[PYTHON] 날짜 문자열에서 적절한 strftime 형식을 결정하는 방법?
PYTHON날짜 문자열에서 적절한 strftime 형식을 결정하는 방법?
dateutil 구문 분석기는 다양한 출처에서 날짜와 시간을 올바르게 추측하는 훌륭한 작업을 수행합니다.
우리는 각 파일이 하나의 날짜 / 시간 형식 만 사용하는 파일을 처리하지만 형식은 파일마다 다릅니다. 프로파일 링은 dateutil.parser.parse에서 많은 시간을 사용하고 있음을 보여줍니다. 파일 당 한 번만 결정하면되므로 매번 형식을 추측하지 못하는 무언가를 구현하면 속도가 빨라질 수 있습니다.
실제로 형식을 미리 알지 못하고 형식을 추론해야합니다. 같은 것 :
from MysteryPackage import date_string_to_format_string
import datetime
# e.g. mystring = '1 Jan 2016'
myformat = None
...
# somewhere in a loop reading from a file or connection:
if myformat is None:
myformat = date_string_to_format_string(mystring)
# do the usual checks to see if that worked, then:
mydatetime = datetime.strptime(mystring, myformat)
그런 기능이 있습니까?
해결법
-
==============================
1.이것은 까다 롭습니다. 내 접근 방식은 정규 표현식과 새로운 정규 표현식 모듈에서만 지원되는 (? (DEFINE) ...) 구문을 사용합니다. 본질적으로, DEFINE은 서브 루틴을 정합하기 전에 정의하기 때문에 먼저 날짜 추측 함수에 필요한 모든 벽돌을 정의합니다.
이것은 까다 롭습니다. 내 접근 방식은 정규 표현식과 새로운 정규 표현식 모듈에서만 지원되는 (? (DEFINE) ...) 구문을 사용합니다. 본질적으로, DEFINE은 서브 루틴을 정합하기 전에 정의하기 때문에 먼저 날짜 추측 함수에 필요한 모든 벽돌을 정의합니다.
(?(DEFINE) (?P<year_def>[12]\d{3}) (?P<year_short_def>\d{2}) (?P<month_def>January|February|March|April|May|June| July|August|September|October|November|December) (?P<month_short_def>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (?P<day_def>(?:0[1-9]|[1-9]|[12][0-9]|3[01])) (?P<weekday_def>(?:Mon|Tue|Wednes|Thurs|Fri|Satur|Sun)day) (?P<weekday_short_def>Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?P<hms_def>\d{2}:\d{2}:\d{2}) (?P<hm_def>\d{2}:\d{2}) (?P<ms_def>\d{5,6}) (?P<delim_def>([-/., ]+|(?<=\d|^)T)) ) # actually match them (?P<hms>^(?&hms_def)$)|(?P<year>^(?&year_def)$)|(?P<month>^(?&month_def)$)|(?P<month_short>^(?&month_short_def)$)|(?P<day>^(?&day_def)$)| (?P<weekday>^(?&weekday_def)$)|(?P<weekday_short>^(?&weekday_short_def)$)|(?P<hm>^(?&hm_def)$)|(?P<delim>^(?&delim_def)$)|(?P<ms>^(?&ms_def)$) """, re.VERBOSE)
이 후, 우리는 가능한 구분 기호를 생각할 필요가있다.
# delim delim = re.compile(r'([-/., ]+|(?<=\d)T)')
형식 매핑 :
# formats formats = {'ms': '%f', 'year': '%Y', 'month': '%B', 'month_dec': '%m', 'day': '%d', 'weekday': '%A', 'hms': '%H:%M:%S', 'weekday_short': '%a', 'month_short': '%b', 'hm': '%H:%M', 'delim': ''}
GuessFormat () 함수는 구분 기호를 사용하여 파트를 분할하고이를 일치 시키려고 시도하고 strftime ()에 해당하는 코드를 출력합니다.
def GuessFormat(datestring): # define the bricks bricks = re.compile(r""" (?(DEFINE) (?P<year_def>[12]\d{3}) (?P<year_short_def>\d{2}) (?P<month_def>January|February|March|April|May|June| July|August|September|October|November|December) (?P<month_short_def>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (?P<day_def>(?:0[1-9]|[1-9]|[12][0-9]|3[01])) (?P<weekday_def>(?:Mon|Tue|Wednes|Thurs|Fri|Satur|Sun)day) (?P<weekday_short_def>Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?P<hms_def>T?\d{2}:\d{2}:\d{2}) (?P<hm_def>T?\d{2}:\d{2}) (?P<ms_def>\d{5,6}) (?P<delim_def>([-/., ]+|(?<=\d|^)T)) ) # actually match them (?P<hms>^(?&hms_def)$)|(?P<year>^(?&year_def)$)|(?P<month>^(?&month_def)$)|(?P<month_short>^(?&month_short_def)$)|(?P<day>^(?&day_def)$)| (?P<weekday>^(?&weekday_def)$)|(?P<weekday_short>^(?&weekday_short_def)$)|(?P<hm>^(?&hm_def)$)|(?P<delim>^(?&delim_def)$)|(?P<ms>^(?&ms_def)$) """, re.VERBOSE) # delim delim = re.compile(r'([-/., ]+|(?<=\d)T)') # formats formats = {'ms': '%f', 'year': '%Y', 'month': '%B', 'month_dec': '%m', 'day': '%d', 'weekday': '%A', 'hms': '%H:%M:%S', 'weekday_short': '%a', 'month_short': '%b', 'hm': '%H:%M', 'delim': ''} parts = delim.split(datestring) out = [] for index, part in enumerate(parts): try: brick = dict(filter(lambda x: x[1] is not None, bricks.match(part).groupdict().items())) key = next(iter(brick)) # ambiguities if key == 'day' and index == 2: key = 'month_dec' item = part if key == 'delim' else formats[key] out.append(item) except AttributeError: out.append(part) return "".join(out)
결국 테스트 :
import regex as re datestrings = [datetime.now().isoformat(), '2006-11-02', 'Thursday, 10 August 2006 08:42:51', 'August 9, 1995', 'Aug 9, 1995', 'Thu, 01 Jan 1970 00:00:00', '21/11/06 16:30', '06 Jun 2017 20:33:10'] # test for dt in datestrings: print("Date: {}, Format: {}".format(dt, GuessFormat(dt)))
결과는 다음과 같습니다.
Date: 2017-06-07T22:02:05.001811, Format: %Y-%m-%dT%H:%M:%S.%f Date: 2006-11-02, Format: %Y-%m-%d Date: Thursday, 10 August 2006 08:42:51, Format: %A, %m %B %Y %H:%M:%S Date: August 9, 1995, Format: %B %m, %Y Date: Aug 9, 1995, Format: %b %m, %Y Date: Thu, 01 Jan 1970 00:00:00, Format: %a, %m %b %Y %H:%M:%S Date: 21/11/06 16:30, Format: %d/%m/%d %H:%M Date: 06 Jun 2017 20:33:10, Format: %d %b %Y %H:%M:%S
-
==============================
2.저는 기성품 해결책이 없지만 이것은 매우 까다로운 문제입니다. 너무 많은 뇌 시간이 이미 dateutil에 사용 되었기 때문에이를 대체하려고하지 않고 그것을 통합하는 접근법을 제안 할 것입니다 :
저는 기성품 해결책이 없지만 이것은 매우 까다로운 문제입니다. 너무 많은 뇌 시간이 이미 dateutil에 사용 되었기 때문에이를 대체하려고하지 않고 그것을 통합하는 접근법을 제안 할 것입니다 :
"각 파일은 하나의 날짜 / 시간 형식 만 사용합니다"라고 말했기 때문에이 방법을 사용해야합니다 (여러 파일의 날짜가 서로 다른 경우 여러 날짜 값을 비교하여 mm / dd 모호성을 해결할 수 있음).
-
==============================
3.자신 만의 파서를 작성할 수 있습니다.
자신 만의 파서를 작성할 수 있습니다.
import datetime class DateFormatFinder: def __init__(self): self.fmts = [] def add(self,fmt): self.fmts.append(fmt) def find(self, ss): for fmt in self.fmts: try: datetime.datetime.strptime(ss, fmt) return fmt except: pass return None
다음과 같이 사용할 수 있습니다.
>>> df = DateFormatFinder() >>> df.add('%m/%d/%y %H:%M') >>> df.add('%m/%d/%y') >>> df.add('%H:%M') >>> df.find("01/02/06 16:30") '%m/%d/%y %H:%M' >>> df.find("01/02/06") '%m/%d/%y' >>> df.find("16:30") '%H:%M' >>> df.find("01/02/06 16:30") '%m/%d/%y %H:%M' >>> df.find("01/02/2006")
그러나 날짜가 모호 할 수 있고 형식이 문맥없이 결정될 수 없기 때문에 그렇게 간단하지 않습니다.
>>> datetime.strptime("01/02/06 16:30", "%m/%d/%y %H:%M") # us format datetime.datetime(2006, 1, 2, 16, 30) >>> datetime.strptime("01/02/06 16:30", "%d/%m/%y %H:%M") # european format datetime.datetime(2006, 2, 1, 16, 30)
from https://stackoverflow.com/questions/44321601/how-to-determine-appropriate-strftime-format-from-a-date-string by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬 : obj.next ()가 아닌 next ()를 사용해야하는 이유는 무엇입니까? (0) | 2018.11.21 |
---|---|
[PYTHON] 파이썬 : sys.argv 처리에 사용되는 인코딩은 무엇입니까? (0) | 2018.11.21 |
[PYTHON] 파이썬에서 커서 위치 찾기 (0) | 2018.11.21 |
[PYTHON] 파이썬에서리스트에서 가장 짧은 문자열 찾기 (0) | 2018.11.21 |
[PYTHON] 파이썬에서 '\ x'가 왜 유효하지 않습니까? (0) | 2018.11.21 |