Converting fractional days to H:M:S.MS - Two examples
Of the two methods of calculating a fractional day to local time, which one would you consider the best way and why?
Edit: 'Fractional day' means here the decimal part of a Julian day jd: jd - (math.floor(jd - 0.5) + 0.5)
(this is because 0:00:00 is at jd.5)
@classmethod
def fromfractional(cls, frac, **kwargs):
changed = False
f = lambda x: decimal.dec(floor(x))
if not isinstance(frac, decimal.Decimal):
frac = decimal.dec(frac)
hours = decimal.dec(D24 * (frac - f(frac)))
if hours < 1:
hours += 1 # Or else microseconds won't be calculated correctly
changed = True
minutes = decimal.dec(D60 * (hours - f(hours)))
seconds = decimal.dec(D60 * (minutes - f(minutes)))
ms = decimal.dec(DKS * (seconds - f(seconds)))
if changed:
hours -= 1
return int(hours), int(minutes), int(seconds), int(ms)
@classmethod
def fromfractional2(cls, x):
d = lambda x: decimal.Decimal(str(x))
total = d(x) * d(86400000000000)
hours = (total - (total % d(3600000000000))) / d(3600000000000)
total = total % d(3600000000000)
minutes = (total - (total % d(60000000000))) / d(60000000000)
total = total % d(60000000000)
seconds = (total - (total % d(1000000000))) / d(1000000000)
total = total % d(1000000000)
ms = (total - (total % d(1000000))) / d(1000000)
total = total % d(1000000)
mics = (total - (total % d(1000))) / d(1000)
return int(hours), int(minutes), int(seconds), int(ms)
D24 = decimal.Decimal('24')
DMS = decimal.Decimal('86400000.0')
D60 = decimal.Decimal('60')
D3600 = decimal.Decimal('3600')
D1440=decimal.Decimal('1400')
DKS=decima开发者_开发技巧l.Decimal('1000')
DTS=decimal.Decimal('86400')
I think you are trying to get from something like:
1.2256 days
To:
1 day, 5 hours, 24 minutes, 51 seconds
but with microseconds, too?
Here's how I generated the above response:
def nice_repr(timedelta, display="long"):
"""
Turns a datetime.timedelta object into a nice string repr.
display can be "minimal", "short" or "long" [default].
>>> from datetime import timedelta as td
>>> nice_repr(td(days=1, hours=2, minutes=3, seconds=4))
'1 day, 2 hours, 3 minutes, 4 seconds'
>>> nice_repr(td(days=1, seconds=1), "minimal")
'1d, 1s'
"""
assert isinstance(timedelta, datetime.timedelta), "First argument must be a timedelta."
result = ""
weeks = timedelta.days / 7
days = timedelta.days % 7
hours = timedelta.seconds / 3600
minutes = (timedelta.seconds % 3600) / 60
seconds = timedelta.seconds % 60
if display == 'minimal':
words = ["w", "d", "h", "m", "s"]
elif display == 'short':
words = [" wks", " days", " hrs", " min", " sec"]
else:
words = [" weeks", " days", " hours", " minutes", " seconds"]
values = [weeks, days, hours, minutes, seconds]
for i in range(len(values)):
if values[i]:
if values[i] == 1 and len(words[i]) > 1:
result += "%i%s, " % (values[i], words[i].rstrip('s'))
else:
result += "%i%s, " % (values[i], words[i])
return result[:-2]
精彩评论