Extract day of year and Julian day from a string date

前端 未结 9 1955
臣服心动
臣服心动 2020-11-27 06:51

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 year and also Julian day

相关标签:
9条回答
  • 2020-11-27 06:57

    For quick computations, you could find day of year and Julian day number using only stdlib datetime module:

    #!/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:

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

    julian_day in 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".

    The time module documentation uses the term "Julian day" differently:

    Jn The 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.
    n The zero-based Julian day (0 <= n <= 365). Leap days are counted, and it is possible to refer to February 29.

    i.e., the zero-based Julian day is day_of_year - 1 here. 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.

    There is also a related term: Julian date. Julian day number is an integer. Julian date is inherently fractional: "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."

    In general, to avoid handling edge cases yourself, use a library to compute Julian day as suggested by @abarnert.

    0 讨论(0)
  • 2020-11-27 06:58

    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
    
    0 讨论(0)
  • 2020-11-27 06:59

    According to this article there is an unpublished one-line formula created by Fliegel and Van Flandern to calculate an Gregorian Date to an Julian Date:

    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:

    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.

    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
    
    0 讨论(0)
  • 2020-11-27 07:00

    This functionality (conversion of date strings to Julian date/time) is also present in the astropy module. Please refer to their documentation for complete details. The astropy implementation is especially handy for easy conversions to Julian time, as opposed to just the Julian date.

    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
    
    0 讨论(0)
  • 2020-11-27 07:02

    To get the Julian day, use the datetime.date.toordinal method and add a fixed offset.

    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.

    The toordinal function 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.

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

    Simply add 1721424.5 to the result of toordinal to get the Julian day.

    Another answer already explained how to parse the string you started with and turn it into a datetime.date object. So you can find the Julian day as follows:

    import datetime
    
    my_date = datetime.date(2012,11,7)   # time = 00:00:00
    my_date.toordinal() + 1721424.5
    # 2456238.5
    
    0 讨论(0)
  • 2020-11-27 07:03
    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
    
    0 讨论(0)
提交回复
热议问题