我在python中有一个字符串"2012.11.07"
,我需要将其转换为日期对象,然后获得一年中的第几天和儒略日的整数值。这是否可能?
我在python中有一个字符串"2012.11.07"
,我需要将其转换为日期对象,然后获得一年中的第几天和儒略日的整数值。这是否可能?
首先,您可以将它转换为一个 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
并简要浏览了 readme 文件后,我就能够做到这一点:
>>> sum(jdcal.gcal2jd(dt.year, dt.month, dt.day))
2456238.5
这与美国海军儒略日转换器给出的结果相同。
如果你想要整数的儒略日,而不是分数儒略日,你需要决定向哪个方向舍入——向0、负无穷大、将中午舍入到下一天、向偶数日进行舍入等(请注意,儒略日的定义是从公元前4713年1月1日中午开始计算,因此2012年11月7日的一半是2456238,另一半是2456239,只有您知道您想要哪一个……)例如,向0进行舍入:
>>> int(sum(jdcal.gcal2jd(dt.year, dt.month, dt.day)))
2456238
jdcal
返回分数儒略日(如果仅给出日期,则假定为中午)。如果您想争论这些不应该被称为儒略日而是其他名称,请与模块的作者联系。 - abarnertgdcal
作为示例,展示您可以在快速谷歌、PyPI 或 ActiveState 搜索中找到哪些类型的库;仍需由 OP 自己进行搜索、评估库,并选择他想要的那个。 - abarnertPyPI Julian
,点击第一行,浏览其自述文件,pip install jdcal
,从自述文件中运行一个示例,验证其是否合理。”至于四舍五入……好的,我也会在答案中加上。 - abarnertdatetime.date.toordinal
方法并添加固定偏移量。toordinal
函数返回自公元前1年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
from dateutil import parser
s = '2012.11.07'
dt = parser.parse(s)
我导入了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
对于快速计算,您可以仅使用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
在上面的代码中是{{link1:"儒略日数,关联太阳日--指从公元前4713年1月1日格林威治平均正午开始连续计数的天数,儒略历(Julian proleptic calendar)将对应的儒略日数为0"}}。
"time
模块文档使用术语“儒略日”有所不同:
Jn
儒略日n (1 <= n <= 365)。不计闰日,因此在所有年份中,2月28日是第59天,3月1日是第60天。
n
基于零的儒略日(0 <= n <= 365)。包括闰日,可以表示2月29日。
即基于0的儒略日在此处为day_of_year - 1
。而第一个儒略日(Jn
)是day_of_year - (calendar.isleap(dt.year) and day_of_year > 60)
--从3月1日开始的日期将被移位以排除闰年。
还有一个相关术语:儒略日日期。 儒略日编号是一个整数。儒略日日期本质上是分数形式: "任何时刻的儒略日日期(JD)都是其前一天中午的儒略日编号加上自那时刻起的一天时间比例。"
通常,为避免自行处理边缘情况,请使用库计算儒略日,如@abarnert所建议的。
JD = 367 * year - 7 * (year + (month + 9)/12)/4 - 3 * ((year + (month - 9)/7)/100 + 1)/4 + 275 * month/9 + day + 1721029
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 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
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