在Python中将年/月/日转换为年份

Pet*_*ete 119 python datetime

我正在使用Python"datetime"模块,即:

>>> import datetime
>>> today = datetime.datetime.now()
>>> print today
2009-03-06 13:24:58.857946
Run Code Online (Sandbox Code Playgroud)

我想计算一年中对闰年敏感的日期.例如,今天(2009年3月6日)是2009年的第65天. 这是基于网络的DateTime计算器.

无论如何,我看到两个选项:

  1. 创建一个number_of_days_in_month数组= [31,28,...],判断它是否为闰年,手动总结天数

  2. 使用datetime.timedelta进行猜测,然后二元搜索正确的一年:

.

>>> import datetime
>>> YEAR = 2009
>>> DAY_OF_YEAR = 62
>>> d = datetime.date(YEAR, 1, 1) + datetime.timedelta(DAY_OF_YEAR - 1)
Run Code Online (Sandbox Code Playgroud)

这些都感觉很笨重,我有一种直觉,那就是有更多的"Pythonic"方式计算一年中的一天.有什么想法/建议吗?

Dzi*_*inX 233

有一个非常简单的解决方案:

from datetime import datetime
day_of_year = datetime.now().timetuple().tm_yday
Run Code Online (Sandbox Code Playgroud)

  • @MikeEllis但是这个解决方案说明了当datetime与今天不对应时该怎么做. (13认同)
  • 一个非常小的,可以说是迂腐的补充,但是使用`date.today()`而不是`datetime.now()`也可以工作并且更强调操作的本质. (10认同)
  • 更好的是:`time.localtime().tm_yday`无需将datetime转换为timetuple,因为这是localtime()产生的. (5认同)
  • **注意:** 从 1 开始计数 (4认同)
  • 如果我想做相反的事情,我有数字“2020 年 26 日”,我想将其转换为日期“26-01-2020”? (3认同)
  • @Sankar,然后你用谷歌搜索这个问题,如果你没有找到任何东西,就问你自己的 Stack Overflow 问题。 (3认同)

Pao*_*ino 36

你不能用strftime吗?

>>> import datetime
>>> today = datetime.datetime.now()
>>> print today
2009-03-06 15:37:02.484000
>>> today.strftime('%j')
'065'
Run Code Online (Sandbox Code Playgroud)

编辑

如评论中所述,如果您希望使用此数字进行比较或计算,则必须将其转换为int()因为strftime()返回字符串.如果是这种情况,最好使用DzinX的答案.

  • 真的吗?这个icky和减少的1月1号怎么样?strftime是有原因的.我只是不同意.在我看来,这是更清洁的方式. (9认同)
  • 使用 strftime 是间接的,因为它从一个数字生成一个字符串:timetuple.tm_yday 成员。阅读源码。生成的字符串应该在任何计算/比较之前转换为数字,那么何必呢? (2认同)
  • 如果需要一个字符串中的某一天,比如说在文件名中使用,那么strftime是一个更清洁的解决方案. (2认同)

Dav*_*e X 12

DZinX的答案是这个问题的一个很好的答案.我在寻找反函数时发现了这个问题.我发现这个工作:

import datetime
datetime.datetime.strptime('1936-077T13:14:15','%Y-%jT%H:%M:%S')

>>>> datetime.datetime(1936, 3, 17, 13, 14, 15)

datetime.datetime.strptime('1936-077T13:14:15','%Y-%jT%H:%M:%S').timetuple().tm_yday

>>>> 77
Run Code Online (Sandbox Code Playgroud)

我不确定这里的礼节,但我认为指向反函数的指针可能对像我这样的其他人有用.


omi*_*ron 6

我想在Python 3.4,Linux x64上展示不同方法的性能.来自line profiler的摘录:

      Line #      Hits         Time  Per Hit   % Time  Line Contents
      ==============================================================
         (...)
         823      1508        11334      7.5     41.6          yday = int(period_end.strftime('%j'))
         824      1508         2492      1.7      9.1          yday = period_end.toordinal() - date(period_end.year, 1, 1).toordinal() + 1
         825      1508         1852      1.2      6.8          yday = (period_end - date(period_end.year, 1, 1)).days + 1
         826      1508         5078      3.4     18.6          yday = period_end.timetuple().tm_yday
         (...)
Run Code Online (Sandbox Code Playgroud)

所以效率最高的是

yday = (period_end - date(period_end.year, 1, 1)).days
Run Code Online (Sandbox Code Playgroud)


zwe*_*nde 5

从日期开始减去1月1日:

import datetime
today = datetime.datetime.now()
day_of_year = (today - datetime.datetime(today.year, 1, 1)).days + 1
Run Code Online (Sandbox Code Playgroud)

  • 可爱,但很难"标准,正确的算法." (10认同)
  • d.toordinal() - date(d.year, 1, 1).toordinal() + 1 根据文档更标准。它相当于不产生整个时间元组的接受答案。 (2认同)

Bar*_*sen 5

如果您有理由避免使用该datetime模块,那么这些功能将起作用。

def is_leap_year(year):
    """ if year is a leap year return True
        else return False """
    if year % 100 == 0:
        return year % 400 == 0
    return year % 4 == 0

def doy(Y,M,D):
    """ given year, month, day return day of year
        Astronomical Algorithms, Jean Meeus, 2d ed, 1998, chap 7 """
    if is_leap_year(Y):
        K = 1
    else:
        K = 2
    N = int((275 * M) / 9.0) - K * int((M + 9) / 12.0) + D - 30
    return N

def ymd(Y,N):
    """ given year = Y and day of year = N, return year, month, day
        Astronomical Algorithms, Jean Meeus, 2d ed, 1998, chap 7 """    
    if is_leap_year(Y):
        K = 1
    else:
        K = 2
    M = int((9 * (K + N)) / 275.0 + 0.98)
    if N < 32:
        M = 1
    D = N - int((275 * M) / 9.0) + K * int((M + 9) / 12.0) + 30
    return Y, M, D
Run Code Online (Sandbox Code Playgroud)