从字符串日期提取一年中的一天和Julian日

时间:2012-12-18 23:12:37

标签: python date datetime julian

我在python中有一个字符串"2012.11.07"。我需要将其转换为日期对象,然后获得一年的整数值以及 Julian day 。有可能吗?

9 个答案:

答案 0 :(得分:42)

首先,您可以将其转换为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没有你想要的功能,所以你需要转换为time tuple

>>> 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 date converter给我的结果相同。

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

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

答案 1 :(得分:3)

简化abarnert答案的初始步骤:

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

然后应用abanert的其余部分。

答案 2 :(得分:3)

此功能(将日期字符串转换为Julian日期/时间)也存在于astropy模块中。有关完整的详细信息,请参阅their documentation。与仅使用Julian date 相比,astropy实现对于轻松转换为Julian time 特别方便。

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

>>> 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

答案 3 :(得分:2)

对于快速计算,您可以仅使用stdlib datetime模块找到一年中的某一天和 Julian日数

#!/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"the Julian day number associated with the solar day -- the number assigned to a day in a continuous count of days beginning with the Julian day number 0 assigned to the day starting at Greenwich mean noon on 1 January 4713 BC, Julian proleptic calendar -4712"

time module documentation使用术语" Julian day"

  

Jn朱利安日n(1&lt; = n&lt; = 365)。闰日不算,所以   所有年份2月28日是第59天,3月1日是第60天   n   从零开始的Julian日(0 <= n <= 365)。闰日计算在内   可以参考2月29日。

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

还有一个相关术语:朱利安日期 Julian day number 是一个整数。 朱利安日期本质上是小数:"The Julian Date (JD) of any instant is the Julian day number for the preceding noon plus the fraction of the day since that instant."

通常,为避免自己处理边缘情况,请使用库将Julian日计算为suggested by @abarnert

答案 4 :(得分:2)

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

朱利安日是自公元前4713年1月1日在易瑞典朱利安历法中的12:00,或公元前4714年11月24日在proleptic Gregorian calendar中的12:00的天数。请注意,每个儒略日都在中午开始,而不是午夜。

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

import datetime

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

只需在toordinal的结果中添加1721424.5即可获得Julian日。

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

import datetime

my_date = datetime.date(2012,11,7)   # time = 00:00:00
my_date.toordinal() + 1721424.5
# 2456238.5

答案 5 :(得分:0)

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

import datetime

doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday

答案 6 :(得分: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

答案 7 :(得分:0)

根据this article,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

这是由加利福尼亚州帕萨迪纳市喷气推进实验室的P.M. Muller和R.N. 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

答案 8 :(得分:0)

我导入datetime lib,并使用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