I have the following Python functions to convert normal time into decimal time and vice versa:
import math
def std_to_dec(hour, minute, second):
dec_total_seconds = (3600*hour+60*minute+second)/0.864
dec_hour = int(str(dec_total_seconds/float(10000))[0])
dec_minute = int(str(dec_total_seconds/float(10000))[2:4])
dec_second = int(str(dec_total_seconds/float(10000))[4:6])
return [dec_hour, dec_minute, dec_second]
def dec_to_std(hour, minute, second):
std_total_seconds = (10000*hour+100*minute+second)*0.864
std_hour = math.floor(std_total_seconds/float(3600))
std_minute = math.floor((float(str(std_total_seconds/float(3600))[str(std_total_seconds/float(3600)).find('.'):]))*60)
std_minute_dec = (float(str(std_total_seconds/float(3600))[str(std_total_seconds/float(3600)).find('.'):]))*60
std_second = math.floor((float(str(std_minute_dec)[str(std_minute_dec).find('.'):]))*60)
return [std_hour, std_minute, std_second]
When I do print(std_to_dec(18, 21, 47))
I get [7, 65, 12]
, which is all fine. But when I try to do it vice versa, print(dec_to_std(7, 65, 12))
, I get [18, 21, 46]
, which is not the same.
Additionally, std_to_dec(0, 0, 0)
returns the error:
dec_second = int(str(dec_total_seconds/float(10000))[4:6]) ValueError: invalid literal for int() with base 10: ''
dec_to_std(0, 0, 0)
works though.
By using the string representation your code expects to have a string with at least 6 characters (which is not always the case) and ignores any characters from the 7th character onwards, losing precision, and leading to differences when converting back.
A core problem however is that standard time has 60*60*24 = 86400 possible times, while decimal time has 10*100*100 = 100000 (more) possible times. By consequence there is no 1-to-1 mapping possible, as then you would need an equal number of possibilities at both sides. However, as standard time has less possibilities, it must be possible to do that mapping as you require, but that means that some possibilities for decimal time will not occur.
Here is what you could use to always get the same standard time back when having it converted to decimal time and back:
def std_to_dec(hour, minute, second):
dec = round((3600*hour+60*minute+second)/0.864)
dec_second = dec % 100
dec //= 100
dec_minute = dec % 100
dec //= 100
dec_hour = dec
return [dec_hour, dec_minute, dec_second]
def dec_to_std(hour, minute, second):
std = round((10000*hour+100*minute+second)*0.864)
std_second = std % 60
std //= 60
std_minute = std % 60
std //= 60
std_hour = std
return [std_hour, std_minute, std_second]
With this solution it is not possible to expect the inverse: there are decimal times such that if you would convert them to standard time and back, they don't result in the same decimal time. Again, this is because there are more decimal times than standard times (when only using integers of course).
For instance:
std_to_dec(0, 0, 3) == [0, 0, 3]
std_to_dec(0, 0, 4) == [0, 0, 5]
This means that decimal time [0, 0, 4] will not occur, and also means that if you do the inverse, starting with that decimal time, you cannot get it back:
dec_to_std(0, 0, 4) == [0, 0, 3]