【问题标题】:Extract day of year and Julian day from a string date从字符串日期中提取一年中的某一天和儒略日
【发布时间】:2012-12-06 06:07:04
【问题描述】:

我在 python 中有一个字符串"2012.11.07"。我需要将它转换为日期对象,然后得到一个整数值 day of yearJulian day。有可能吗?

【问题讨论】:

标签: python date datetime julian-date


【解决方案1】:

我导入 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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      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
      

      【讨论】:

        【解决方案4】:

        要获取儒略日,请使用datetime.date.toordinal 方法并添加固定偏移量。

        儒略日是自 BC 4713 年 1 月 1 日 12:00 在预产儒略历或 4714 年 11 月 24 日 12:00 在proleptic Gregorian calendar 中的天数。请注意,每个儒略日从中午开始,而不是午夜。

        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
        

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

            为了快速计算,您可以仅使用 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"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 使用术语“儒略日”的方式不同:

            Jn儒略日 n (1 n 从零开始的儒略日 (0

            即,从零开始的儒略日在这里是day_of_year - 1。第一个 (Jn) 是 day_of_year - (calendar.isleap(dt.year) and day_of_year &gt; 60) - 从 3 月 1 日开始的日期被转移以排除闰日。

            还有一个相关的术语:儒略日期儒略日数是一个整数。 朱利安日期本质上是小数:"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."

            一般来说,为避免自己处理极端情况,请使用库将儒略日计算为 suggested by @abarnert

            【讨论】:

              【解决方案7】:

              astropy 模块中也提供此功能(将日期字符串转换为 Julian 日期/时间)。完整详情请参阅their documentation。 astropy 实现对于轻松转换到 Julian time 而言特别方便,而不仅仅是 Julian date

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

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

              【讨论】:

                【解决方案8】:

                首先,您可以将其转换为 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上的方法得到你想要的了……只不过@9​​87654330@没有你想要的功能,所以你需要转换成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、朝负无穷大、将中午舍入到第二天、将中午舍入到偶数天等。 (注意儒略日期定义为从 4713 年 1 月 1 日中午开始,所以 2012 年 11 月 7 日的一半是 2456238,另一半是 2456239,只有你知道你想要哪一个……)例如,向 0 舍入:

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

                【讨论】:

                • julian day is an integer number。 gcal2jd() 返回 julian 日期.
                • @J.F.Sebastian:阅读链接的文档。 “儒略日期存储在两个浮点数(双精度)中。” jdcal 正在返回小数儒略日(如果只给出日期,则假设中午)。如果您想争辩说这些不应该被称为朱利安时代而是其他东西,请与模块的作者讨论。
                • 您有责任确保 建议的模块返回 OP 的要求。
                • @J.F.Sebastian:好的,我已经添加了调用int的代码。但重点不是给出他可以不假思索地使用的OP代码,或者推荐一个特定的库;我使用gdcal 作为您可以通过快速 google、PyPI 或 ActiveState 搜索找到的各种库的示例;仍然由 OP 进行搜索、评估库并选择他想要的库。
                • 最好假设中午给定日期而不是前一天的午夜,即它应该是 39,如my answer,而不是 38。你的观点是有效的,但不是吗如果可能的话,最好在答案中提供研究结果,以避免强迫人们复制它。
                【解决方案9】:

                为了简化 abarnert 回答的初始步骤:

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

                然后应用 abanert 的其余答案。

                【讨论】:

                • 这是哪个版本的python? tm_yday 不适合我 @ 2.7
                • 这是给我的。您是否忘记转换为时间元组? dt 对象没有成员 tm_yday,而您从 dt.timetuple() 获得的 time.struct_time 对象具有该成员。
                猜你喜欢
                • 2016-01-22
                • 2023-04-02
                • 1970-01-01
                • 2013-09-12
                • 1970-01-01
                • 1970-01-01
                • 2018-04-29
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多