diff --git a/sarracenia/__init__.py b/sarracenia/__init__.py index 261a35dd8..393c0b8aa 100755 --- a/sarracenia/__init__.py +++ b/sarracenia/__init__.py @@ -316,6 +316,13 @@ def timev2tov3str(s): else: return s[0:8] + 'T' + s[8:] +""" + So for natural delta, tested stuff, and empirically it looks like humanize thinks this is how many days there are in a month. + At least assuming that makes calculations here match with what humanize does. + +""" +days_in_a_month=30.7 + def durationToString(d) -> str: """ given a numbner of seconds, return a short, human readable string. @@ -323,21 +330,35 @@ def durationToString(d) -> str: if (d < 60): return f"{d:7.2f}s" - first_part= humanize.naturaldelta(d).replace("minutes","m").replace("seconds","s").replace("hours","h").replace("days","d").replace("an hour","1h").replace("a day","1d").replace("a minute","1m").replace(" ","") - - second_part="" - if first_part[-1] == 'm': - rem=int(d-int(first_part[0:-1])*60) - if rem > 0: - second_part=f"{rem:d}s" - if first_part[-1] == 'h': - rem=int(( d-int(first_part[0:-1])*60*60 ) / 60 ) - if rem > 0: - second_part=f"{rem:d}m" - if first_part[-1] == 'd': - rem=int (( d-int(first_part[0:-1])*60*60*24 ) / (60*60) ) - if rem > 0: - second_part=f"{rem:d}h" + hnd = humanize.naturaldelta(d).replace("minute","m").replace("second","T").replace("hour","h").replace("day","d").replace("month","M").replace("year","y").replace(" ","").replace("s","").replace("T","s").replace("an", "1").replace("a","1") + + if ',' in hnd: + ( first_part, second_part ) = hnd.split(',') + else: + first_part=hnd + second_part="" + + if not second_part: + if first_part[-1] == 'm': + rem=int(d-int(first_part[0:-1])*60) + if rem > 0: + second_part=f"{rem:d}s" + if first_part[-1] == 'h': + rem=int(( d-int(first_part[0:-1])*60*60 ) / 60 ) + if rem > 0: + second_part=f"{rem:d}m" + if first_part[-1] == 'd': + rem=int (( d-int(first_part[0:-1])*60*60*24 ) / (60*60) ) + if rem > 0: + second_part=f"{rem:d}h" + if first_part[-1] == 'M': + rem=int (( d-int(first_part[0:-1])*60*60*24*days_in_a_month ) / (60*60*24) ) + if rem > 0: + second_part=f"{rem:d}d" + if first_part[-1] == 'y': + rem=int (( d-int(first_part[0:-1])*60*60*24*365.25 ) / (60*60*24*days_in_a_month ) ) + if rem > 0: + second_part=f"{rem:d}M" return first_part+second_part def durationToSeconds(str_value, default=None) -> float: @@ -364,7 +385,7 @@ def durationToSeconds(str_value, default=None) -> float: return float(default) first_unit=None - second_unit=str_value[-1].lower() + second_unit=str_value[-1] if second_unit in 's': factor *= 1 first_unit='m' @@ -376,9 +397,16 @@ def durationToSeconds(str_value, default=None) -> float: first_unit='d' elif second_unit in 'd': factor *= 60 * 60 * 24 - first_unit='w' - elif second_unit in 'w': - factor *= 60 * 60 * 24 * 7 + if 'y' in str_value: + first_unit='y' + else: + first_unit='M' + elif second_unit in 'M': + factor *= 60 * 60 * 24 * days_in_a_month + if 'y' in str_value: + first_unit='y' + elif second_unit in 'y': + factor *= 60 * 60 * 24 * 365.25 if str_value[-1].isalpha(): str_value = str_value[:-1] @@ -392,8 +420,10 @@ def durationToSeconds(str_value, default=None) -> float: big = big*60*60 elif first_unit == 'd': big = big*60*60*24 - elif first_unit == 'w': - big = big*60*60*24*7 + elif first_unit == 'M': + big = big*60*60*24*days_in_a_month + elif first_unit == 'y': + big = big*60*60*24*365.25 str_value = little else: big=0 diff --git a/tests/sarracenia/__init___test.py b/tests/sarracenia/__init___test.py index 64f6fb2dc..753db8ca5 100644 --- a/tests/sarracenia/__init___test.py +++ b/tests/sarracenia/__init___test.py @@ -32,12 +32,11 @@ def test_durationToSeconds(): assert sarracenia.durationToSeconds('none') == sarracenia.durationToSeconds('off') == sarracenia.durationToSeconds('false') == 0.0 assert sarracenia.durationToSeconds('on', default=10) == sarracenia.durationToSeconds('true', default=10) == 10.0 - assert sarracenia.durationToSeconds('1s') == sarracenia.durationToSeconds('1S') == 1.0 - assert sarracenia.durationToSeconds('2m') == sarracenia.durationToSeconds('2M') == 120.0 - assert sarracenia.durationToSeconds('3h') == sarracenia.durationToSeconds('3H') == 10800.0 - assert sarracenia.durationToSeconds('4d') == sarracenia.durationToSeconds('4D') == 345600.0 - assert sarracenia.durationToSeconds('1w') == sarracenia.durationToSeconds('1W') == 604800.0 - assert sarracenia.durationToSeconds('0.5h') == sarracenia.durationToSeconds('0.5H') == 1800.0 + assert sarracenia.durationToSeconds('1s') == 1.0 + assert sarracenia.durationToSeconds('2m') == 120.0 + assert sarracenia.durationToSeconds('3h') == 10800.0 + assert sarracenia.durationToSeconds('4d') == 345600.0 + assert sarracenia.durationToSeconds('0.5h') == 1800.0 assert sarracenia.durationToSeconds('invalid') == 0.0 assert sarracenia.durationToSeconds(b'5') == 0.0 @@ -45,11 +44,16 @@ def test_durationToSeconds(): assert sarracenia.durationToSeconds(2.5) == 2.5 assert sarracenia.durationToSeconds('1s', default=None) == 1.0 - assert sarracenia.durationToSeconds('1y') == 1.0 assert sarracenia.durationToSeconds('-1s') == -1.0 assert sarracenia.durationToSeconds('-1.5h') == -5400.0 assert sarracenia.durationToSeconds('2h2m') == 7320 assert sarracenia.durationToSeconds('3m2s') == 182 + assert sarracenia.durationToSeconds( '6M1d' ) == 16001280.0 + assert sarracenia.durationToSeconds( '6M5d' ) == 16346880.0 + assert sarracenia.durationToSeconds( '1y' ) == 31557600.0 + assert sarracenia.durationToSeconds( '1y28d' ) == 33976800.0 + assert sarracenia.durationToSeconds( '1y1M' ) == 34210080.0 + def test_durationToString(): assert sarracenia.durationToString( 3600 ) == '1h' @@ -58,6 +62,14 @@ def test_durationToString(): assert sarracenia.durationToString( 6*3600 ) == '6h' assert sarracenia.durationToString( 6*3600+120 ) == '6h2m' assert sarracenia.durationToString( 26*3600+120 ) == '1d2h' + assert sarracenia.durationToString( 30*24*3600 ) == '30d' + assert sarracenia.durationToString( 35*24*3600 ) == '1M4d' + assert sarracenia.durationToString( 182*24*3600 ) == '5M28d' + assert sarracenia.durationToString( 186*24*3600 ) == '6M1d' + assert sarracenia.durationToString( 190*24*3600 ) == '6M5d' + assert sarracenia.durationToString( 365*24*3600 ) == '1y' + assert sarracenia.durationToString( 393*24*3600 ) == '1y28d' + assert sarracenia.durationToString( 396*24*3600 ) == '1y1M' def test_timeValidate(): assert sarracenia.timeValidate('20230710120000') == True