sistema - modulo tiempo python
Cómo incrementar el horario por meses personalizados en python sin usar la biblioteca (21)
Esta pregunta ya tiene una respuesta aquí:
Necesito incrementar el mes de un valor de fecha y hora
next_month = datetime.datetime(mydate.year, mydate.month+1, 1)
cuando el mes es 12, se convierte en 13 y aumenta el error "el mes debe estar en 1..12". (Esperaba que el año aumentara)
Quería usar timedelta, pero no toma argumento de mes. Hay relativedelta paquete relativedelta python, pero no quiero instalarlo solo para esto. También hay una solución usando strtotime .
time = strtotime(str(mydate));
next_month = date("Y-m-d", strtotime("+1 month", time));
No quiero convertir de datetime a str, luego a time y luego a datetime; por lo tanto, sigue siendo una biblioteca también
¿Alguien tiene alguna solución buena y simple al igual que el uso de timedelta?
¿Qué hay de este? (no requiere ninguna biblioteca adicional)
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)
Aquí está mi sal:
current = datetime.datetime(mydate.year, mydate.month, 1)
next_month = datetime.datetime(mydate.year + (mydate.month / 12), ((mydate.month % 12) + 1), 1)
Rapido y Facil :)
Bueno, con algunos ajustes y el uso de timedelta aquí vamos:
from datetime import datetime, timedelta
def inc_date(origin_date):
day = origin_date.day
month = origin_date.month
year = origin_date.year
if origin_date.month == 12:
delta = datetime(year + 1, 1, day) - origin_date
else:
delta = datetime(year, month + 1, day) - origin_date
return origin_date + delta
final_date = inc_date(datetime.today())
print final_date.date()
Esta implementación puede tener algún valor para alguien que está trabajando con la facturación.
Si está trabajando con la facturación, es probable que desee obtener "la misma fecha el próximo mes (si es posible)" en lugar de "agregar 1/12 de un año".
Lo que es tan confuso acerca de esto es que realmente necesita tener en cuenta dos valores si lo hace continuamente. De lo contrario, para cualquier fecha posterior al día 27, seguirás perdiendo algunos días hasta que termines el día 27 después del año bisiesto.
Los valores que necesita para tener en cuenta:
- El valor que desea agregar un mes a
- El día que comenzaste con
De esta forma, si se ve afectado desde el 31 hasta el 30 cuando agrega un mes, se lo devolverá al 31 por el mes siguiente que tenga ese día.
Así es como lo hice:
def closest_date_next_month(year, month, day):
month = month + 1
if month == 13:
month = 1
year = year + 1
condition = True
while condition:
try:
return datetime.datetime(year, month, day)
except ValueError:
day = day-1
condition = day > 26
raise Exception(''Problem getting date next month'')
paid_until = closest_date_next_month(
last_paid_until.year,
last_paid_until.month,
original_purchase_date.day) # The trick is here, I''m using the original date, that I started adding from, not the last one
Estaba buscando resolver el problema relacionado de encontrar la fecha para el primer día del mes siguiente, independientemente del día en la fecha indicada. Esto no se encuentra el mismo día 1 mes después.
Por lo tanto, si todo lo que desea es colocarlo el 12 de diciembre de 2014 (o cualquier día de diciembre) y obtener el 1 de enero de 2015, intente esto:
import datetime
def get_next_month(date):
month = (date.month % 12) + 1
year = date.year + (date.month + 1 > 12)
return datetime.datetime(year, month, 1)
Este es un método breve y agradable para agregar un mes a una fecha usando relativedelta .
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'')
Salida:
Hoy: 01/03/2013
Después del mes: 01/04/2013
Una palabra de advertencia : relativedelta(months=1)
y relativedelta(month=1)
tienen diferentes significados .
Nota: esto requerirá python-dateutil
. Para instalarlo, necesita ejecutarlo en la terminal de Linux.
sudo apt-get update && sudo apt-get install python-dateutil
Explicación: Agregar valor de mes en python
Esto es lo que se me ocurrió
from calendar import monthrange
def same_day_months_after(start_date, months=1):
target_year = start_date.year + ((start_date.month + months) / 12)
target_month = (start_date.month + months) % 12
num_days_target_month = monthrange(target_year, target_month)[1]
return start_date.replace(year=target_year, month=target_month,
day=min(start_date.day, num_days_target_month))
La solución más simple es ir a fin de mes (siempre sabemos que los meses tienen al menos 28 días) y agregar suficientes días para pasar a la siguiente polilla:
>>> 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)
También funciona entre años:
>>> 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)
Solo tenga en cuenta que no está garantizado que el próximo mes tenga el mismo día, por ejemplo, al pasar del 31 de enero al 31 de febrero fallará:
>>> 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
Entonces, esta es una solución válida si necesita pasar al primer día del mes siguiente, ya que siempre sabrá que el próximo mes tiene el día 1 ( .replace(day=1)
). De lo contrario, para pasar al último día disponible, es posible que desee usar:
>>> 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)
Mi solución muy simple, que no requiere ningún módulo adicional:
def addmonth(date):
if date.day < 20:
date2 = date+timedelta(32)
else :
date2 = date+timedelta(25)
date2.replace(date2.year, date2.month, day)
return date2
Para calcular el mes actual, anterior y siguiente:
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
Similar en ideal a la solución de Dave Webb, pero sin toda esa complicada aritmética de módulo:
import datetime, calendar
def increment_month(date):
# Go to first of this month, and add 32 days to get to the next month
next_month = date.replace(day=1) + datetime.timedelta(32)
# Get the day of month that corresponds
day = min(date.day, calendar.monthrange(next_month.year, next_month.month)[1])
return next_month.replace(day=day)
Solo usa esto:
import datetime
today = datetime.datetime.today()
nextMonthDatetime = today + datetime.timedelta(days=(today.max.day - today.day)+1)
Tal vez, agregue la cantidad de días en el mes actual usando 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)
Una solución sin el uso de calendario:
def add_month_year(date, years=0, months=0):
year, month = date.year + years, date.month + months + 1
dyear, month = divmod(month - 1, 12)
rdate = datetime.date(year + dyear, month + 1, 1) - datetime.timedelta(1)
return rdate.replace(day = min(rdate.day, date.day))
Use el paquete monthdelta , funciona igual que timedelta, pero por meses calendario en lugar de días / horas / etc.
Aquí hay un ejemplo:
from monthdelta import MonthDelta
def prev_month(date):
"""Back one month and preserve day if possible"""
return date + MonthDelta(-1)
Compare eso con el enfoque de bricolaje:
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
ejemplo usando el objeto de tiempo:
start_time = time.gmtime(time.time()) # start now
#increment one month
start_time = time.gmtime(time.mktime([start_time.tm_year, start_time.tm_mon+1, start_time.tm_mday, start_time.tm_hour, start_time.tm_min, start_time.tm_sec, 0, 0, 0]))
ya que nadie sugirió ninguna solución, así es cómo he resuelto hasta ahora
year, month= divmod(mydate.month+1, 12)
if month == 0:
month = 12
year = year -1
next_month = datetime.datetime(mydate.year + year, month, 1)
Editar : en función de su comentario sobre las fechas que se deben redondear si hay menos días en el próximo mes, aquí hay una solución:
>>> 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)
...
>>> somedate = datetime.date.today()
>>> somedate
datetime.date(2010, 11, 9)
>>> add_months(somedate,1)
datetime.date(2010, 12, 9)
>>> add_months(somedate,23)
datetime.date(2012, 10, 9)
>>> otherdate = datetime.date(2010,10,31)
>>> add_months(otherdate,1)
datetime.date(2010, 11, 30)
Además, si no le preocupan las horas, los minutos y los segundos, puede usar la date
lugar de la datetime
. Si le preocupan las horas, los minutos y los segundos, necesita modificar mi código para usar el horario y copiar horas, minutos y segundos desde el origen hasta el resultado.
def add_month(d,n=1): return type(d)(d.year+(d.month+n-1)/12, (d.month+n-1)%12+1, 1)
def month_sub(year, month, sub_month):
result_month = 0
result_year = 0
if month > (sub_month % 12):
result_month = month - (sub_month % 12)
result_year = year - (sub_month / 12)
else:
result_month = 12 - (sub_month % 12) + month
result_year = year - (sub_month / 12 + 1)
return (result_year, result_month)
def month_add(year, month, add_month):
return month_sub(year, month, -add_month)
>>> month_add(2015, 7, 1)
(2015, 8)
>>> month_add(2015, 7, 20)
(2017, 3)
>>> month_add(2015, 7, 12)
(2016, 7)
>>> month_add(2015, 7, 24)
(2017, 7)
>>> month_add(2015, 7, -2)
(2015, 5)
>>> month_add(2015, 7, -12)
(2014, 7)
>>> month_add(2015, 7, -13)
(2014, 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)
Si simplemente desea el primer día del mes siguiente:
next = (x.replace(day=1) + timedelta(days=31)).replace(day=1)