[英]Extract day of year and Julian day from a string date
我在 python 中有一个字符串"2012.11.07"
。我需要将它转换为日期 object,然后得到 integer年的日期值和Julian day值。 是否可以?
首先,您可以将其转换为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、向负无穷大、将中午四舍五入到第二天、将中午向偶数四舍五入等(注意Julian 日期被定义为从公元前 4713 年 1 月 1 日中午开始,所以 2012 年 11 月 7 日的一半是 2456238,另一半是 2456239,只有你知道你想要哪一个......)例如,向 0 舍入:
>>> int(sum(jdcal.gcal2jd(dt.year, dt.month, dt.day)))
2456238
要获得儒略日,请使用datetime.date.toordinal
方法并添加固定偏移量。
儒略日是自公元前 4713 年 1 月 1 日 12:00 开始的天数,在预言儒略历中,或公元前 4714 年 11 月 24 日在 12:00 在预言格里高利历。 请注意,每个儒略日从中午开始,而不是午夜。
toordinal
函数返回自公历12 月31 日00:00 开始的天数(换句话说,公元1 年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
为了简化 abarnert 答案的初始步骤:
from dateutil import parser
s = '2012.11.07'
dt = parser.parse(s)
然后应用abanet的其余答案。
为了快速计算,您可以仅使用 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 日开始的日子被转移以排除闰日。
还有一个相关术语: Julian date 。 儒略日数是一个整数。 儒略日期本质上是小数: “任何时刻的儒略日期 (JD)是前一个中午的儒略日数加上自该时刻起当天的分数。”
通常,为了避免自己处理边缘情况,请按照@abernert 的建议使用库来计算儒略日。
根据这篇文章,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
从上面的例子中,这是一个班轮(非朱利安):
import datetime
doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday
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
我导入日期时间库,并使用 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
虽然 @FGol 的答案提供了独立的公式,但应该注意的是,这些公式只有在除法向零舍入(所谓的“截断除法”)时才有效,这与语言有关。
例如 Python 实现了向-infinity 的舍入,这是非常不同的。 要使用 Python 中给出的公式,您可以这样做:
def trunc_div(a, b):
"""Implement 'truncated division' in Python."""
return (a // b) if a >= 0 else -(-a // b)
def formula1(year, month, day):
"""Convert Gregorian date to julian day number."""
return 367 * year - trunc_div(7 * (year + trunc_div(month + 9, 12)), 4) - trunc_div(3 * (trunc_div(year + trunc_div(month - 9, 7), 100) + 1), 4) + trunc_div(275 * month, 9) + day + 1721029
def formula2(year, month, day):
"""Convert Gregorian date to julian day number (simplified); only valid for dates from March 1900 and beyond."""
return 367 * year - trunc_div(7 * (year + trunc_div(month + 9, 12)), 4) + trunc_div(275 * month, 9) + day + 1721014
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.