将日期 (YYYY MM DD HH:MM:SS) 转换为小数日 (YYYY MM DD.ddddd)
Convert Date (YYYY MM DD HH:MM:SS) to Decimal Day (YYYY MM DD.ddddd)
我构建了一个脚本,它在 telescope 处获取观察的日期和时间,并将其转换为仅带小数点的日期。该脚本还采用一半的曝光时间并将其添加到小数日,以便我可以获得最准确的天文计算。然后提交给只接受年月观测时间的小行星中心 Day.XXXXX 最精确到小数点后5位的方法是什么?这是我目前使用的方式,是的,它非常混乱,但它确实让我得到了小数日。有时它在时间转换中会偏移一秒。
expmpc = float.("10")
utcstartmpc = "05:45:19.03"
datempc = "2015-02-14"
ddexposure = expmpc/(60.0*60.0*24.0)
ddexposure = round(ddexposure, 5)
seconds = int(utcstartmpc[6:8]) / 60.0
minutes = (int(utcstartmpc[3:5]) + seconds) / 60
hours = (int(utcstartmpc[:2]) + minutes) / 24
hours = round(hours, 5)
expadd = str(hours + ddexposure)
datempc = datempc.replace("-", " ")
utcmpc = "C%s%s" % (datempc, expadd[1:])
utcmpc = utcmpc.ljust(17, "0")
如您所见,这非常混乱,涉及对大量数据进行四舍五入,我相信四舍五入会降低准确性。代码的完成结果留下了这样的时间:
C2015 02 14.23986
有没有更好用的模块?
感谢您的帮助。
这是使用更多内置 time/date 模块的东西(我 认为 它可以满足您的需求):
import time
import datetime
def my_date_converter(date_in):
parse_str, _ = date_in.split(".")
date_str, time_str = parse_str.split(" ")
parsed_time = time.strptime(time_str, "%H:%M:%S")
total_seconds = datetime.timedelta(hours=parsed_time.tm_hour,minutes=parsed_time.tm_min,seconds=parsed_time.tm_sec).total_seconds()
seconds_in_day = 86400.0
decimal_seconds = total_seconds / seconds_in_day
utcmpc = "C%s%s" % (date_str.replace("-", " "), str(round(decimal_seconds, 5))[1:])
utcmpc = utcmpc.ljust(17, "0")
return utcmpc
def main():
to_convert = "2015-02-14 05:45:19.03"
converted = my_date_converter(to_convert)
print "%s => %s" % (to_convert, converted)
if __name__ == '__main__':
main()
示例输出:2015-02-14 05:45:19.03 => C2015 02 14.23980
你试过优秀的astropy库了吗?他们有一个处理时间和转化的包:astropy.time
您可以将您的问题分成 2 个任务:
- 从输入
expmpc
、utcstartmpc
、datempc
获取表示 UTC 时间的对象
- 将日期时间对象转换为
Year Month Day.XXXXX
格式的字符串。
从输入expmpc
、utcstartmpc
、datempc
中获取datetime
对象
from datetime import datetime, timedelta
expmpc = "10"
utcstartmpc = "05:45:19.03"
datempc = "2015-02-14"
dt = datetime.strptime(datempc + " " + utcstartmpc, "%Y-%m-%d %H:%M:%S.%f")
dt += timedelta(seconds=int(expmpc))
将 datetime
对象转换为 Year Month Day.XXXXX
格式的字符串
from datetime import datetime, time, timedelta
s = dt.strftime("C%Y %m %d.")
day_fraction = dt - datetime.combine(dt, time.min)
s += ("%.0f" % (100000*day_fraction / timedelta(days=1)))
# -> C2015 02 14.23992
注意:结果与您问题中的结果略有不同(92
vs. 最后的 86
)。
在Python2中,需要将td / timedelta(1)
替换为td.total_seconds() / 86400
。
这是另一种方式:
>>> from __future__ import division
>>> assert day_fraction.days == 0
>>> '%.0f' % ((day_fraction.seconds*10**6 + day_fraction.microseconds) / 864000)
'23992'
真除法之前的所有算术运算均以无限精度执行。
另一种方法也产生 92
:
>>> from datetime import timezone
>>> ('%.5f' % ((dt.replace(tzinfo=timezone.utc).timestamp() % 86400) / 86400))[2:]
'23992'
我构建了一个脚本,它在 telescope 处获取观察的日期和时间,并将其转换为仅带小数点的日期。该脚本还采用一半的曝光时间并将其添加到小数日,以便我可以获得最准确的天文计算。然后提交给只接受年月观测时间的小行星中心 Day.XXXXX 最精确到小数点后5位的方法是什么?这是我目前使用的方式,是的,它非常混乱,但它确实让我得到了小数日。有时它在时间转换中会偏移一秒。
expmpc = float.("10")
utcstartmpc = "05:45:19.03"
datempc = "2015-02-14"
ddexposure = expmpc/(60.0*60.0*24.0)
ddexposure = round(ddexposure, 5)
seconds = int(utcstartmpc[6:8]) / 60.0
minutes = (int(utcstartmpc[3:5]) + seconds) / 60
hours = (int(utcstartmpc[:2]) + minutes) / 24
hours = round(hours, 5)
expadd = str(hours + ddexposure)
datempc = datempc.replace("-", " ")
utcmpc = "C%s%s" % (datempc, expadd[1:])
utcmpc = utcmpc.ljust(17, "0")
如您所见,这非常混乱,涉及对大量数据进行四舍五入,我相信四舍五入会降低准确性。代码的完成结果留下了这样的时间: C2015 02 14.23986
有没有更好用的模块?
感谢您的帮助。
这是使用更多内置 time/date 模块的东西(我 认为 它可以满足您的需求):
import time
import datetime
def my_date_converter(date_in):
parse_str, _ = date_in.split(".")
date_str, time_str = parse_str.split(" ")
parsed_time = time.strptime(time_str, "%H:%M:%S")
total_seconds = datetime.timedelta(hours=parsed_time.tm_hour,minutes=parsed_time.tm_min,seconds=parsed_time.tm_sec).total_seconds()
seconds_in_day = 86400.0
decimal_seconds = total_seconds / seconds_in_day
utcmpc = "C%s%s" % (date_str.replace("-", " "), str(round(decimal_seconds, 5))[1:])
utcmpc = utcmpc.ljust(17, "0")
return utcmpc
def main():
to_convert = "2015-02-14 05:45:19.03"
converted = my_date_converter(to_convert)
print "%s => %s" % (to_convert, converted)
if __name__ == '__main__':
main()
示例输出:2015-02-14 05:45:19.03 => C2015 02 14.23980
你试过优秀的astropy库了吗?他们有一个处理时间和转化的包:astropy.time
您可以将您的问题分成 2 个任务:
- 从输入
expmpc
、utcstartmpc
、datempc
获取表示 UTC 时间的对象
- 将日期时间对象转换为
Year Month Day.XXXXX
格式的字符串。
从输入expmpc
、utcstartmpc
、datempc
中获取datetime
对象
from datetime import datetime, timedelta
expmpc = "10"
utcstartmpc = "05:45:19.03"
datempc = "2015-02-14"
dt = datetime.strptime(datempc + " " + utcstartmpc, "%Y-%m-%d %H:%M:%S.%f")
dt += timedelta(seconds=int(expmpc))
将 datetime
对象转换为 Year Month Day.XXXXX
格式的字符串
from datetime import datetime, time, timedelta
s = dt.strftime("C%Y %m %d.")
day_fraction = dt - datetime.combine(dt, time.min)
s += ("%.0f" % (100000*day_fraction / timedelta(days=1)))
# -> C2015 02 14.23992
注意:结果与您问题中的结果略有不同(92
vs. 最后的 86
)。
在Python2中,需要将td / timedelta(1)
替换为td.total_seconds() / 86400
。
这是另一种方式:
>>> from __future__ import division
>>> assert day_fraction.days == 0
>>> '%.0f' % ((day_fraction.seconds*10**6 + day_fraction.microseconds) / 864000)
'23992'
真除法之前的所有算术运算均以无限精度执行。
另一种方法也产生 92
:
>>> from datetime import timezone
>>> ('%.5f' % ((dt.replace(tzinfo=timezone.utc).timestamp() % 86400) / 86400))[2:]
'23992'