단순 문자열로 시간 델타 객체를 구성하는 방법
문자열을 구문 분석해야 하는 함수를 작성하고 있습니다.timedelta
는 사자는다같것입합니다야와 같은 ."32m"
또는"2h32m"
아니 심지어는"4:13"
또는"5hr34m56s"
도서관 같은 것이 이미 구현되어 있는 곳이 있습니까?
dateutil과 같은 외부 라이브러리에 의존하거나 입력을 수동으로 구문 분석할 필요가 없는 가장 우아한 솔루션은 datetime의 강력한 기능을 사용하는 것입니다.strptime
문자열 구문 분석 방법입니다.
from datetime import datetime, timedelta
# we specify the input and the format...
t = datetime.strptime("05:20:25","%H:%M:%S")
# ...and use datetime's hour, min and sec properties to build a timedelta
delta = timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)
그런 다음 시간 델타 개체를 정상적으로 사용하고 초로 변환하여 올바른 작업을 수행했는지 확인할 수 있습니다.
print(delta)
assert(5*60*60+20*60+25 == delta.total_seconds())
저는 어제 시간이 좀 있어서 @virhilo의 답변을 Python 모듈로 개발했고, @priestc에서 요청한 모든 시간 표현 형식을 포함하여 몇 가지 더 추가했습니다.
소스 코드는 Github(MIT License)에 있습니다.PyPI에도 있습니다.
pip install pytimeparse
시간을 초 단위로 반환합니다.
>>> from pytimeparse.timeparse import timeparse
>>> timeparse('32m')
1920
>>> timeparse('2h32m')
9120
>>> timeparse('4:13')
253
>>> timeparse('5hr34m56s')
20096
>>> timeparse('1.2 minutes')
72
첫 번째 형식의 경우(5hr34m56s
.
재기반 솔루션은 다음과 같습니다.
import re
from datetime import timedelta
regex = re.compile(r'((?P<hours>\d+?)hr)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?')
def parse_time(time_str):
parts = regex.match(time_str)
if not parts:
return
parts = parts.groupdict()
time_params = {}
for name, param in parts.items():
if param:
time_params[name] = int(param)
return timedelta(**time_params)
>>> from parse_time import parse_time
>>> parse_time('12hr')
datetime.timedelta(0, 43200)
>>> parse_time('12hr5m10s')
datetime.timedelta(0, 43510)
>>> parse_time('12hr10s')
datetime.timedelta(0, 43210)
>>> parse_time('10s')
datetime.timedelta(0, 10)
>>>
만약 판다가 이미 여러분의 의존도에 있다면, 이것은 꽤 잘 해냅니다.
>>> import pandas as pd
>>> pd.Timedelta('5hr34m56s')
Timedelta('0 days 05:34:56')
>>> pd.Timedelta('2h32m')
Timedelta('0 days 02:32:00')
>>> pd.Timedelta('5hr34m56s')
Timedelta('0 days 05:34:56')
>>> # It is pretty forgiving:
>>> pd.Timedelta('2 days 24:30:00 10 sec')
Timedelta('3 days 00:30:10')
로변는방법으로 datetime.timedelta
해당 유형을 선호하는 경우:
>>> pd.Timedelta('1 days').to_pytimedelta()
datetime.timedelta(1)
그러나 유감스럽게도 이것은 작동하지 않습니다.
>>> pd.Timedelta('4:13')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pandas\_libs\tslibs\timedeltas.pyx", line 1217, in
pandas._libs.tslibs.timedeltas.Timedelta.__new__
File "pandas\_libs\tslibs\timedeltas.pyx", line 454, in
pandas._libs.tslibs.timedeltas.parse_timedelta_string
ValueError: expected hh:mm:ss format
판다는 비록 그것이 주요 목적은 아니지만 사실 꽤 광범위한 날짜와 시간 도구를 가지고 있습니다.
Panda 설치하기
# If you use pip
pip install pandas
# If you use conda
conda install pandas
시간을 입력하고 다양한 날짜에 추가하여 이 작업이 가능하도록 했습니다.
from datetime import datetime as dtt
time_only = dtt.strptime('15:30', "%H:%M") - dtt.strptime("00:00", "%H:%M")
몇 가지 업그레이드를 통해 virhilo의 좋은 답변을 수정했습니다.
- 문자열이 유효한 시간 문자열이라는 주장을 추가했습니다.
- "hr" 시보를 "h"로 바꿉니다.
- "d"일 표시를 허용합니다.
- 이 아닌 시간 ▁((:▁allow
3m0.25s
3개월, 0.25초)
.
import re
from datetime import timedelta
regex = re.compile(r'^((?P<days>[\.\d]+?)d)?((?P<hours>[\.\d]+?)h)?((?P<minutes>[\.\d]+?)m)?((?P<seconds>[\.\d]+?)s)?$')
def parse_time(time_str):
"""
Parse a time string e.g. (2h13m) into a timedelta object.
Modified from virhilo's answer at https://stackoverflow.com/a/4628148/851699
:param time_str: A string identifying a duration. (eg. 2h13m)
:return datetime.timedelta: A datetime.timedelta object
"""
parts = regex.match(time_str)
assert parts is not None, "Could not parse any time information from '{}'. Examples of valid strings: '8h', '2d8h5m20s', '2m4s'".format(time_str)
time_params = {name: float(param) for name, param in parts.groupdict().items() if param}
return timedelta(**time_params)
기능이 함께 됩니다.parse_duration()
설명서에서 다음을 참조하십시오.
문자열을 구문 분석하고 다음을 반환합니다.
datetime.timedelta
.형의데식필요니 를 예상합니다.
"DD HH:MM:SS.uuuuuu"
§ ISO 8601( "):P4DT1H15M20S
는 와동한등에 합니다.4 1:15:20
Postgre) 또는 Postgre 형식( SQL 일 - 간격 예형식간시의예▁(:(식):3 days 04:05:06
).
isodate 라이브러리를 사용하여 ISO 8601 기간 문자열을 구문 분석합니다.예:
isodate.parse_duration('PT1H5M26S')
또한 ISO 8601 기간을 시간 델타로 쉽게 변환하는 방법이 있습니까?를 참조하십시오.
:를 구분 기호로 사용하려면 다음 기능을 사용합니다.
import re
from datetime import timedelta
def timedelta_parse(value):
"""
convert input string to timedelta
"""
value = re.sub(r"[^0-9:.]", "", value)
if not value:
return
return timedelta(**{key:float(val)
for val, key in zip(value.split(":")[::-1],
("seconds", "minutes", "hours", "days"))
})
예:
In [4]: timedelta_parse("1:0:0:1")
Out[4]: datetime.timedelta(days=1, seconds=1)
In [5]: timedelta_parse("123.5")
Out[5]: datetime.timedelta(seconds=123, microseconds=500000)
In [6]: timedelta_parse("1:6:34:9.983")
Out[6]: datetime.timedelta(days=1, seconds=23649, microseconds=983000)
In [8]: timedelta_parse("23:45:00")
Out[8]: datetime.timedelta(seconds=85500)
Python 3을 사용하면 Hari Shankar의 솔루션에 대한 업데이트 버전이 여기에 있습니다.
from datetime import timedelta
import re
regex = re.compile(r'(?P<hours>\d+?)/'
r'(?P<minutes>\d+?)/'
r'(?P<seconds>\d+?)$')
def parse_time(time_str):
parts = regex.match(time_str)
if not parts:
return
parts = parts.groupdict()
print(parts)
time_params = {}
for name, param in parts.items():
if param:
time_params[name] = int(param)
return timedelta(**time_params)
import re
from datetime import timedelta
class InvalidTimeString(Exception):
"""Exception raised when the input string is not a valid time string."""
_TIME_REGEX = re.compile(r'((?P<hours>\d+?)hr)|((?P<minutes>\d+?)m)|((?P<seconds>\d+?)s)')
def parse_time(time_str: str) -> timedelta | None:
"""
Parse a time string into a timedelta object.
Args:
time_str (str): The time string to parse. This can include hours ("Xhr"), minutes ("Ym"), and seconds ("Zs").
Each component is optional and can appear in any order, but they should be separated by non-numeric characters.
Returns:
timedelta: A timedelta object representing the time in the input string.
Raises:
InvalidTimeString: If the input string is not a valid time string.
Usage:
>>> parse_time('12hr5m10s')
datetime.timedelta(seconds=43510)
>>> parse_time('12hr')
datetime.timedelta(seconds=43200)
>>> parse_time('12hr10s')
datetime.timedelta(seconds=43210)
>>> parse_time('12hr5m10s')
datetime.timedelta(seconds=43510)
>>> parse_time('5m10s12hr')
datetime.timedelta(seconds=43510)
"""
time_params = {"hours": 0, "minutes": 0, "seconds": 0}
matches = _TIME_REGEX.finditer(time_str)
if not matches:
raise InvalidTimeString(f"'{time_str}' is not a valid time string")
for match in matches:
match_dict = match.groupdict()
for name, param in match_dict.items():
if param:
time_params[name] = int(param)
return timedelta(**time_params)
그parse_time
함수는 시간 문자열을 Python time delta 개체로 구문 분석하도록 설계되었습니다.입력 시간 문자열은 시간("Xhr"), 분("Ym") 및 초("Zs")를 임의의 순서로 포함할 수 있습니다.각 구성 요소는 선택 사항이며 숫자가 아닌 문자로 구분할 수 있습니다.
함수는 이러한 시간 문자열 구성 요소와 일치할 수 있는 정규식을 정의하는 것으로 시작합니다.이 정규식에는 시간, 분 및 초에 대한 명명된 그룹이 포함되므로 나중에 이러한 값을 쉽게 추출할 수 있습니다.
다음으로 함수는 정규식의 검색기 방법을 사용하여 입력 문자열에서 모든 일치 항목을 찾습니다.이 메서드는 문자열에서 정규식 패턴이 겹치지 않는 모든 일치에 대해 일치 개체를 생성하는 반복기를 반환합니다.
그런 다음 이 함수는 각 일치 항목에 대해 반복되며 groupdict 방법을 사용하여 일치 개체를 사전으로 변환합니다.이 메서드는 일치하는 모든 명명된 그룹을 포함하는 사전을 반환하며, 그룹 이름은 키로, 일치하는 문자열은 값으로 지정합니다.
사전의 각 명명된 그룹에 대해 그룹에 값이 있는지 확인합니다.이 경우 함수는 이 값을 정수로 변환하여 적절한 키(시, 분 또는 초) 아래에 있는 time_params 사전에 저장합니다.
마지막으로, 함수는 다음을 생성합니다.timedelta
time_params 사전의 개체를 반환합니다.
이 접근 방식을 사용하면 다음과 같은 몇 가지 이점이 있습니다.
- 유연성:이 기능은 다양한 형식의 시간 문자열을 처리할 수 있으므로 다양한 상황에서 더욱 유용합니다.
- 견고성:함수에는 입력 문자열이 유효한 시간 문자열인지 확인하는 오류 검사가 포함되어 있습니다.그렇지 않은 경우 함수는 사용자 지정 예외를 발생시켜 이를 나타냅니다.
- 가독성:정규식과 명명된 그룹을 사용하면 코드를 더 읽기 쉽고 쉽게 이해할 수 있습니다.
- 효율성: 사전을 사용하여 시간 성분을 저장하고 최종 결과를 나타내는 시간 델타 객체를 사용하여 시간 계산을 보다 효율적으로 처리할 수 있습니다.
tempora.parse_timedelta(tempora에서)를 시도해 보십시오.
$ pip-run 'tempora>=4.1.1' -- -q
>>> from tempora import parse_timedelta
>>> parse_timedelta("32m")
datetime.timedelta(seconds=1920)
>>> parse_timedelta("2h32m")
datetime.timedelta(seconds=9120)
>>> parse_timedelta("4:13")
datetime.timedelta(seconds=15180)
>>> parse_timedelta("5hr34m56s")
datetime.timedelta(seconds=20096)
언급URL : https://stackoverflow.com/questions/4628122/how-to-construct-a-timedelta-object-from-a-simple-string
'programing' 카테고리의 다른 글
장고 1.7은 장고.core.exceptions를 던집니다.AppRegistryNotReady: 모델이 아직 로드되지 않았습니다. (0) | 2023.07.18 |
---|---|
Oracle에서 데이터베이스 개체가 테이블 또는 보기인지 확인하는 방법 (0) | 2023.07.18 |
기존 열에서 새 열을 생성하기 위해 적용되는 판다 성능 대 np.vectorize (0) | 2023.07.18 |
사용자 지정 데이터 주석 검증기를 만드는 방법 (0) | 2023.07.18 |
스프링 부트에서 프로필을 기반으로 선택적 테스트를 실행/해제하는 방법 (0) | 2023.07.18 |