Python 从字符串日期中提取年份和儒略日
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13943062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extract day of year and Julian day from a string date
提问by f.ashouri
I have a string "2012.11.07"in python. I need to convert it to date object and then get an integer value of day of yearand also Julian day. Is it possible?
我"2012.11.07"在python中有一个字符串。我需要将它转换为日期对象,然后获得一年中的第几天和Julian day的整数值。是否可以?
采纳答案by abarnert
First, you can convert it to a datetime.datetimeobject like this:
首先,您可以将其转换为这样的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)
Then you can use the methods on datetimeto get what you want… except that datetimedoesn't have the function you want directly, so you need to convert to a time tuple
然后你就可以使用 on 的方法datetime来得到你想要的......除了datetime没有你直接想要的功能,所以你需要转换为时间元组
>>> tt = dt.timetuple()
>>> tt.tm_yday
312
The term "Julian day" has a few different meanings. If you're looking for 2012312, you have to do that indirectly, e.g., one of the following.
“儒略日”一词有几种不同的含义。如果您正在寻找2012312,则必须间接执行此操作,例如,以下操作之一。
>>> int('%d%03d' % (tt.tm_year, tt.tm_yday))
2012312
>>> tt.tm_year * 1000 + tt.tm_yday
2012312
If you're looking for a different meaning, you should be able to figure it out from here. For example, if you want the "days since 1 Jan 4713 BC" meaning, and you have a formula that requires Gregorian year and day in year, you've got those two values above to plug in. (If you have a formula that takes Gregorian year, month, and day, you don't even need the timetuplestep.) If you can't work out where to go from there, ask for further details.
如果您正在寻找不同的含义,您应该能够从这里弄清楚。例如,如果您想要“自公元前 4713 年 1 月 1 日以来的天数”的含义,并且您有一个需要公历年和年中日的公式,则您可以插入上面的这两个值。(如果您有一个公式需要公历年、月和日,您甚至不需要该timetuple步骤。)如果您不知道从那里去哪里,请询问更多详细信息。
If you don't have a formula—and maybe even if you already do—your best bet is probably to look around PyPI and ActiveState for pre-existing modules. For example, a quick search turned up something called jdcal. I'd never seen it before, but a quick pip install jdcaland a brief skim of the readme, and I was able to do this:
如果你没有公式——即使你已经有了——你最好的办法可能是在 PyPI 和 ActiveState 周围寻找预先存在的模块。例如,快速搜索出现了一个名为jdcal. 我以前从未见过它,但是快速pip install jdcal浏览一下自述文件,我能够做到这一点:
>>> sum(jdcal.gcal2jd(dt.year, dt.month, dt.day))
2456238.5
That's the same result that the USN Julian date convertergave me.
这与 USN Julian 日期转换器给我的结果相同。
If you want integral Julian day, instead of fractional Julian date, you have to decide which direction you want to round—toward 0, toward negative infinity, rounding noon up to the next day, rounding noon toward even days, etc. (Note that Julian date is defined as starting since noon on 1 Jan 4713BC, so half of 7 Nov 2012 is 2456238, the other half is 2456239, and only you know which one of those you want…) For example, to round toward 0:
如果你想要整数儒略日,而不是小数儒略日期,你必须决定你想要向哪个方向四舍五入——向 0、向负无穷大、将中午四舍五入到第二天、将中午向偶数四舍五入等(注意Julian 日期被定义为从公元前 4713 年 1 月 1 日中午开始,所以 2012 年 11 月 7 日的一半是 2456238,另一半是 2456239,只有你知道你想要哪一个......)例如,向 0 舍入:
>>> int(sum(jdcal.gcal2jd(dt.year, dt.month, dt.day)))
2456238
回答by K.-Michael Aye
To simplify the initial steps of abarnert's answer:
为了简化 abarnert 答案的初始步骤:
from dateutil import parser
s = '2012.11.07'
dt = parser.parse(s)
then apply the rest of abanert's answer.
然后应用abanet的其余答案。
回答by jfs
For quick computations, you could find day of year and Julian day numberusing only stdlib datetimemodule:
为了快速计算,您可以仅使用 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
Another way to get day_of_year:
另一种获取方式day_of_year:
import time
day_of_year = time.strptime("2012.11.07", "%Y.%m.%d").tm_yday
julian_dayin the code above is "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".
julian_day在上面的代码中是“与太阳日相关联的儒略日数字——从儒略日数字 0 开始的连续天数中分配给一天的数字,分配给从格林威治开始的一天,即公元前 4713 年 1 月 1 日中午, 朱利安催眠日历 -4712"。
The timemodule documentationuses the term "Julian day"differently:
该time模块文档使用术语“儒略日”有所不同:
JnThe Julian day n (1 <= n <= 365). Leap days are not counted, so in all years February 28 is day 59 and March 1 is day 60.nThe zero-based Julian day (0 <= n <= 365). Leap days are counted, and it is possible to refer to February 29.
Jn儒略日 n (1 <= n <= 365)。闰日不计算在内,因此在所有年份中,2 月 28 日是第 59 天,3 月 1 日是第 60 天n。从零开始的儒略日 (0 <= n <= 365)。闰日是计算的,可以参考2月29日。
i.e., the zero-based Julian day is day_of_year - 1here. And the first one (Jn) is day_of_year - (calendar.isleap(dt.year) and day_of_year > 60)-- the days starting with March 1 are shifted to exclude the leap day.
即,从零开始的儒略日就day_of_year - 1在这里。第一个 ( Jn) 是day_of_year - (calendar.isleap(dt.year) and day_of_year > 60)- 从 3 月 1 日开始的日期被转移以排除闰日。
There is also a related term: Julian date. Julian day numberis an integer. Julian dateis inherently fractional: "The Julian Date (JD)of any instant is the Julian day numberfor the preceding noon plus the fraction of the day since that instant."
还有一个相关术语:Julian date。 儒略日数是一个整数。儒略日期本质上是小数:“任何时刻的儒略日期 (JD)是前一个中午的儒略日数加上自该时刻起当天的分数。”
In general, to avoid handling edge cases yourself, use a library to compute Julian day as suggested by @abarnert.
通常,为了避免自己处理边缘情况,请按照@abernert 的建议使用库来计算儒略日。
回答by Kyle
This functionality (conversion of date strings to Julian date/time) is also present in the astropymodule. Please refer to their documentationfor complete details. The astropy implementation is especially handy for easy conversions to Julian time, as opposed to just the Julian date.
此功能(将日期字符串转换为 Julian 日期/时间)也存在于astropy模块中。有关完整的详细信息,请参阅他们的文档。astropy 实现对于轻松转换为儒略时间特别方便,而不仅仅是儒略日期。
Example solution for the original question:
原始问题的示例解决方案:
>>> 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
回答by nvd
From the above examples, here is the one liner (non-Julian):
从上面的例子中,这是一个班轮(非朱利安):
import datetime
doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday
回答by ghostarbeiter
To get the Julian day, use the datetime.date.toordinalmethod and add a fixed offset.
要获得儒略日,请使用该datetime.date.toordinal方法并添加固定偏移量。
The Julian day is the number of days since January 1, 4713 BC at 12:00 in the proleptic Julian calendar, or November 24, 4714 BC at 12:00 in the proleptic Gregorian calendar. Note that each Julian day starts at noon, not midnight.
儒略日是自公元前 4713 年 1 月 1 日 12:00(在预兆儒略历)或公元前 4714 年 11 月 24 日 12:00 在预兆格里高利历以来的天数。请注意,每个儒略日从中午开始,而不是午夜。
The toordinalfunction returns the number of days since December 31, 1 BC at 00:00 in the proleptic Gregorian calendar (in other words, January 1, 1 AD at 00:00 is the start of day 1, not day 0). Note that 1 BC directly precedes 1 AD, there was no year 0 since the number zero wasn't invented until many centuries later.
该toordinal函数返回自公历12 月31 日00:00 开始的天数(换句话说,公元1 年1 月1 日00:00 是第1 天的开始,而不是第0 天)。请注意,公元前 1 年直接在公元 1 年之前,没有 0 年,因为直到许多世纪后才发明数字零。
import datetime
datetime.date(1,1,1).toordinal()
# 1
Simply add 1721424.5 to the result of toordinalto get the Julian day.
只需将 1721424.5 添加到 的结果中toordinal即可获得儒略日。
Another answer already explained how to parse the string you started with and turn it into a datetime.dateobject. So you can find the Julian day as follows:
另一个答案已经解释了如何解析您开始使用的字符串并将其转换为datetime.date对象。所以你可以找到儒略日如下:
import datetime
my_date = datetime.date(2012,11,7) # time = 00:00:00
my_date.toordinal() + 1721424.5
# 2456238.5
回答by Mounirsky
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
回答by FGol
According to this articlethere is an unpublished one-line formula created by Fliegel and Van Flandern to calculate an Gregorian Date to an Julian Date:
根据这篇文章,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
This was compacted by P. M. Muller and R. N. Wimberly of the Jet Propulsion Laboratory, Pasadena, California for dates after March of 1900 to:
加利福尼亚州帕萨迪纳市喷气推进实验室的 PM Muller 和 RN Wimberly 将其压缩为 1900 年 3 月之后的日期:
JD = 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014
These formulas are off by 0.5, so just subtract 0.5 from the formulas.
这些公式相差 0.5,所以只需从公式中减去 0.5。
Use some string manupulation to actually extract the data and you will be good
使用一些字符串操作来实际提取数据,你会很好
>>> 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
回答by Cícero Alves
I import datetime lib, and use strftime to extract 'julian day', year, month, day...
我导入日期时间库,并使用 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

