将python datetime对象格式化为argumen

2024-10-03 00:25:10 发布

您现在位置:Python中文网/ 问答频道 /正文

对python有些陌生,但尝试将其用于卫星轨道分析。我真的没有得到datetime对象和方法。我希望能够将datetime对象传递给接受参数的函数,该函数的格式与datetime基本相同(年、周一、日、小时、分、秒)。下面的代码可以工作,但是有一个更好的方法。请开导我。谢谢!在

import jday
import datetime

jdate = jday.JD(2015,12,1,22,8,0) # example

now1 = datetime.datetime.now().strftime("%Y,%m,%d,%H,%M,%S")
now2 = now1.split(",")
now3 = [int(i) for i in now2]
jdatenow = jday.JD(*now3)
print jdatenow

jday模块是从davidvallado的天体动力学源代码Matlab移植过来的。在

^{pr2}$

Tags: 对象方法函数import参数datetime格式jd
3条回答

如果您已经移植了JD代码,并因此可以将其作为模块jday来控制,那么您可能正在寻找一个decorator。这有一个明显的好处,即不会破坏函数的原始签名(对于现有的客户机代码),但是根据您的请求添加了日期参数的便利性。在

jday()与jday()相同,但它也直接接受jday>模块。如果不需要向后兼容,这是最简单的解决方案。在

请参阅下面的工作示例代码:

日.py

import math as m
import functools

def date_support_wrapper(f):
    """ Wraps JD and provides a way to pass a date param

    :param f: the original function
    :return: the wrapper around the original function
    """

    @functools.wraps(f)
    def wrap(*args, **kwargs):
        if 'date' in kwargs:
            d = kwargs['date']
            return f(yr=d.year, mon=d.month, day=d.day, hr=d.hour, min=d.minute, sec=d.second)

        return f(*args, **kwargs)

    return wrap


@date_support_wrapper
def JD(yr, mon, day, hr, min, sec):
    jd = 367.0 * yr - m.floor(
        (7 * (yr + m.floor((mon + 9) / 12.0))) * 0.25) + m.floor(
        275 * mon / 9.0) + day + 1721013.5 + (
                                                 (sec / 60.0 + min) / 60.0 + hr) / 24.0
    return jd

jday2.py

^{pr2}$

和示例客户端代码:

客户端.py

import datetime
import jday
import jday2

# The date we are interested in
a = dict(year=2015, month=12, day=1, hour=22, minute=8, second=0)
dt = datetime.datetime(**a)  # 2015-12-01 22:08:00

# The original signature of the function
jdate1 = jday.JD(a['year'], a["month"], a["day"], a["hour"], a["minute"], a["second"])
# 2457358.422222222

# The new signature that accepts a normal date object
# Note that we use keyword "date" argument
jdate2 = jday.JD(date=dt)
# 2457358.422222222

# The new signature that accepts a normal date object
jdate3 = jday2.JD(dt)
# 2457358.422222222

您可以不使用math.floor()重写它:

def jdate(year, month, day, hour, minute, second):
    day_fraction = ((second + 60 * minute) + 3600 * hour) / 86400.
    return (367 * year - (7 * (year + (month + 9) // 12)) // 4 +
            275 * month // 9 + day + (1721013.5 + day_fraction))

您可以简化它;如果您使用datetime算术:

^{pr2}$

要将datetime对象传递给jdate(),可以使用.timetuple()方法:

import math

for time_tuple in [(1961, 1, 1), (1968, 2, 1), (1972, 1, 1), (1996, 1, 1)]:
    dt = datetime(*time_tuple)
    a, b = jdate(*dt.timetuple()[: 6]), JD(dt)
    print("{} UTC -> {} JD(UTC)".format(dt, b))
    assert math.isclose(a, b), (a, b)

另外,如果需要,可以使用dt.yeardt.monthdt.day等属性。在

输出

1961-01-01 00:00:00 UTC -> 2437300.5 JD(UTC)
1968-02-01 00:00:00 UTC -> 2439887.5 JD(UTC)
1972-01-01 00:00:00 UTC -> 2441317.5 JD(UTC)
1996-01-01 00:00:00 UTC -> 2450083.5 JD(UTC)

根据IERS web-site where a recommended "Julian Date" definition is provided,这是正确的。在


对于1900年3月之前和2100年2月之后的日期,公式得出了不同的结果:

import jdcal  # pip install jdcal
import astropy.time  # pip install astropy

print("                UTC |    matlab |  datetime |   astropy | jdcal")
for year in [1900, 2000, 2100]:
    for time_tuple in [(year, 2, 28, 12), (year, 3, 1, 12)]:
        dt = datetime(*time_tuple)
        matlabJD = jdate(*dt.timetuple()[:6])
        datetimeJD = JD(dt)
        jdcalJD = sum(jdcal.gcal2jd(*dt.timetuple()[:3])) + .5
        astropyJD = astropy.time.Time(dt)
        print("{dt} | {matlabJD} | {datetimeJD} | {astropyJD.jd} | {jdcalJD}"
              .format(**vars()))

输出

                UTC |    matlab |  datetime |   astropy | jdcal
1900-02-28 12:00:00 | 2415078.0 | 2415079.0 | 2415079.0 | 2415079.0
1900-03-01 12:00:00 | 2415080.0 | 2415080.0 | 2415080.0 | 2415080.0
2000-02-28 12:00:00 | 2451603.0 | 2451603.0 | 2451603.0 | 2451603.0
2000-03-01 12:00:00 | 2451605.0 | 2451605.0 | 2451605.0 | 2451605.0
2100-02-28 12:00:00 | 2488128.0 | 2488128.0 | 2488128.0 | 2488128.0
2100-03-01 12:00:00 | 2488130.0 | 2488129.0 | 2488129.0 | 2488129.0

你问题中的公式认为jdate()19002100是闰年。datetime实现、astropy和{}库在这里产生相同的结果。在

注意:Julianday是一个整数。JD()计算包含一天的分数的Julian日期,请参见definitions in the links。在

正如链接讨论中提到的,您应该使用已经制作好的库,并在必要时发送补丁,而不是重新设计轮子,以避免由于闰年、浮点问题、错误的时间刻度、儒略日定义上的细微差异等而产生的简单错误

不幸的是,不能将datetime对象直接传递给需要整数的函数。有什么特别的原因不能用datetime提供的字段调用函数?在

now = datetime.now()
jdatenow = jday.JD(now.year, now.month, now.day, now.hour, now.minute, now.second)

或者,如果这太麻烦了,总结一下:

^{pr2}$

这可能比

jdatenow = jday.JD(*list(datetime.now().timetuple())[:-3])

相关问题 更多 >