Rutas
/
Julia
Julia
/
Ejercicios
/
Reservar cita de belleza
Reservar cita de belleza

Reservar cita de belleza

Ejercicio de aprendizaje

Introducción

«Las fechas y las horas son algo que enseñamos a los niños pequeños. ¿Qué dificultad puede tener?»

Muchos programadores han cometido ese error, y la experiencia posterior suele tener un efecto negativo en su salud y su felicidad.

Cualquiera que haga programación no trivial con fechas y horas debería estar al menos preparado para comprender y mitigar los posibles problemas.

Este documento intentará ofrecer una visión general de cómo Julia gestiona las fechas y las horas, pero será necesario consultar el manual para más detalles. También hay un Wikibook cuyas explicaciones pueden resultar más claras a algunos lectores, e incluye un útil diagrama de la jerarquía de tipos.

El módulo Dates

La mayor parte de la funcionalidad básica está en Dates, un módulo que se incluye en una instalación predeterminada pero que no forma parte de la biblioteca estándar.

Para usar el módulo, hay dos opciones:

  1. Añade import Dates y, después, antepón Dates. a todas las llamadas a funciones.
  2. Añade using Dates, lo que trae todo el módulo al espacio de nombres actual (excepto unos cuantos nombres problemáticos).
# option 1
julia> import Dates

julia> Dates.now()
2025-06-21T16:02:39.080

julia> now()  # wrong: need to include `Dates.` after an import
ERROR: UndefVarError: `now` not defined in `Main`


# option 2
julia> using Dates

julia> now()  # functions are now in the namespace
2025-06-21T16:03:04.161

El módulo Dates es grande y complicado, pero proporciona cuatro tipos principales de funcionalidad:

  • Dates.Date, que incluye día, mes y año, pero no la hora del día.
  • Dates.Time, que incluye la hora del día, pero no la fecha.
  • Dates.DateTime, que combina fecha y hora.
  • Dates.Period, que gestiona intervalos de tiempo y fecha.

Ten en cuenta que un DateTime generalmente no incluye información sobre la zona horaria (Python lo llamaría un datetime «naive»). Una excepción es now(), que obtiene la hora local del reloj de tu sistema y puede convertirla a UTC si es necesario.

Quizá las necesidades más frecuentes sean:

  • Analizar algún formato de entrada adecuado para construir un tipo de Dates.
  • Obtener el formato numérico o de string requerido a partir de un tipo de Dates.
  • Aplicar un desplazamiento a un valor Date, Time o DateTime.
  • Calcular el intervalo entre dos de esos valores.
  • Obtener la fecha actual (con today()) y/o la hora actual (con now()).
Note

Para reducir las distracciones visuales, la mayor parte del código de ejemplo del resto de este documento da por supuesto using Dates y evita incluir el nombre del módulo Dates. en las llamadas a funciones.

Formatos de fecha y hora

Hay muchas formas de escribir fechas y horas, que tienden a ser específicas de cada cultura. Las fechas escritas solo con números, como «7/6/23», son ambiguas, confusas y han provocado muchos errores costosos en organizaciones multinacionales (el autor lo dice por amarga experiencia personal).

El estándar internacional se define en ISO 8601, con dos ventajas principales:

  • El análisis es rápido e inequívoco.
  • La ordenación es sencilla, ya que el datetime puede tratarse como texto normal y ordenarse alfabéticamente.

Vimos en un ejemplo anterior que Date.now() devolvía 2025-06-21T16:03:04.161.

Se compone de varias partes:

  • YYYY-MM-DD para la parte de la fecha.
  • hh:mm:ss para la parte de la hora.
  • Opcionalmente, milisegundos (o una unidad aún más pequeña) después del separador decimal.

Otros formatos de string se tratarán en una sección posterior.

Fechas

Dates.Date es un tipo relativamente simple que solo representa fechas, sin ninguna noción de horas ni de zonas horarias.

# constructor with year, month, day arguments
julia> date1 = Date(2025, 06, 23)
2025-06-23

# constructor with ISO 8601 string
julia> date2 = Date("2025-06-23")
2025-06-23

julia> date1 == date2
true

julia> typeof(date1)
Date

Hay funciones de acceso para las distintas partes de la fecha, y vienen en pares que se distinguen por el uso de mayúsculas o minúsculas.

# lowercase returns an integer
julia> month(date1)
6

julia> typeof(month(date1))
Int64

# Propercase returns a Period type
julia> Month(date1)
6 months

julia> typeof(Month(date1))
Month

Funciones de consulta

Hay varias funciones que entienden algo del calendario. El siguiente ejemplo muestra solo unas pocas.

julia> date1
2025-06-23

julia> dayofweek(date1) # 1 = Monday, 7 = Sunday
1

julia> dayname(date1)
"Monday"

julia> daysinmonth(date1)
30

julia> isleapyear(date1)
false

julia> lastdayofmonth(date1)
2025-06-30

Horas

Dates.Time es el tipo básico que solo representa horas. No tiene ninguna noción de las fechas: las horas vuelven automáticamente a Time(0, 0, 0) a medianoche.

El formato completo del constructor es Time(hour, min, sec, millisec, microsec) o su equivalente en ISO 8601.

Todos los parámetros son opcionales y toman el valor 0 de forma predeterminada.

julia> Time(14, 57, 25, 142)
14:57:25.142

julia> Time("14:57:25.142")
14:57:25.142

julia> Time(14, 57, 25, 142, 32)
14:57:25.142032

Al igual que con Date, las distintas partes están disponibles mediante funciones de acceso:

julia> minute(t) # => integer
57

julia> Minute(t) # => Period
57 minutes

Fechas y horas

Dates.DateTime combina la mayoría de las características de los tipos Date y Time.

julia> dt1 = DateTime(2025, 6, 23, 14, 57, 25, 142)
2025-06-23T14:57:25.142

# date1 and t were defined in previous examples
julia> dt2 = DateTime(date1, t)
2025-06-23T14:57:25.142

Los parámetros de año, mes y día toman el valor 1 de forma predeterminada, y los parámetros de hora toman todos el valor 0.

Mantener el orden correcto de todos estos parámetros puede ser todo un reto, así que el formato ISO puede ser preferible para la entrada.

Como alternativa, un DateTime puede construirse a partir de un Date y un Time, como en el ejemplo anterior.

Periodos

Cada uno de los componentes de fecha y hora tiene su propio tipo Period, desde Year hasta Nanosecond, que representa un intervalo de tiempo. Estos son especialmente útiles para la aritmética.

julia> dt1
2025-06-23T14:57:25.142

julia> Year(21)
21 years

julia> Second(61)
61 seconds

julia> dt1 + Year(21) - Second(61)
2046-06-23T14:56:24.142

julia> Date(2025, 07, 03) - Date(2025, 04, 25)
69 days

Cuando se trabaja con tipos Period, Julia intenta ser inteligente con las irregularidades del calendario, como la duración de los meses, redondeando cuando es necesario.

# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1) 
2025-02-28

Representaciones como string

Antes mencionamos el estándar ISO 8601, que es la representación predeterminada de fecha y hora de Julia al formatear o analizar strings.

Obviamente, se usan con frecuencia muchos otros formatos, a menudo de maneras específicas de cada cultura. Para gestionarlos, Julia cuenta con el tipo DateFormat, que puede construirse a partir de un string de formato de complejidad arbitraria.

# dateformat"" string syntax
julia> dtfmt = dateformat"d/m/y"
dateformat"d/m/y"

julia> typeof(dtfmt)
DateFormat{Symbol("d/m/y"), Tuple{Dates.DatePart{'d'}, Dates.Delim{Char, 1}, Dates.DatePart{'m'}, Dates.Delim{Char, 1}, Dates.DatePart{'y'}}}

# DateFormat constructor
julia> DateFormat("d/m/y")
dateformat"d/m/y"

El ejemplo anterior es muy sencillo, solo una fecha en el formato día/mes/año habitual en Europa. Se muestran dos variantes de la sintaxis, pero el resultado es idéntico.

Un DateFormat puede usarse después para analizar cualquier string adecuado:

julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00

Crear un DateFormat implica una sobrecarga considerable, así que hacer este paso una sola vez (como aquí con dtfmt) ayuda al rendimiento cuando se recorre un gran número de strings de fecha y hora.

Los formatos pueden ser mucho más complejos que esto, así que consulta el manual para más detalles.

El mismo DateFormat también puede usarse para mostrar una fecha y hora en cualquier formato de string deseado, mediante la función Dates.format().

Lamentablemente, parece haber un conflicto de espacio de nombres con format (al menos en Julia 1.11.5), así que lo mejor es incluir el prefijo Dates. incluso después de using Dates.

julia> dt1
2025-06-23T14:57:25.142

julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"

Como se documenta, "e, u d" proporciona la representación de texto abreviada del día de la semana y del mes.

La representación de texto es el inglés de forma predeterminada. Se pueden añadir otros idiomas, aunque actualmente el soporte para ello no es óptimo.

Instrucciones

En este ejercicio vas a trabajar en un planificador de citas para un salón de belleza de Nueva York que abrió sus puertas el 15 de septiembre de 2012.

Tienes cinco tareas, todas ellas relacionadas con fechas de citas. Las horas están en formato de 24 horas (sin AM/PM).

1. Analizar una fecha de cita totalmente numérica

Implementa la función schedule_appointment() para analizar una representación textual de una fecha de cita y convertirla al formato DateTime correspondiente.

Ten en cuenta que la entrada sigue el formato estadounidense mes/día/año.

julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00

2. Comprobar si una cita ya ha pasado

Implementa la función has_passed(), que recibe una fecha de cita y comprueba si la cita fue en algún momento del pasado:

julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true

3. Comprobar si la cita es por la tarde

Implementa la función is_afternoon_appointment(), que recibe una fecha de cita y comprueba si la cita es por la tarde (>= 12:00 y < 18:00):

julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true

4. Describir la hora y la fecha de la cita

Implementa la función description(), que recibe una fecha de cita y devuelve una descripción de esa fecha y hora:

julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"

5. Devolver la fecha de aniversario

Implementa la función anniversary_date(), que devuelve la fecha de aniversario de este año, que es el 15 de septiembre:

julia> anniversary_date()  # run during 2025
2025-09-15
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Julia Exercism

¿Listo para empezar Reservar cita de belleza?

Regístrate en Exercism para aprender y dominar Julia con 35 conceptos128 ejercicios y mentoría humana real, todo gratis.