Tracks
/
Julia
Julia
/
Ejercicios
/
Citas para el salón de belleza
Citas para el salón de belleza

Citas para el salón de belleza

Ejercicio de aprendizaje

Introducción

«Las fechas y las horas son algo que le enseñamos a los niños pequeños. ¿Qué tan difícil puede ser?»

Muchos programadores han cometido ese error, y la experiencia que sigue suele tener un mal efecto en su salud y su felicidad.

Quien haga programación no trivial con fechas y horas debería al menos estar en condiciones de entender y mitigar posibles problemas.

Este documento intentará dar una visión general de cómo Julia maneja las fechas y las horas, pero para más detalles será necesario consultar el manual. También hay un Wikibook cuyas explicaciones pueden resultar más claras para 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. Agregar import Dates y luego anteponer Dates. a todas las llamadas a funciones.
  2. Agregar using Dates, lo que trae todo el módulo al espacio de nombres actual (excepto unos pocos 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 ofrece cuatro tipos principales de funcionalidad:

  • Dates.Date, que incluye día-mes-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 maneja intervalos de tiempo y de fecha.

Ten en cuenta que un DateTime por lo general no incluye información de zona horaria (Python a esto 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 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 (con now()).
Note

Para reducir la distracción visual, la mayor parte del código de ejemplo en el resto de este documento supone using Dates y evita incluir el nombre del módulo Dates. en las llamadas a funciones.

Formatos de fecha y hora

Hay muchas maneras de escribir fechas y horas, y suelen depender de la cultura. Las fechas 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 y no da lugar a ambigüedades.
  • Ordenar es fácil, ya que se puede tratar como texto normal y ordenarlo alfabéticamente.

En un ejemplo anterior vimos 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.
  • De forma opcional, milisegundos (o una unidad aún más pequeña) después del punto decimal.

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

Fechas

Dates.Date es un tipo relativamente simple que solo maneja fechas, sin 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 partes individuales 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 una variedad de funciones con cierta noción del calendario. El siguiente ejemplo muestra solo algunas.

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 maneja horas. No tiene noción de fechas: las horas vuelven automáticamente a Time(0, 0, 0) a la 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 0 por defecto.

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 partes individuales 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 1 por defecto, y los parámetros de hora toman todos 0 por defecto.

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

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

Períodos

Cada uno de los componentes de fecha y hora tiene su propio tipo Period, desde Year hasta Nanosecond, que representa un intervalo de tiempo. Resultan 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 trabajas con tipos Period, Julia intenta ser inteligente con las irregularidades del calendario, como la duración de los meses, y redondea cuando es necesario.

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

Representaciones de string

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

Obviamente, muchos otros formatos se usan con frecuencia, a menudo de maneras propias de cada cultura. Para manejarlos, Julia tiene el tipo DateFormat, que se puede construir 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 simple: solo una fecha en el formato día/mes/año común en Europa. Se muestran dos variantes de la sintaxis, pero el resultado es idéntico.

Luego, un DateFormat se puede usar 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 con el rendimiento cuando se recorre en un bucle una gran cantidad 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 se puede usar para mostrar una fecha y hora en cualquier formato de string deseado, con 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" da la representación de texto abreviada para el día de la semana y el mes.

La representación de texto toma el inglés por defecto. Se pueden agregar otros idiomas, aunque por ahora el soporte para esto no es óptimo.

Instrucciones

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

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

1. Convierte la fecha de una cita en formato numérico

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

Nota que la entrada está en el orden estadounidense mes/día/año.

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

2. Verifica si una cita ya pasó

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

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

3. Verifica si la cita es por la tarde

Implementa la función is_afternoon_appointment() que toma la fecha de una cita y verifica 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. Describe la hora y la fecha de la cita

Implementa la función description() que toma la fecha de una 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. Devuelve la fecha del aniversario

Implementa la función anniversary_date() que devuelve la fecha del 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 una pestaña nuevas
Julia Exercism

¿Todo listo para empezar Citas para el salón de belleza?

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