29

"2012.11.07"在python中有一个字符串。我需要将其转换为 date 对象,然后获取day of yearJulian day的整数值。是否可以?

4

9 回答 9

58

首先,您可以将其转换为datetime.datetime如下对象:

>>> import datetime
>>> fmt = '%Y.%m.%d'
>>> s = '2012.11.07'
>>> dt = datetime.datetime.strptime(s, fmt)
>>> dt
datetime.datetime(2012, 11, 7, 0, 0)

然后你可以使用方法datetime来得到你想要的......只是datetime没有你想要的功能,所以你需要转换为时间元组

>>> tt = dt.timetuple()
>>> tt.tm_yday
312

“儒略日”一词有几个不同的含义。如果您正在寻找2012312,则必须间接执行此操作,例如,以下操作之一。

>>> int('%d%03d' % (tt.tm_year, tt.tm_yday))
2012312
>>> tt.tm_year * 1000 + tt.tm_yday
2012312

如果您正在寻找不同的含义,您应该能够从这里弄清楚。例如,如果您想要“自公元前 4713 年 1 月 1 日以来的天数”的含义,并且您有一个需要公历年份和年份的公式,则可以插入上面的这两个值。(如果您有一个公式需要公历年、月和日,您甚至不需要该timetuple步骤。)如果您无法确定从那里去哪里,请询问更多详细信息。

如果你没有公式——也许即使你已经有了——最好的办法可能是查看 PyPI 和 ActiveState 以查找预先存在的模块。例如,快速搜索会找到一个名为jdcal. 我以前从未见过它,但快速pip install jdcal而简短地浏览了自述文件,我能够做到这一点:

>>> sum(jdcal.gcal2jd(dt.year, dt.month, dt.day))
2456238.5

这与 USN Julian 日期转换器给我的结果相同。

如果你想要整数儒略日,而不是分数儒略日,你必须决定你想要向哪个方向舍入——向 0、向负无穷、将中午舍入到第二天、将中午舍入到偶数天等。(请注意,儒略日期定义为从 4713 年 1 月 1 日中午开始,因此 2012 年 11 月 7 日的一半是 2456238,另一半是 2456239,只有你知道你想要哪一个……)例如,向 0 舍入:

>>> int(sum(jdcal.gcal2jd(dt.year, dt.month, dt.day)))
2456238
于 2012-12-18T23:17:12.373 回答
7

要获得儒略日,请使用该datetime.date.toordinal方法并添加固定偏移量。

儒略日是自 BC 4713 年 1 月 1 日 12:00 在预产儒略历或 4714 年 11 月 24 日在 12:00 在预产公历中的天数。请注意,每个儒略日从中午开始,而不是午夜。

toordinal函数返回自公元前 1 年 12 月 31 日 00:00 前的公历以来的天数(换句话说,公元 1 月 1 日 00:00 是第 1 天的开始,而不是第 0 天)。请注意,公元前 1 年直接在公元 1 年之前,没有 0 年,因为直到许多世纪后才发明数字零。

import datetime

datetime.date(1,1,1).toordinal()
# 1

只需将 1721424.5 添加到结果中toordinal即可获得儒略日。

另一个答案已经解释了如何解析您开始使用的字符串并将其转换为datetime.date对象。所以你可以找到儒略日如下:

import datetime

my_date = datetime.date(2012,11,7)   # time = 00:00:00
my_date.toordinal() + 1721424.5
# 2456238.5
于 2016-08-18T13:08:31.973 回答
4

为了简化 abarnert 回答的初始步骤:

from dateutil import parser
s = '2012.11.07'
dt = parser.parse(s)

然后应用 abanert 的其余答案。

于 2013-01-04T01:21:09.090 回答
3

为了快速计算,您可以仅使用 stdlib模块找到一年中的某一天和儒略日数:datetime

#!/usr/bin/env python3
from datetime import datetime, timedelta

DAY = timedelta(1)
JULIAN_EPOCH = datetime(2000, 1, 1, 12) # noon (the epoch name is unrelated)
J2000_JD = timedelta(2451545) # julian epoch in julian dates

dt = datetime.strptime("2012.11.07", "%Y.%m.%d") # get datetime object
day_of_year = (dt - datetime(dt.year, 1, 1)) // DAY + 1 # Jan the 1st is day 1
julian_day = (dt.replace(hour=12) - JULIAN_EPOCH + J2000_JD) // DAY
print(day_of_year, julian_day)
# 312 2456239

另一种获取方式day_of_year

import time

day_of_year = time.strptime("2012.11.07", "%Y.%m.%d").tm_yday

julian_day在上面的代码中是“与太阳日相关的儒略日编号 - 分配给从儒略日编号 0 开始的连续天数中的一天的编号,分配给从格林威治开始的日子意味着 4713 年 1 月 1 日中午,儒略历-4712"

time模块文档以不同的方式使用术语“朱利安日”

Jn儒略日 n (1 <= n <= 365)。闰日不计算在内,因此在所有年份中,2 月 28 日是第 59 天,3 月 1 日是第 60 天
n。从零开始的儒略日 (0 <= n <= 365)。闰日计算,可参考2月29日。

即,从零开始的儒略日就day_of_year - 1在这里。第一个 ( Jn) 是day_of_year - (calendar.isleap(dt.year) and day_of_year > 60)- 从 3 月 1 日开始的日期被转移以排除闰日。

还有一个相关的术语:朱利安日期儒略日数是一个整数。儒略日期本质上是分数:“任何时刻的儒略日期 (JD)是前一个中午的儒略日数加上自该时刻以来的一天的分数。”

通常,为了避免自己处理极端情况,请使用库来计算@abarnert 建议的儒略日。

于 2014-09-14T08:24:27.453 回答
3

此功能(将日期字符串转换为儒略日期/时间)也存在于astropy模块中。有关完整的详细信息,请参阅他们的文档。astropy 实现对于轻松转换为儒略时间特别方便,而不仅仅是儒略日期

原始问题的示例解决方案:

>>> import astropy.time
>>> import dateutil.parser

>>> dt = dateutil.parser.parse('2012.11.07')
>>> time = astropy.time.Time(dt)
>>> time.jd
2456238.5
>>> int(time.jd)
2456238
于 2015-02-18T21:37:50.797 回答
2

根据这篇文章,Fliegel 和 Van Flandern 创建了一个未发表的单行公式,用于计算公历日期到儒略日期:

JD = 367 * year - 7 * (year + (month + 9)/12)/4 - 3 * ((year + (month - 9)/7)/100 + 1)/4 + 275 * month/9 + day + 1721029

这是由加利福尼亚州帕萨迪纳市喷气推进实验室的 PM Muller 和 RN Wimberly 于 1900 年 3 月之后的日期压缩的:

JD = 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014

这些公式相差 0.5,因此只需从公式中减去 0.5。

使用一些字符串操作来实际提取数据,你会很好

>>> year, month, day = map(int,"2018.11.02".split("."))
>>> 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014 - 0.5
2458424.5
于 2018-07-13T06:04:52.853 回答
2

我导入 datetime 库,并使用 strftime 提取“朱利安日”、年、月、日...

import datetime as dt
my_date = dt.datetime.strptime('2012.11.07', '%Y.%m.%d')
jld_str = my_date.strftime('%j') # '312'
jld_int = int(jld_str)           #  312
于 2020-03-10T14:21:20.530 回答
1

从上面的例子中,这里是一个班轮(非朱利安):

import datetime

doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday
于 2015-03-05T01:28:15.923 回答
0
def JulianDate_to_date(y, jd):
    month = 1
    while jd - calendar.monthrange(y,month)[1] > 0 and month <= 12:
        jd = jd - calendar.monthrange(y,month)[1]
        month += 1
    date = datetime.date(y,month,jd).strftime("%m/%d/%Y")
    return date
于 2017-01-12T14:08:00.737 回答