ultimo sumar sistema restar obtener mes horas hora formato fechas fecha con capturar actual python date

sumar - restar fechas con python



Consigue el último día del mes en Python (25)

¡Usa pandas!

def isMonthEnd(date): return date + pd.offsets.MonthEnd(0) == date isMonthEnd(datetime(1999, 12, 31)) True isMonthEnd(pd.Timestamp(''1999-12-31'')) True isMonthEnd(pd.Timestamp(1965, 1, 10)) False

¿Hay alguna manera de usar la biblioteca estándar de Python para determinar fácilmente (es decir, una llamada a una función) el último día de un mes determinado?

Si la biblioteca estándar no lo admite, ¿el paquete dateutil lo admite?


Aquí hay una solución basada en lambdas de pitón:

next_month = lambda y, m, d: (y, m + 1, 1) if m + 1 < 13 else ( y+1 , 1, 1) month_end = lambda dte: date( *next_month( *dte.timetuple()[:3] ) ) - timedelta(days=1)

El next_month lambda encuentra la representación de la tupla del primer día del mes siguiente y se transfiere al año siguiente. El month_end lambda transforma una fecha ( dte ) en una tupla, aplica next_month y crea una nueva fecha. Luego, el "fin de mes" es solo el primer día del mes siguiente menos timedelta(days=1) .


EDITAR: vea la respuesta de @Blair Conrad para una solución más limpia

>>> import datetime >>> datetime.date (2000, 2, 1) - datetime.timedelta (days = 1) datetime.date(2000, 1, 31) >>>


EDITAR: ver mi otra respuesta . Tiene una implementación mejor que esta, que dejo aquí solo en caso de que alguien esté interesado en ver cómo uno podría "rodar su propia calculadora".

@ John Millikin da una buena respuesta, con la complicación adicional de calcular el primer día del próximo mes.

Lo siguiente no es particularmente elegante, pero para averiguar el último día del mes en el que vive una fecha determinada, puede intentarlo:

def last_day_of_month(date): if date.month == 12: return date.replace(day=31) return date.replace(month=date.month+1, day=1) - datetime.timedelta(days=1) >>> last_day_of_month(datetime.date(2002, 1, 17)) datetime.date(2002, 1, 31) >>> last_day_of_month(datetime.date(2002, 12, 9)) datetime.date(2002, 12, 31) >>> last_day_of_month(datetime.date(2008, 2, 14)) datetime.date(2008, 2, 29)


Espero que sea útil por mucho ... Inténtelo de esta manera ... necesitamos importar algún paquete

import time from datetime import datetime, date from datetime import timedelta from dateutil import relativedelta start_date = fields.Date( string=''Start Date'', required=True, ) end_date = fields.Date( string=''End Date'', required=True, ) _defaults = { ''start_date'': lambda *a: time.strftime(''%Y-%m-01''), ''end_date'': lambda *a: str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10], }


Esto es realmente bastante fácil con dateutil.relativedelta (paquete python-datetutil para pip). day=31 siempre volverá el último día del mes.

Ejemplo:

from datetime import datetime from dateutil.relativedelta import relativedelta date_in_feb = datetime.datetime(2013, 2, 21) print datetime.datetime(2013, 2, 21) + relativedelta(day=31) # End-of-month >>> datetime.datetime(2013, 2, 28, 0, 0)


Esto no aborda la pregunta principal, pero un buen truco para obtener el último día laborable de un mes es usar calendar.monthcalendar , que devuelve una matriz de fechas, organizada con el lunes desde la primera columna hasta el domingo como la última.

# Some random date. some_date = datetime.date(2012, 5, 23) # Get last weekday last_weekday = np.asarray(calendar.monthcalendar(some_date.year, some_date.month))[:,0:-2].ravel().max() print last_weekday 31

Todo el asunto [0:-2] es rasurar las columnas del fin de semana y desecharlas. Las fechas que caen fuera del mes se indican con 0, por lo que el máximo las ignora de manera efectiva.

El uso de numpy.ravel no es estrictamente necesario, pero odio confiar en la mera convención de que numpy.ndarray.max la matriz si no se le numpy.ndarray.max qué eje debe calcularse.


La forma más fácil (sin tener que importar el calendario), es obtener el primer día del mes siguiente y luego restarle un día.

import datetime as dt from dateutil.relativedelta import relativedelta thisDate = dt.datetime(2017, 11, 17) last_day_of_the_month = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1) print last_day_of_the_month

Salida:

datetime.datetime(2017, 11, 30, 0, 0)

PD: este código se ejecuta más rápido en comparación con el enfoque del import calendar ; vea abajo:

import datetime as dt import calendar from dateutil.relativedelta import relativedelta someDates = [dt.datetime.today() - dt.timedelta(days=x) for x in range(0, 10000)] start1 = dt.datetime.now() for thisDate in someDates: lastDay = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1) print (''Time Spent= '', dt.datetime.now() - start1) start2 = dt.datetime.now() for thisDate in someDates: lastDay = dt.datetime(thisDate.year, thisDate.month, calendar.monthrange(thisDate.year, thisDate.month)[1]) print (''Time Spent= '', dt.datetime.now() - start2)

SALIDA:

Time Spent= 0:00:00.097814 Time Spent= 0:00:00.109791

Este código asume que desea la fecha del último día del mes (es decir, no solo la parte de DD, sino la fecha completa de AAAAMMDD)


No noté esto antes cuando miraba la documentación del módulo de calendario , pero un método llamado monthrange proporciona esta información:

mes (año, mes)
Devuelve el día de la semana del primer día del mes y la cantidad de días en el mes, para el año y mes especificados.

>>> import calendar >>> calendar.monthrange(2002,1) (1, 31) >>> calendar.monthrange(2008,2) (4, 29) >>> calendar.monthrange(2100,2) (0, 28)

asi que:

calendar.monthrange(year, month)[1]

Parece la forma más sencilla de ir.

Solo para ser claros, monthrange soporta años bisiestos:

>>> from calendar import monthrange >>> monthrange(2012, 2) (2, 29)

Mi respuesta anterior todavía funciona, pero es claramente subóptima.


Otra solución sería hacer algo como esto:

from datetime import datetime def last_day_of_month(year, month): """ Work out the last day of the month """ last_days = [31, 30, 29, 28, 27] for i in last_days: try: end = datetime(year, month, i) except ValueError: continue else: return end.date() return None

Y usa la función así:

>>> >>> last_day_of_month(2008, 2) datetime.date(2008, 2, 29) >>> last_day_of_month(2009, 2) datetime.date(2009, 2, 28) >>> last_day_of_month(2008, 11) datetime.date(2008, 11, 30) >>> last_day_of_month(2008, 12) datetime.date(2008, 12, 31)


Para mí es la forma más sencilla:

selected_date = date(some_year, some_month, some_day) if selected_date.month == 12: # December last_day_selected_month = date(selected_date.year, selected_date.month, 31) else: last_day_selected_month = date(selected_date.year, selected_date.month + 1, 1) - timedelta(days=1)


Para obtener la última fecha del mes hacemos algo como esto:

from datetime import date, timedelta import calendar last_day = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])

Ahora, para explicar lo que estamos haciendo aquí, lo dividiremos en dos partes:

Lo primero es obtener la cantidad de días del mes en curso para los cuales utilizamos el monthrange que Blair Conrad ya mencionó su solución:

calendar.monthrange(date.today().year, date.today().month)[1]

segundo es obtener la última fecha en sí, lo que hacemos con la ayuda de replace por ejemplo,

>>> date.today() datetime.date(2017, 1, 3) >>> date.today().replace(day=31) datetime.date(2017, 1, 31)

y cuando los combinamos como se menciona en la parte superior obtenemos una solución dinámica.


Si está dispuesto a usar una biblioteca externa, visite http://crsmithdev.com/arrow/

U puede obtener el último día del mes con:

import arrow arrow.utcnow().ceil(''month'').date()

Esto devuelve un objeto de fecha que luego puede hacer su manipulación.


Si no desea importar el módulo de calendar , una función simple de dos pasos también puede ser:

import datetime def last_day_of_month(any_day): next_month = any_day.replace(day=28) + datetime.timedelta(days=4) # this will never fail return next_month - datetime.timedelta(days=next_month.day)

Salidas:

>>> for month in range(1, 13): ... print last_day_of_month(datetime.date(2012, month, 1)) ... 2012-01-31 2012-02-29 2012-03-31 2012-04-30 2012-05-31 2012-06-30 2012-07-31 2012-08-31 2012-09-30 2012-10-31 2012-11-30 2012-12-31


Si pasa en un rango de fechas, puede usar esto:

def last_day_of_month(any_days): res = [] for any_day in any_days: nday = any_day.days_in_month -any_day.day res.append(any_day + timedelta(days=nday)) return res


Si quieres hacer tu propia pequeña función, este es un buen punto de partida:

def eomday(year, month): """returns the number of days in a given month""" days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] d = days_per_month[month - 1] if month == 2 and (year % 4 == 0 and year % 100 != 0 or year % 400 == 0): d = 29 return d

Para esto debes conocer las reglas de los años bisiestos:

  • cada cuatro años
  • con la excepción de cada 100 años
  • pero de nuevo cada 400 años

Tengo una solución simple:

import datetime datetime.date(2012,2, 1).replace(day=1,month=datetime.date(2012,2,1).month+1)-timedelta(days=1) datetime.date(2012, 2, 29)


Usando relativedelta obtendrías la última fecha del mes así:

from dateutil.relativedelta import relativedelta last_date_of_month = datetime(mydate.year,mydate.month,1)+relativedelta(months=1,days=-1)

La idea es obtener el primer día del mes y usar relativedelta para adelantar 1 mes y 1 día para que pueda obtener el último día del mes que desea.


Usted puede calcular la fecha de finalización usted mismo. la lógica simple es restar un día de la fecha de inicio del próximo mes. :)

Así que escribe un método personalizado,

import datetime def end_date_of_a_month(date): start_date_of_this_month = date.replace(day=1) month = start_date_of_this_month.month year = start_date_of_this_month.year if month == 12: month = 1 year += 1 else: month += 1 next_month_start_date = start_date_of_this_month.replace(month=month, year=year) this_month_end_date = next_month_start_date - datetime.timedelta(days=1) return this_month_end_date

Vocación,

end_date_of_a_month(datetime.datetime.now().date())

Volverá la fecha de finalización de este mes. Pase cualquier fecha a esta función. Te devuelve la fecha de finalización de ese mes.


Yo prefiero de esta manera

import datetime import calendar date=datetime.datetime.now() month_end_date=datetime.datetime(date.year,date.month,1) + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1] - 1)


>>> import datetime >>> import calendar >>> date = datetime.datetime.now() >>> print date 2015-03-06 01:25:14.939574 >>> print date.replace(day = 1) 2015-03-01 01:25:14.939574 >>> print date.replace(day = calendar.monthrange(date.year, date.month)[1]) 2015-03-31 01:25:14.939574


from datetime import timedelta (any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)


import calendar from time import gmtime, strftime calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]

Salida:

31



Esto imprimirá el último día del mes actual. En este ejemplo, fue el 15 de mayo de 2016. Por lo tanto, su salida puede ser diferente, sin embargo, la salida será la misma cantidad de días que el mes actual. Excelente si desea verificar el último día del mes ejecutando un trabajo cron diario.

Asi que:

import calendar from time import gmtime, strftime lastDay = calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1] today = strftime("%d", gmtime()) lastDay == today

Salida:

False

A menos que sea el último día del mes.


import datetime now = datetime.datetime.now() start_month = datetime.datetime(now.year, now.month, 1) date_on_next_month = start_month + datetime.timedelta(35) start_next_month = datetime.datetime(date_on_next_month.year, date_on_next_month.month, 1) last_day_month = start_next_month - datetime.timedelta(1)


import datetime today = datetime.datetime.today() # currentr day for date example last_date = today + relativedelta(day=31) print "Date:", last_date.date(),"Day:", last_date.date().day

salida:

Date: 2018-10-31 Day: 31