在巨蟒中找到每月的第一天

我试图用一个条件在 python 中找到每月的第一天: 如果我的当前日期超过了这个月的25号,那么第一个日期变量将保存下个月的第一个日期,而不是当前月份。我正在做以下事情:

import datetime
todayDate = datetime.date.today()
if (todayDate - todayDate.replace(day=1)).days > 25:
x= todayDate + datetime.timedelta(30)
x.replace(day=1)
print x
else:
print todayDate.replace(day=1)

有没有更干净的方法?

206779 次浏览

Use dateutil.

from datetime import date
from dateutil.relativedelta import relativedelta


today = date.today()
first_day = today.replace(day=1)
if today.day > 25:
print(first_day + relativedelta(months=1))
else:
print(first_day)

Yes, first set a datetime to the start of the current month.

Second test if current date day > 25 and get a true/false on that. If True then add add one month to the start of month datetime object. If false then use the datetime object with the value set to the beginning of the month.

import datetime
from dateutil.relativedelta import relativedelta


todayDate = datetime.date.today()
resultDate = todayDate.replace(day=1)


if ((todayDate - resultDate).days > 25):
resultDate = resultDate + relativedelta(months=1)


print resultDate

This is a pithy solution.

import datetime


todayDate = datetime.date.today()
if todayDate.day > 25:
todayDate += datetime.timedelta(7)
print todayDate.replace(day=1)

One thing to note with the original code example is that using timedelta(30) will cause trouble if you are testing the last day of January. That is why I am using a 7-day delta.

The arrow module will steer you around and away from subtle mistakes, and it's easier to use that older products.

import arrow


def cleanWay(oneDate):
if currentDate.date().day > 25:
return currentDate.replace(months=+1,day=1)
else:
return currentDate.replace(day=1)




currentDate = arrow.get('25-Feb-2017', 'DD-MMM-YYYY')
print (currentDate.format('DD-MMM-YYYY'), cleanWay(currentDate).format('DD-MMM-YYYY'))


currentDate = arrow.get('28-Feb-2017', 'DD-MMM-YYYY')
print (currentDate.format('DD-MMM-YYYY'), cleanWay(currentDate).format('DD-MMM-YYYY'))

In this case there is no need for you to consider the varying lengths of months, for instance. Here's the output from this script.

25-Feb-2017 01-Feb-2017
28-Feb-2017 01-Mar-2017

Can be done on the same line using date.replace:

from datetime import datetime


datetime.today().replace(day=1)

Use arrow.

import arrow
arrow.utcnow().span('month')[0]

You can use dateutil.rrule:

In [1]: from dateutil.rrule import *


In [2]: rrule(DAILY, bymonthday=1)[0].date()
Out[2]: datetime.date(2018, 10, 1)


In [3]: rrule(DAILY, bymonthday=1)[1].date()
Out[3]: datetime.date(2018, 11, 1)
from datetime import datetime


date_today = datetime.now()
month_first_day = date_today.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
print(month_first_day)

My solution to find the first and last day of the current month:

def find_current_month_last_day(today: datetime) -> datetime:
if today.month == 2:
return today.replace(day=28)


if today.month in [4, 6, 9, 11]:
return today.replace(day=30)


return today.replace(day=31)




def current_month_first_and_last_days() -> tuple:
today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
first_date = today.replace(day=1)
last_date = find_current_month_last_day(today)
return first_date, last_date

This could be an alternative to Gustavo Eduardo Belduma's answer:

import datetime
first_day_of_the_month = datetime.date.today().replace(day=1)

First day of next month:

from datetime import datetime

class SomeClassName(models.Model):
if datetime.now().month == 12:
new_start_month = 1
else:
new_start_month = datetime.now().month + 1

Then we replace the month and the day

    start_date = models.DateField(default=datetime.today().replace(month=new_start_month, day=1, hour=0, minute=0, second=0, microsecond=0))

I found a clean way to do this is to create a datetime object using the month and year attributes of todayDate, with days set to 1 i.e.

import datetime
todayDate = datetime.date.today()


firstOfMon = datetime.date(todayDate.year, todayDate.month, 1)

One-liner:

from datetime import datetime, timedelta
last_month=(datetime.now().replace(day=1) - timedelta(days=1)).replace(day=1)

Inspired by Jouberto's and @akx's answers (elsewhere), oneliners without any dependencies:

now = datetime.datetime.now(tz=ZoneInfo("UTC"))
this_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
next_month = (this_month.replace(day=28) + datetime.timedelta(days=4)).replace(day=1)
last_month = (this_month.replace(day=1) - datetime.timedelta(days=1)).replace(day=1)