날짜/시간 개체의 분 단위 반올림 방법
나는 있습니다datetime
사하여생개체를 사용하여 제작된 strptime()
.
>>> tm
datetime.datetime(2010, 6, 10, 3, 56, 23)
제가 해야 할 일은 1분을 가장 가까운 10분으로 돌리는 것입니다.제가 지금까지 해온 것은 분값을 취하여 반올림()을 사용하는 것이었습니다.
min = round(tm.minute, -1)
그러나 위의 예와 마찬가지로 분 값이 56보다 클 때 잘못된 시간을 제공합니다. 즉, 3:60
이것을 하는 더 좋은 방법은 무엇입니까? 있습니까?datetime
이것을 지지합니까?
이것은 '바닥'을 얻을 것입니다.datetime
tm 앞의 입니다.tm
.
tm = tm - datetime.timedelta(minutes=tm.minute % 10,
seconds=tm.second,
microseconds=tm.microsecond)
클래식 반올림을 가장 가까운 10분 표시로 하려면 다음을 수행합니다.
discard = datetime.timedelta(minutes=tm.minute % 10,
seconds=tm.second,
microseconds=tm.microsecond)
tm -= discard
if discard >= datetime.timedelta(minutes=5):
tm += datetime.timedelta(minutes=10)
또는 다음과 같습니다.
tm += datetime.timedelta(minutes=5)
tm -= datetime.timedelta(minutes=tm.minute % 10,
seconds=tm.second,
microseconds=tm.microsecond)
모든 시간 경과 시 날짜 시간을 초 단위로 반올림하는 일반 기능:
def roundTime(dt=None, roundTo=60):
"""Round a datetime object to any time lapse in seconds
dt : datetime.datetime object, default now.
roundTo : Closest number of seconds to round to, default 1 minute.
Author: Thierry Husson 2012 - Use it as you want but don't blame me.
"""
if dt == None : dt = datetime.datetime.now()
seconds = (dt.replace(tzinfo=None) - dt.min).seconds
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)
1시간 반올림 및 반올림 시간이 30분인 표본:
print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=60*60)
2013-01-01 00:00:00
print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=30*60)
2012-12-31 23:30:00
Stijn Nevens 코드(Stijn 감사합니다)를 사용했고 공유할 약간의 추가 기능이 있습니다.반올림, 반올림 및 가장 가까운 반올림.
업데이트 2019-03-09 = 댓글 Spinxz 통합; 감사합니다.
업데이트 2019-12-27 = 댓글 바트 통합; 감사합니다.
date_delta가 "X시간", "X분" 또는 "X초"인지 테스트했습니다.
import datetime
def round_time(dt=None, date_delta=datetime.timedelta(minutes=1), to='average'):
"""
Round a datetime object to a multiple of a timedelta
dt : datetime.datetime object, default now.
dateDelta : timedelta object, we round to a multiple of this, default 1 minute.
from: http://stackoverflow.com/questions/3463930/how-to-round-the-minute-of-a-datetime-object-python
"""
round_to = date_delta.total_seconds()
if dt is None:
dt = datetime.now()
seconds = (dt - dt.min).seconds
if seconds % round_to == 0 and dt.microsecond == 0:
rounding = (seconds + round_to / 2) // round_to * round_to
else:
if to == 'up':
# // is a floor division, not a comment on following line (like in javascript):
rounding = (seconds + dt.microsecond/1000000 + round_to) // round_to * round_to
elif to == 'down':
rounding = seconds // round_to * round_to
else:
rounding = (seconds + round_to / 2) // round_to * round_to
return dt + datetime.timedelta(0, rounding - seconds, - dt.microsecond)
# test data
print(round_time(datetime.datetime(2019,11,1,14,39,00), date_delta=datetime.timedelta(seconds=30), to='up'))
print(round_time(datetime.datetime(2019,11,2,14,39,00,1), date_delta=datetime.timedelta(seconds=30), to='up'))
print(round_time(datetime.datetime(2019,11,3,14,39,00,776980), date_delta=datetime.timedelta(seconds=30), to='up'))
print(round_time(datetime.datetime(2019,11,4,14,39,29,776980), date_delta=datetime.timedelta(seconds=30), to='up'))
print(round_time(datetime.datetime(2018,11,5,14,39,00,776980), date_delta=datetime.timedelta(seconds=30), to='down'))
print(round_time(datetime.datetime(2018,11,6,14,38,59,776980), date_delta=datetime.timedelta(seconds=30), to='down'))
print(round_time(datetime.datetime(2017,11,7,14,39,15), date_delta=datetime.timedelta(seconds=30), to='average'))
print(round_time(datetime.datetime(2017,11,8,14,39,14,999999), date_delta=datetime.timedelta(seconds=30), to='average'))
print(round_time(datetime.datetime(2019,11,9,14,39,14,999999), date_delta=datetime.timedelta(seconds=30), to='up'))
print(round_time(datetime.datetime(2012,12,10,23,44,59,7769),to='average'))
print(round_time(datetime.datetime(2012,12,11,23,44,59,7769),to='up'))
print(round_time(datetime.datetime(2010,12,12,23,44,59,7769),to='down',date_delta=datetime.timedelta(seconds=1)))
print(round_time(datetime.datetime(2011,12,13,23,44,59,7769),to='up',date_delta=datetime.timedelta(seconds=1)))
print(round_time(datetime.datetime(2012,12,14,23,44,59),date_delta=datetime.timedelta(hours=1),to='down'))
print(round_time(datetime.datetime(2012,12,15,23,44,59),date_delta=datetime.timedelta(hours=1),to='up'))
print(round_time(datetime.datetime(2012,12,16,23,44,59),date_delta=datetime.timedelta(hours=1)))
print(round_time(datetime.datetime(2012,12,17,23,00,00),date_delta=datetime.timedelta(hours=1),to='down'))
print(round_time(datetime.datetime(2012,12,18,23,00,00),date_delta=datetime.timedelta(hours=1),to='up'))
print(round_time(datetime.datetime(2012,12,19,23,00,00),date_delta=datetime.timedelta(hours=1)))
내가 datetime 객체만을 사용하여 수정한 최적의 답변에서 초 단위로 변환할 필요가 없으며 호출 코드를 더 읽기 쉽게 만듭니다.
def roundTime(dt=None, dateDelta=datetime.timedelta(minutes=1)):
"""Round a datetime object to a multiple of a timedelta
dt : datetime.datetime object, default now.
dateDelta : timedelta object, we round to a multiple of this, default 1 minute.
Author: Thierry Husson 2012 - Use it as you want but don't blame me.
Stijn Nevens 2014 - Changed to use only datetime objects as variables
"""
roundTo = dateDelta.total_seconds()
if dt == None : dt = datetime.datetime.now()
seconds = (dt - dt.min).seconds
# // is a floor division, not a comment on following line:
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)
반올림이 1시간이고 반올림이 15분인 표본:
print roundTime(datetime.datetime(2012,12,31,23,44,59),datetime.timedelta(hour=1))
2013-01-01 00:00:00
print roundTime(datetime.datetime(2012,12,31,23,44,49),datetime.timedelta(minutes=15))
2012-12-31 23:30:00
판다는 날짜/시간 원형 기능이 있지만 판다의 대부분과 마찬가지로 시리즈 형식이어야 합니다.
>>> ts = pd.Series(pd.date_range(Dt(2019,1,1,1,1),Dt(2019,1,1,1,4),periods=8))
>>> print(ts)
0 2019-01-01 01:01:00.000000000
1 2019-01-01 01:01:25.714285714
2 2019-01-01 01:01:51.428571428
3 2019-01-01 01:02:17.142857142
4 2019-01-01 01:02:42.857142857
5 2019-01-01 01:03:08.571428571
6 2019-01-01 01:03:34.285714285
7 2019-01-01 01:04:00.000000000
dtype: datetime64[ns]
>>> ts.dt.round('1min')
0 2019-01-01 01:01:00
1 2019-01-01 01:01:00
2 2019-01-01 01:02:00
3 2019-01-01 01:02:00
4 2019-01-01 01:03:00
5 2019-01-01 01:03:00
6 2019-01-01 01:04:00
7 2019-01-01 01:04:00
dtype: datetime64[ns]
문서 - 필요에 따라 주파수 문자열을 변경합니다.
부동 소수점 정밀도 문제와 외부 라이브러리 종속성이 없는 보다 단순한 일반화 솔루션은 다음과 같습니다.
import datetime
def time_mod(time, delta, epoch=None):
if epoch is None:
epoch = datetime.datetime(1970, 1, 1, tzinfo=time.tzinfo)
return (time - epoch) % delta
def time_round(time, delta, epoch=None):
mod = time_mod(time, delta, epoch)
if mod < delta / 2:
return time - mod
return time + (delta - mod)
def time_floor(time, delta, epoch=None):
mod = time_mod(time, delta, epoch)
return time - mod
def time_ceil(time, delta, epoch=None):
mod = time_mod(time, delta, epoch)
if mod:
return time + (delta - mod)
return time
당신의 경우:
>>> tm = datetime.datetime(2010, 6, 10, 3, 56, 23)
>>> time_round(tm, datetime.timedelta(minutes=10))
datetime.datetime(2010, 6, 10, 4, 0)
>>> time_floor(tm, datetime.timedelta(minutes=10))
datetime.datetime(2010, 6, 10, 3, 50)
>>> time_ceil(tm, datetime.timedelta(minutes=10))
datetime.datetime(2010, 6, 10, 4, 0)
을 사용하면 .modulo
연산자:
minutes = int(round(tm.minute, -1)) % 60
갱신하다
당신은 이런 것을 원했나요?
def timeround10(dt):
a, b = divmod(round(dt.minute, -1), 60)
return '%i:%02i' % ((dt.hour + a) % 24, b)
timeround10(datetime.datetime(2010, 1, 1, 0, 56, 0)) # 0:56
# -> 1:00
timeround10(datetime.datetime(2010, 1, 1, 23, 56, 0)) # 23:56
# -> 0:00
결과를 문자열로 원하는 경우.datetime 결과를 얻으려면 time delta를 사용하는 것이 좋습니다 - 다른 응답 참조 ;)
저는 이것을 사용하고 있어요.tz 인식 날짜 시간으로 작업할 수 있는 장점이 있습니다.
def round_minutes(some_datetime: datetime, step: int):
""" round up to nearest step-minutes """
if step > 60:
raise AttrbuteError("step must be less than 60")
change = timedelta(
minutes= some_datetime.minute % step,
seconds=some_datetime.second,
microseconds=some_datetime.microsecond
)
if change > timedelta():
change -= timedelta(minutes=step)
return some_datetime - change
1시간 미만의 시간 동안만 작동하는 단점이 있습니다.
간단한 접근 방식:
def round_time(dt, round_to_seconds=60):
"""Round a datetime object to any number of seconds
dt: datetime.datetime object
round_to_seconds: closest number of seconds for rounding, Default 1 minute.
"""
rounded_epoch = round(dt.timestamp() / round_to_seconds) * round_to_seconds
rounded_dt = datetime.datetime.fromtimestamp(rounded_epoch).astimezone(dt.tzinfo)
return rounded_dt
이걸로 충분해요, 라운드를 아주 유용하게 사용하는 것 같아요.
from typing import Literal
import math
def round_datetime(dt: datetime.datetime, step: datetime.timedelta, d: Literal['no', 'up', 'down'] = 'no'):
step = step.seconds
round_f = {'no': round, 'up': math.ceil, 'down': math.floor}
return datetime.datetime.fromtimestamp(step * round_f[d](dt.timestamp() / step))
date = datetime.datetime(year=2022, month=11, day=16, hour=10, minute=2, second=30, microsecond=424242)#
print('Original:', date)
print('Standard:', round_datetime(date, datetime.timedelta(minutes=5)))
print('Down: ', round_datetime(date, datetime.timedelta(minutes=5), d='down'))
print('Up: ', round_datetime(date, datetime.timedelta(minutes=5), d='up'))
결과:
Original: 2022-11-16 10:02:30.424242
Standard: 2022-11-16 10:05:00
Down: 2022-11-16 10:00:00
Up: 2022-11-16 10:05:00
예, 데이터가 팬더 시리즈의 날짜/시간 열에 속하는 경우 내장된 팬더를 사용하여 반올림할 수 있습니다.Series.dt.round 함수입니다.팬더에 대한 설명서는 여기를 참조하십시오.시리즈.dt.라운드.10분으로 반올림하는 경우 다음과 같이 Series.dt.round('10min') 또는 Series.dt.round('600s')가 됩니다.
pandas.Series(tm).dt.round('10min')
예제 코드를 추가하려면 편집:
import datetime
import pandas
tm = datetime.datetime(2010, 6, 10, 3, 56, 23)
tm_rounded = pandas.Series(tm).dt.round('10min')
print(tm_rounded)
>>> 0 2010-06-10 04:00:00
dtype: datetime64[ns]
저는 이 매우 간단한 기능을 생각해냈습니다. 60초의 배수나 분할이 가능한 모든 시간 델타를 연구했습니다.또한 표준 시간대 인식 날짜 시간과도 호환됩니다.
#!/usr/env python3
from datetime import datetime, timedelta
def round_dt_to_delta(dt, delta=timedelta(minutes=30)):
ref = datetime.min.replace(tzinfo=dt.tzinfo)
return ref + round((dt - ref) / delta) * delta
출력:
In [1]: round_dt_to_delta(datetime(2012,12,31,23,44,49), timedelta(seconds=15))
Out[1]: datetime.datetime(2012, 12, 31, 23, 44, 45)
In [2]: round_dt_to_delta(datetime(2012,12,31,23,44,49), timedelta(minutes=15))
Out[2]: datetime.datetime(2012, 12, 31, 23, 45)
시간(분)을 반올림하는 일반 기능:
from datetime import datetime
def round_minute(date: datetime = None, round_to: int = 1):
"""
round datetime object to minutes
"""
if not date:
date = datetime.now()
date = date.replace(second=0, microsecond=0)
delta = date.minute % round_to
return date.replace(minute=date.minute - delta)
그것들은 너무 복잡해 보입니다.
def round_down_to():
num = int(datetime.utcnow().replace(second=0, microsecond=0).minute)
return num - (num%10)
def get_rounded_datetime(self, dt, freq, nearest_type='inf'):
if freq.lower() == '1h':
round_to = 3600
elif freq.lower() == '3h':
round_to = 3 * 3600
elif freq.lower() == '6h':
round_to = 6 * 3600
else:
raise NotImplementedError("Freq %s is not handled yet" % freq)
# // is a floor division, not a comment on following line:
seconds_from_midnight = dt.hour * 3600 + dt.minute * 60 + dt.second
if nearest_type == 'inf':
rounded_sec = int(seconds_from_midnight / round_to) * round_to
elif nearest_type == 'sup':
rounded_sec = (int(seconds_from_midnight / round_to) + 1) * round_to
else:
raise IllegalArgumentException("nearest_type should be 'inf' or 'sup'")
dt_midnight = datetime.datetime(dt.year, dt.month, dt.day)
return dt_midnight + datetime.timedelta(0, rounded_sec)
Stijn Nevens를 기반으로 현재 시간을 가장 가까운 15분으로 반올림하도록 Django용으로 수정되었습니다.
from datetime import date, timedelta, datetime, time
def roundTime(dt=None, dateDelta=timedelta(minutes=1)):
roundTo = dateDelta.total_seconds()
if dt == None : dt = datetime.now()
seconds = (dt - dt.min).seconds
# // is a floor division, not a comment on following line:
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + timedelta(0,rounding-seconds,-dt.microsecond)
dt = roundTime(datetime.now(),timedelta(minutes=15)).strftime('%H:%M:%S')
dt = 11:45:00
전체 날짜와 시간이 필요하면 제거하십시오..strftime('%H:%M:%S')
예외가 발생할 경우 속도에 가장 적합하지는 않지만, 이것은 효과적입니다.
def _minute10(dt=datetime.utcnow()):
try:
return dt.replace(minute=round(dt.minute, -1))
except ValueError:
return dt.replace(minute=0) + timedelta(hours=1)
타이밍
%timeit _minute10(datetime(2016, 12, 31, 23, 55))
100000 loops, best of 3: 5.12 µs per loop
%timeit _minute10(datetime(2016, 12, 31, 23, 31))
100000 loops, best of 3: 2.21 µs per loop
주어진 시간 단위(여기서 초)로 반올림할 수 있는 두 줄 직관적인 솔루션datetime
물건t
:
format_str = '%Y-%m-%d %H:%M:%S'
t_rounded = datetime.strptime(datetime.strftime(t, format_str), format_str)
다른 단위로 반올림하려면 간단히 변경format_str
.
이 접근 방식은 위의 방법처럼 임의의 시간 양으로 반올림하는 것이 아니라 주어진 시간, 분 또는 초로 반올림하는 훌륭한 파이썬 방식입니다.
기타 솔루션:
def round_time(timestamp=None, lapse=0):
"""
Round a timestamp to a lapse according to specified minutes
Usage:
>>> import datetime, math
>>> round_time(datetime.datetime(2010, 6, 10, 3, 56, 23), 0)
datetime.datetime(2010, 6, 10, 3, 56)
>>> round_time(datetime.datetime(2010, 6, 10, 3, 56, 23), 1)
datetime.datetime(2010, 6, 10, 3, 57)
>>> round_time(datetime.datetime(2010, 6, 10, 3, 56, 23), -1)
datetime.datetime(2010, 6, 10, 3, 55)
>>> round_time(datetime.datetime(2019, 3, 11, 9, 22, 11), 3)
datetime.datetime(2019, 3, 11, 9, 24)
>>> round_time(datetime.datetime(2019, 3, 11, 9, 22, 11), 3*60)
datetime.datetime(2019, 3, 11, 12, 0)
>>> round_time(datetime.datetime(2019, 3, 11, 10, 0, 0), 3)
datetime.datetime(2019, 3, 11, 10, 0)
:param timestamp: Timestamp to round (default: now)
:param lapse: Lapse to round in minutes (default: 0)
"""
t = timestamp or datetime.datetime.now() # type: Union[datetime, Any]
surplus = datetime.timedelta(seconds=t.second, microseconds=t.microsecond)
t -= surplus
try:
mod = t.minute % lapse
except ZeroDivisionError:
return t
if mod: # minutes % lapse != 0
t += datetime.timedelta(minutes=math.ceil(t.minute / lapse) * lapse - t.minute)
elif surplus != datetime.timedelta() or lapse < 0:
t += datetime.timedelta(minutes=(t.minute / lapse + 1) * lapse - t.minute)
return t
이것이 도움이 되길 바랍니다!
내가 아는 가장 짧은 길은
min = tm.minute // 10 * 10
대부분의 답은 그렇게 간단한 질문을 하기에는 너무 복잡한 것 같습니다.
가정하면your_time
날짜/시간 객체이며, 분 단위로 정의된 원하는 해상도로 다음 라운드(304층)를 수행합니다.
from math import floor
your_time = datetime.datetime.now()
g = 10 # granularity in minutes
print(
datetime.datetime.fromtimestamp(
floor(your_time.timestamp() / (60*g)) * (60*g)
))
최소 가져오기 기능을 가진 아래의 기능이 작업을 수행할 것입니다.te 매개변수 unit, rnd, frm을 설정하여 원하는 값으로 반올림할 수 있습니다.기능을 가지고 놀면 얼마나 쉬울지 알 수 있습니다.
def toNearestTime(ts, unit='sec', rnd=1, frm=None):
''' round to nearest Time format
param ts = time string to round in '%H:%M:%S' or '%H:%M' format :
param unit = specify unit wich must be rounded 'sec' or 'min' or 'hour', default is seconds :
param rnd = to which number you will round, the default is 1 :
param frm = the output (return) format of the time string, as default the function take the unit format'''
from time import strftime, gmtime
ts = ts + ':00' if len(ts) == 5 else ts
if 'se' in unit.lower():
frm = '%H:%M:%S' if frm is None else frm
elif 'm' in unit.lower():
frm = '%H:%M' if frm is None else frm
rnd = rnd * 60
elif 'h' in unit.lower():
frm = '%H' if frm is None else frm
rnd = rnd * 3600
secs = sum(int(x) * 60 ** i for i, x in enumerate(reversed(ts.split(':'))))
rtm = int(round(secs / rnd, 0) * rnd)
nt = strftime(frm, gmtime(rtm))
return nt
다음과 같은 통화 기능: 다음과 같은 기본 출력 형식 = hh:mm로 가장 가까운 5분간 반올림
ts = '02:27:29'
nt = toNearestTime(ts, unit='min', rnd=5)
print(nt)
output: '02:25'
또는 다음과 같이 출력 형식 hh:mm:ss를 사용하여 가장 가까운 시간으로 반올림합니다.
ts = '10:30:01'
nt = toNearestTime(ts, unit='hour', rnd=1, frm='%H:%M:%S')
print(nt)
output: '11:00:00'
언급URL : https://stackoverflow.com/questions/3463930/how-to-round-the-minute-of-a-datetime-object
'IT' 카테고리의 다른 글
로그아웃 시 JWT 토큰을 폐기하는 방법은 무엇입니까? (0) | 2023.09.05 |
---|---|
인라인/인라인 블록 요소의 CSS 수직 정렬 (0) | 2023.09.05 |
JQuery를 사용하여 이벤트를 발생시킨 요소의 클래스 가져오기 (0) | 2023.08.31 |
사용자 입력을 가져오는 중 (0) | 2023.08.31 |
MySQL "::1" 호스트 이름은 무엇을 의미합니까? (0) | 2023.08.31 |