jueves, 28 de julio de 2016

Python XI (formato de fechas y calendario)

Este es otro post dedicado a programación en Python, encontraréis todos los posts de este tipo juntos en el apartado Programación del blog. Y si queréis aprender más podéis visitar la web oficial de www.python.org

En este post vamos a ver como trabajar y formatear las fechas y un calendario con python. Para ello vamos a necesitar importar módulos, tal y como vimos en el post anterior


1. Modulos para trabajar con fechas (módulo time y el módulo datetime)


Para trabajar con fechas los dos módulos principales de python son el módulo time y el módulo datetime. El primero es un módulo de bajo nivel con diversas funciones pero no todas ellas están disponibles en todas las plataformas. Por otro lado tenemos el módulo datetime que nos proporciona un abanico más amplio.

Me centraré directamente en el módulo datetime aunque si tenéis curiosidad aquí tenéis un enlace de referencia para el módulo time

https://docs.python.org/3/library/time.html


1.1 Módulo datetime 



Como ya he dicho este módulo porporciona un abanico más amplio para trabajar con fechas, vamos a ver algunas de las muchas opciones que podremos usar. 


1.1.1 Obtener la fecha y hora actual

Vamos a ver como obtener la fecha y hora actual del sistema y como ver por separado cada uno de estos elementos, vamos con un ejemplo

# importamos el modulo datetime
import datetime
# guardamos en la variable instante la fecha y hora actual
instante=datetime.datetime.now()
# mostramos por pantalla la fecha y hora actuales en formato UTC
print("fecha y hora en formato UTC: ",instante.utcnow())
# mostramos solo el año
print("año actual: ",instante.year)
# mostramos solo el mes
print("mes actual: ",instante.month)
# mostramos solo el dia
print("dia actual: ",instante.day)
# mostramos solo la hora
print("hora actual: ",instante.hour)
# mostramos solo los minutos
print("minutos actuales: ",instante.minute)
# mostramos solo los segundos
print("segundos actuales: ",instante.second)
# mostramos solo los milisegundos
print("milisegundos actuales: ",instante.microsecond)

1.1.2 Aplicar un formato a la fecha y la hora

Como podemos ver en el ejemplo anterior por defecto la fecha sale formateada con el año-mes-dia (aaaa-mm-dd). Pero podemos aplicar un formato concreto a la fecha y la hora para trabjar de forma más cómoda.

# importamos el modulo datetime
import datetime
# guardamos en la variable instante la fecha y hora actual
instante=datetime.datetime.now()
# mostramos la fecha y hora en formato original
print(instante)
# mostramos la fecha y hora con formato dd-mm-aaaa hh:mm:ss
instante_formateado=instante.strftime("%d-%m-%Y %H:%M:%S")
# mostramos por pantalla la fecha y la hora con el nuevo formato
print(instante_formateado)

en este ejemplo hemos importado el módulo datetime y hemos guardado en la variable instante la fecha y hora actuales y las mostramos por pantalla, seguidamente se ha aplicado un formato a la variable con instante.strftime("%d-%m-%Y %H:%M:%S"). Este formato lo conseguimos gracias a la cadena entre comillas, pero disponemos de muchas más opciones para formatear  os las dejo las principales en el siguiente cuadro


%a Nombre local abreviado de día de semana
%A Nombre local completo de día de semana
%b Nombre local abreviado de mes
%B Nombre local completo de mes
%c Representación local de fecha y hora
%d Día de mes [01,31]
%H Hora (horario 24 horas) [00,23]
%I Hora (horario 12 horas) [01,12]
%j Número de día del año [001,366]
%m Mes [01,12]
%M Minuto [00,59]
%p Etiqueta AM o PM
%S Segundo
%U Nº semana del año. Se considera al Domingo como primer día de semana [00,53]
%w Establece el primer día de semana [0(Domingo),1(Lunes)... 6].
%W Nº semana del año (Se considera al Lunes como primer día de semana) [00,53]
%x Fecha local
%X Hora local
%y Año en formato corto [00,99]
%Y Año en formato largo
%Z Nombre de Zona Horaria

os animo a modificar el código del ejemplo anterior para ver como queda con las diferentes opciones de formato

por otro lado en el siguiente ejemplo mostraremos la fecha con formato largo

# importamos el modulo datetime
import datetime
# guardamos en una variable la fecha y hora actual
fecha_actual=datetime.datetime.now()
# guardamos en una variable la fecha con formato largo
fecha_actual_formateada=datetime.datetime.ctime(fecha_actual)
# mostramos por pantalla la fecha en formato largo
print("fecha actual formateada: ",fecha_actual_formateada)

1.1.3 Generar una fecha concreta

Hasta ahora hemos visto como obtener la fecha del sistema, pero si queremos trabajar con fechas concretas podemos generar una variable de tipo fecha con un valor determinado. Mirad el siguiente ejemplo

# importamos el modulo datetime
import datetime
# guardamos en una variable la fecha actual
fecha_actual=datetime.datetime.now()
# guardamos en una variable la fecha de vuestro nacimiento
fecha_nacimiento=datetime.datetime(1976, 8, 5, 0 , 0, 0)
# restamos las dos fechas y guardamos el valor en una variable
diferencia_fechas=fecha_actual-fecha_nacimiento
# mostramos por pantalla la fecha inicial y la de nacimiento
print("fecha actual: ",fecha_actual)
print("fecha_nacimiento: ",fecha_nacimiento)
# mostramos por pantalla la diferencia entre las dos fechas
print("diferencia_fechas: ",diferencia_fechas)
# diferencia en días
print("diferencia en días: ",diferencia_fechas.days)
# diferencia en segundos
print("diferencia en segundos: ",diferencia_fechas.seconds)

en este ejemplo hemos generado dos variables con dos fechas para (la actual y la fecha de vuestro nacimiento) para asignar la fecha de nacimiento hemos usado al orden fecha_nacimiento=datetime.datetime(1976, 8, 5, 0 , 0, 0), la primera posición es el año, la segunda es el mes la tercera el día, la cuarta la hora, la quinta los minutos la sexta los segundos (las tres últimas las he dejado a cero) luego hemos restado las fechas y mostramos por pantalla el valor de la diferencia en días y segundos. Tened en cuenta que para realizar operaciones con fechas estas deben tener el mismo formato, en este ejemplo la variable fecha_actual tiene por defecto el formato (aaaa-mm-dd), de la misma forma que fecha_nacimiento en la que he asignado una fecha con el mismo formato. Si realizamos operaciones con fechas en formato distinto el resultado no será correcto.

1.1.4 Operaciones con fechas

En el ejemplo anterior ya hemos visto la primera operación, lo más importante es que al realizar operaciones tengamos las fechas en el mismo formato. Vamos a ver algunas cosas que se pueden hacer con las fechas, en este caso vamos a usar timedelta que nos permite realizar operaciones con semanas, dias, horas, minutos,segundos, milisegundos y microsegundos

# importamos el modulo datetime
import datetime
# creamos la variable fecha_actual y guardamos la fecha del sistema
fecha_actual=datetime.datetime.now()
fecha_ayer=fecha_actual-datetime.timedelta(days=1)
fecha_manana=fecha_actual+datetime.timedelta(days=1)
# mostramos por pantalla las tres fechas
print("print fecha actual: ", fecha_actual)
print("print fecha ayer: ", fecha_ayer)
print("print fecha mañana: ", fecha_manana)

en este ejemplo guardamos el día actual  y luego usamos timedelta para sumar y restar días. En el siguiente ejemplo veremos como trabajar con otras unidades de tiempo

# importamos el modulo datetime
import datetime
# creamos la variable fecha_actual y guardamos la fecha del sistema
fecha_actual=datetime.datetime.now()
# sumamos a fecha_actual 2 millones de segundos
fecha_actual_mas2mlls=fecha_actual+datetime.timedelta(seconds=2000000)
# sumamos a la fecha acctual 10 horas
fecha_actual_mas10h=fecha_actual+datetime.timedelta(hours=10)
# mostramos los valores por pantalla
print("fecha actual: ",fecha_actual)
print("fecha actual mas 2 millones de segundos: ",fecha_actual_mas2mlls)
print("fecha actual mas 10 horas: ",fecha_actual_mas10h)

también podemos comparar fechas y horas (recordad que para realizar operaciones con fechas deben tener el mismo formato)

# importamos el modulo datetime
import datetime
# guardamos una variable con una hora inicial 10:05:00
hora_inicial=datetime.time(10,5,0)
# guardamos una variable con una hora final 23:15:00
hora_final=datetime.time(23,15,0)
if hora_inicial<hora_final:
    print("hora inicial ", hora_inicial, " anterior a hora final ", hora_final)
# guardamos en una varibale la fecha actual
fecha_actual=datetime.datetime.now()
#guaradamos en una variable otra fecha
fecha_anterior=datetime.datetime(1976,8,1,0,0,0)
if fecha_actual>fecha_anterior:
    print("fecha actual ", fecha_actual, " mayor que fecha anterior ", fecha_anterior)

1.1.5 Obtener el día de la semana de una fecha

podemos saber el día de la semana de una fecha concreta teniendo en cuenta que si no modificamos el formato del número del primer día de la semana (%w o %W, ver cuadro mas arriba) corresponde a:  0=lunes, 1=martes, 2=miércoles, 3=jueves, 4=viernes, 5=sábado, 6=domingo

# importamos modulo datetime
import datetime
# guardamos en una variable la fecha de vuestro nacimiento
fecha_nacimiento=datetime.datetime(1976, 8, 1, 0, 0, 0)
# guardamos en una variable el día de la semana de la fecha
dia_semana=datetime.datetime.weekday(fecha_nacimiento)
# mostramos por pantalla el resultado
print("fecha nacimiento: ", fecha_nacimiento, "- día de la semana: ", dia_semana)

en este ejemplo obtenemos el valor 6=domingo que es el día de la semana del 1 de agosto de 1976.

1.1.6 Alguna cosa más

Hasta ahora os he mostrado ejemplos que trabajan básicamente con datetime.datetime esto nos proporciona la fecha completa en formato aaaa-mm-dd hh:mm:ss, sin embargo muchas veces no necesitamos trabajar con horas, minutos y segundos, nos bastará con la fecha, en este caso podemos usar datetime.date, mirad este ejemplo

# importamos el modulo datetime
import datetime
# obtenemos la fecha actual
fecha_actual=datetime.date.today()
# mostramos la fecha obtenida
print("fecha actual: ",fecha_actual)

a partir de aquí también podríamos realizar operaciones tal y como hemos visto en ejemplos anteriores.

Creo que con estos ejemplos ya tenéis una pequeña base para trabajar con fechas, el módulo datetime, dispone de muchas otras opciones podéis ir a la web oficial de python para saber más

https://docs.python.org/3/library/datetime.html



1.2 Módulo calendar



Este módulo nos ofrece la posibilidad de trabajar con el calendario de una forma "sencilla", veamos algunas opciones

1.2.1 Mostrar el calendario del mes actual por pantalla con print()

veamos un ejemplo sencillo para ver el mes actual por pantalla

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el mes y año actuales
M=datetime.date.today().month
Y=datetime.date.today().year
# guardamos en una variable el calendario del mes
calendario=calendar.month(Y,M)
# mostramos el calendario por pantalla
print(calendario)

1.2.2 Mostrar el calendario del mes actual por pantalla con prmonth()

otra forma de hacerlo es esta, usando la orden prmonth(), sin usar la orden print()

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el mes y año actuales
M=datetime.date.today().month
Y=datetime.date.today().year
# mostramos por pantalla el calendario del mes con prmonth()
calendar.prmonth(Y,M)

1.2.3 Cambiar el primer día de la semana del calendario

si es necesario podemos cambiar el primer día de la semana de la siguiente manera (tened en cuenta que: 0=lunes, 1=martes, 2=miércoles, 3=jueves, 4=viernes, 5=sábado, 6=domingo), con este ejemplo cambiamos el primer día de la semana para que sea el martes

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el mes y año actuales
M=datetime.date.today().month
Y=datetime.date.today().year
# cambiamos el primer dia de la semana a martes asignándolo a una variable
calendario=calendar.TextCalendar(1)
# mostramos por pantalla el calendario del mes con prmonth()
calendario.prmonth(Y,M)

con TextCalendar podemos configurar las opciones de salida en formato de texto del calendario luego lo veremos con más detalle. 

En el siguiente ejemplo vamos a mostrar el calendario de un año completo

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el mes y año actuales
M=datetime.date.today().month
Y=datetime.date.today().year
# guardamos en una variable la matriz del calendario
calendario=calendar.TextCalendar(0)
calendario.pryear(Y)

si queréis dar formato a lo que vemos por pantalla detras de TextCalendar() podemos usar formatyear() que admite un total de 5 parámetros: el año, espacio entre columnas de los días, espacio entre las lineas por semana, espacios entre las columnas de los meses, número de meses que se muestran en cada fila. mirad el siguiente ejemplo y modificadlo para ver como cambia la presentación.

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el año actual
Y=datetime.date.today().year
# guardamos en una variable la matriz del calendario con la configuración
calendario=calendar.TextCalendar(0).formatyear(Y,1,1,1,2)
# mostramos por pantalla el calendario
print(calendario)


1.2.4 Obtener la matriz del calendario

también podemos obtener una matriz con la información del calendario del mes, como se muestra en este ejemplo

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el mes y año actuales
M=datetime.date.today().month
Y=datetime.date.today().year
# guardamos en una variable la matriz del calendario
calendario=calendar.Calendar()
# mostramos por pantalla los elementos de la matriz con un bucle
for elemento in calendario.monthdayscalendar(Y,M):
    print(elemento)

también podemos obtener la matriz del calendario con una tupla donde el primer dígito muestra el día del mes y el segundo la posición del día de la semana

# importamos el modulo datetime y calendar
import datetime
import calendar
# obetenemos el mes y año actuales
M=datetime.date.today().month
Y=datetime.date.today().year
# guardamos en una variable la matriz del calendario
calendario=calendar.Calendar()
# mostramos por pantalla los elementos de la matriz con un bucle
for elemento in calendario.monthdays2calendar(Y,M):
    print(elemento)

para saber más sobre el módulo calendar podéis visitar la web oficial de python

https://docs.python.org/3/library/calendar.html

espero que todo esto os sirva de ayuda, hasta pronto.