如何在不使用库的情况下在python中按自定义月份增加日期时间

jar*_*lan 183 python datetime

我需要增加日期时间值的月份

next_month = datetime.datetime(mydate.year, mydate.month+1, 1)
Run Code Online (Sandbox Code Playgroud)

当月份为12时,它变为13并且引发错误"月份必须在1..12".(我预计这一年会增加)

我想使用timedelta,但它不需要一个月的论点.有relativedelta python包,但我不想只为此安装它.还有使用strtotime的解决方案.

time = strtotime(str(mydate));
next_month = date("Y-m-d", strtotime("+1 month", time));
Run Code Online (Sandbox Code Playgroud)

我不想将datetime转换为str然后转换为time,然后转换为datetime; 因此,它仍然是一个图书馆

有没有人像使用timedelta一样有任何好的和简单的解决方案?

Atu*_*ind 410

这是使用dateutilrelativedelta将日期添加到日期的简短方法.

from datetime import datetime
from dateutil.relativedelta import relativedelta

date_after_month = datetime.today()+ relativedelta(months=1)
print 'Today: ',datetime.today().strftime('%d/%m/%Y')
print 'After Month:', date_after_month.strftime('%d/%m/%Y')
Run Code Online (Sandbox Code Playgroud)

输出:

今天:01/03/2013

月之后:01/04/2013

一句警告:relativedelta(months=1)relativedelta(month=1)不同的含义.传递month=1将原始日期中的月份替换为1月,而传递months=1将在原始日期添加一个月.

注意:这将需要python-dateutil.要安装它,您需要在Linux终端中运行.

sudo apt-get update && sudo apt-get install python-dateutil
Run Code Online (Sandbox Code Playgroud)

说明:在python中添加月份值

  • 这需要[`python-dateutil`](http://labix.org/python-dateutil)模块,但/ (26认同)
  • @Fomalhaut这是月****,而不仅仅是月份.如何使图书馆容易受到错误行为的影响. (11认同)
  • 如果您无法全局安装该软件包(或者您想要不同的版本),您也可以使用“pip install --user python-dateutil”。 (3认同)
  • dateutil包中的timedelta和relativedelta有什么区别? (2认同)
  • -1因为`print datetime(2015,12,1)+ relativedelta(month = 1)`打印`2015-01-01 00:00:00`而不是2016-01-01 00:00:00` (2认同)
  • 月复一月为我节省了 3 个多小时的调试时间 (2认同)

Dav*_*ebb 129

编辑 - 根据您对日期的评论,如果下个月的天数较少,则需要向下舍入,这是一个解决方案:

import datetime
import calendar

def add_months(sourcedate, months):
    month = sourcedate.month - 1 + months
    year = sourcedate.year + month // 12
    month = month % 12 + 1
    day = min(sourcedate.day, calendar.monthrange(year,month)[1])
    return datetime.date(year, month, day)
Run Code Online (Sandbox Code Playgroud)

此外,如果您不担心小时,分钟和秒钟,您可以使用date而不是datetime.如果您担心小时,分钟和秒钟,则需要修改我的代码以使用datetime并从源到结果复制小时,分钟和秒.

  • 如果是 10 月 31 日,那么就是 11 月 30 日 (2认同)
  • 但我认为月份可能会溢出-->月份 = (sourcedate.month - 1 + 月份) % 12 + 1。您不认为在计算月份后解决年份更好吗? (2认同)
  • 这并没有错,但也不是最简单的解决方案。请注意下面的“Atul Arvind”答案。 (2认同)

Cyr*_* N. 27

这是我的盐:

current = datetime.datetime(mydate.year, mydate.month, 1)
next_month = datetime.datetime(mydate.year + (mydate.month / 12), ((mydate.month % 12) + 1), 1)
Run Code Online (Sandbox Code Playgroud)

快捷方便 :)

  • 这并没有完全解决OP的问题,但它确实适用于我的情况. (4认同)
  • 这并不能解决问题:它会将您带到下个月的第一天,而不是“同一天”。当然,您可以将“1”更改为 mydate.day,但是当您从 1 月 31 日到 2 月时可能会出错。 (2认同)
  • `next_month = datetime.datetime(mydate.year + int(mydate.month / 12),(((mydate.month%12)+ 1),1)'')。添加** int **演员表。 (2认同)
  • `next_month = datetime(如果月份 == 12,则年+1,否则年,如果月 == 12,否则年,则 1)` (2认同)
  • 纯粹的厉害!!! (2认同)

jar*_*lan 11

既然没有人提出任何解决方案,这就是我迄今为止的解决方法

year, month= divmod(mydate.month+1, 12)
if month == 0: 
      month = 12
      year = year -1
next_month = datetime.datetime(mydate.year + year, month, 1)
Run Code Online (Sandbox Code Playgroud)

  • 虽然,这并没有解决问题:它会带你到下个月的第一天,而不是"同一天". (3认同)

Eri*_*ack 10

使用monthdelta包,它就像timedelta一样,但是对于日历月而不是几天/小时/等.

这是一个例子:

from monthdelta import MonthDelta

def prev_month(date):
    """Back one month and preserve day if possible"""
    return date + MonthDelta(-1)
Run Code Online (Sandbox Code Playgroud)

与DIY方法相比:

def prev_month(date):
    """Back one month and preserve day if possible"""
   day_of_month = date.day
   if day_of_month != 1:
           date = date.replace(day=1)
   date -= datetime.timedelta(days=1)
   while True:
           try:
                   date = date.replace(day=day_of_month)
                   return date
           except ValueError:
                   day_of_month -= 1               
Run Code Online (Sandbox Code Playgroud)

  • 这是最简单的解决方案。 (2认同)
  • 如果必须安装其他软件包,我宁愿使用python-dateutil。 (2认同)

uzi*_*uzi 6

也许使用calendar.monthrange()添加当月的天数?

import calendar, datetime

def increment_month(when):
    days = calendar.monthrange(when.year, when.month)[1]
    return when + datetime.timedelta(days=days)

now = datetime.datetime.now()
print 'It is now %s' % now
print 'In a month, it will be %s' % increment_month(now)
Run Code Online (Sandbox Code Playgroud)


Mic*_*bor 6

这个如何?(不需要任何额外的库)

from datetime import date, timedelta
from calendar import monthrange

today = date.today()
month_later = date(today.year, today.month, monthrange(today.year, today.month)[1]) + timedelta(1)
Run Code Online (Sandbox Code Playgroud)


Col*_*son 6

from datetime import timedelta
try:
    next = (x.replace(day=1) + timedelta(days=31)).replace(day=x.day)
except ValueError:  # January 31 will return last day of February.
    next = (x + timedelta(days=31)).replace(day=1) - timedelta(days=1)
Run Code Online (Sandbox Code Playgroud)

如果您只想下个月的第一天:

next = (x.replace(day=1) + timedelta(days=31)).replace(day=1)
Run Code Online (Sandbox Code Playgroud)


Dar*_*ber 6

要计算当前,上个月和下个月:

import datetime
this_month = datetime.date.today().month
last_month = datetime.date.today().month - 1 or 12
next_month = (datetime.date.today().month + 1) % 12 or 12
Run Code Online (Sandbox Code Playgroud)

  • 更短的 `next_month = datetime.date.today().month % 12 + 1` (2认同)

amo*_*mol 5

最简单的解决方案是在月底(我们总是知道每月至少有 28 天)并添加足够的天数以移至下个月:

>>> from datetime import datetime, timedelta
>>> today = datetime.today()
>>> today
datetime.datetime(2014, 4, 30, 11, 47, 27, 811253)
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
datetime.datetime(2014, 5, 30, 11, 47, 27, 811253)
Run Code Online (Sandbox Code Playgroud)

也适用于年份之间:

>>> dec31
datetime.datetime(2015, 12, 31, 11, 47, 27, 811253)
>>> today = dec31
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
Run Code Online (Sandbox Code Playgroud)

请记住,不能保证下个月会是同一天,例如,从 1 月 31 日移动到 2 月 31 日时,它将失败:

>>> today
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: day is out of range for month
Run Code Online (Sandbox Code Playgroud)

因此,如果您需要移至下个月的第一天,这是一个有效的解决方案,因为您始终知道下个月有第1天( .replace(day=1))。否则,要移至最后可用日期,您可能需要使用:

>>> today
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
>>> next_month = (today.replace(day=28) + timedelta(days=10))
>>> import calendar
>>> next_month.replace(day=min(today.day, 
                               calendar.monthrange(next_month.year, next_month.month)[1]))
datetime.datetime(2016, 2, 29, 11, 47, 27, 811253)
Run Code Online (Sandbox Code Playgroud)