mytime.seconds2str: small amend with speed-up, code simplification and few tests

pull/3185/head^2^2^2
sebres 2021-11-04 14:34:04 +01:00
parent ebf5784b8c
commit a57643404c
2 changed files with 43 additions and 29 deletions

View File

@ -178,34 +178,45 @@ class MyTime:
def __str__(self): def __str__(self):
# s = str(datetime.timedelta(seconds=int(self.sec))) # s = str(datetime.timedelta(seconds=int(self.sec)))
# return s if s[-3:] != ":00" else s[:-3] # return s if s[-3:] != ":00" else s[:-3]
s = self.sec; r = ""; c = 3 s = self.sec; c = 3
# automatic accuracy: round by large values (upto 1 minute, or 1 day by year): # automatic accuracy: round by large values (and maximally 3 groups)
if s >= 3570: if s >= 31536000: # a year as 365*24*60*60 (don't need to consider leap year by this accuracy)
if s >= 31536000: s = int(round(float(s)/86400)) # round by a day
s = int(round(float(s)/86400)*86400) r = str(s//365) + 'y '; s %= 365
elif s >= 86400: if s >= 7:
s = int(round(float(s)/60)*60) r += str(s//7) + 'w '; s %= 7
else: if s:
s = int(round(float(s)/10)*10) r += str(s) + 'd '
for n, m in ( return r[:-1]
('y', 31536000), # a year as 365*24*60*60 (don't need to consider leap year by this accuracy) if s >= 604800: # a week as 24*60*60*7
('w', 604800), # a week as 24*60*60*7 s = int(round(float(s)/3600)) # round by a hour
('d', 86400), # a day as 24*60*60 r = str(s//168) + 'w '; s %= 168
('h', 3600), # a hour as 60*60 if s >= 24:
('m', 60), # a minute r += str(s//24) + 'd '; s %= 24
('s', 1) # a second if s:
): r += str(s) + 'h '
if s >= m: return r[:-1]
c -= 1 if s >= 86400: # a day as 24*60*60
r += ' ' + str(s//m) + n s = int(round(float(s)/60)) # round by a minute
s %= m r = str(s//1440) + 'd '; s %= 1440
# stop if no remaining part or no repeat needed (too small granularity): if s >= 60:
if not s or not c: break r += str(s//60) + 'h '; s %= 60
elif c < 3: if s:
# avoid too small granularity: r += str(s) + 'm '
c -= 1 return r[:-1]
if not c: break if s >= 3595: # a hour as 60*60 (- 5 seconds)
# s = int(round(float(s)/10)) # round by 10 seconds
return r[1:] r = str(s//360) + 'h '; s %= 360
if s >= 6: # a minute
r += str(s//6) + 'm '; s %= 6
return r[:-1]
r = ''
if s >= 60: # a minute
r += str(s//60) + 'm '; s %= 60
if s: # remaining seconds
r += str(s) + 's '
elif not self.sec: # 0s
r = '0 '
return r[:-1]
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()

View File

@ -466,6 +466,9 @@ class MyTimeTest(unittest.TestCase):
self.assertEqual(sec2str(86400*14-10), '2w') self.assertEqual(sec2str(86400*14-10), '2w')
self.assertEqual(sec2str(86400*2+3600*7+60*15), '2d 7h 15m') self.assertEqual(sec2str(86400*2+3600*7+60*15), '2d 7h 15m')
self.assertEqual(sec2str(86400*2+3599), '2d 1h') self.assertEqual(sec2str(86400*2+3599), '2d 1h')
self.assertEqual(sec2str(3600*3.52), '3h 31m')
self.assertEqual(sec2str(3600*2-5), '2h')
self.assertEqual(sec2str(3600-5), '1h') self.assertEqual(sec2str(3600-5), '1h')
self.assertEqual(sec2str(3600-10), '59m 50s') self.assertEqual(sec2str(3600-10), '59m 50s')
self.assertEqual(sec2str(59), '59s') self.assertEqual(sec2str(59), '59s')
self.assertEqual(sec2str(0), '0')