Rutas
/
JavaScript
JavaScript
/
Ejercicios
/
Hora de la cita
Hora de la cita

Hora de la cita

Ejercicio de aprendizaje

Introducción

JavaScript tiene un objeto integrado, Date, que almacena la fecha y la hora y proporciona métodos para gestionarlas.

Caution

Estaba basado en la clase java.util.Date de Java, que fue reemplazada a principios de la década de 2010, pero, por retrocompatibilidad, el Date de JavaScript sigue existiendo.

Debido a lo difícil que es trabajar con fechas en general y a lo mala o inexistente que es la gestión de las zonas horarias, existen muchas bibliotecas, como moment.js, day.js, date-fns y luxon. Ninguna de ellas está disponible en Exercism.

En tus propios proyectos, no uses un paquete obsoleto o sin mantenimiento como moment.js, sino que es mejor confiar en alternativas más modernas como luxon, o en Temporal, que aún no está ampliamente disponible. Este ejercicio se centra en Date, que seguirá siendo relevante hasta el fin de JavaScript.

Creación

Un objeto Date es una instancia de la clase Date. Se puede crear sin pasar ningún argumento a la función constructora. Esto da como resultado un objeto Date que representa la fecha y la hora actuales:

const now = new Date();
// => Thu Apr 14 2022 11:46:08 GMT+0530 (India Standard Time)
// Shows current day, date and time (in your time zone).

Timestamp de Unix (número)

Si se pasa un número, se interpretará como un timestamp. Un timestamp es un número entero que representa la cantidad de milisegundos transcurridos desde el 1 de enero de 1970 UTC+0.

const epoch = new Date(0);
// Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)

const another = new Date(1749508766627);
// Tue Jun 10 2025 00:39:26 GMT+0200 (Central European Summer Time)

Se podría esperar que new Date(0) genere el objeto de fecha «más temprano», pero JavaScript convertirá la fecha a tu zona horaria local, lo que significa que solo quienes tengan una zona horaria GMT / con UTC+0 obtendrán realmente el valor de la época de Unix.

Timestamp ISO 8601 (string)

Puedes pasar un valor de tipo string que represente una fecha al constructor de Date. El único formato coherente entre implementaciones es la versión simplificada de los denominados strings de timestamp ISO 8601, reconocidos y estandarizados internacionalmente.

Un momento concreto en UTC tiene este aspecto:

YYYY-MM-DDTHH:mm:ss.mssZ
YYYYMMDDTHHmmss.mssZ

Donde se aplican las siguientes sustituciones:

Clave Descripción Predeterminado
YYYY El año calendario, representado con 4 dígitos
MM El mes calendario, representado con 2 dígitos 01
DD El día calendario, representado con 2 dígitos 01
T La letra T literal, que separa la fecha de la hora
HH Las horas en un reloj de 24 horas, 2 dígitos 00
mm Los minutos, 2 dígitos 00
ss Los segundos, 2 dígitos 00
mss Los milisegundos, 3 dígitos 000
Z La letra Z literal, o un desplazamiento +/-HH:mm

La letra Z literal indica UTC (sin zona horaria, sin horario de verano).

Como la mayoría de los componentes tienen valores predeterminados, es válido omitir partes al final:

YYYY-MM-DD

El valor predeterminado es una hora de 00:00:00.000

Si el timestamp no termina en Z, y no termina con +HH:mm o -HH:mm (lo que indica un desplazamiento de zona horaria), por motivos históricos se aplica lo siguiente:

Cuando no hay desplazamiento de zona horaria, los formatos que solo incluyen la fecha se interpretan como una hora UTC, y los formatos de fecha y hora se interpretan como una hora local. La interpretación como hora UTC se debe a un error histórico de la especificación que no era coherente con ISO 8601, pero que no se pudo cambiar debido a la compatibilidad web. Consulta Broken Parser – A Web Reality Issue.

Caution

Otros formatos que acepta Date.parse pueden funcionar o no. Cuando trabajes con fechas en JavaScript, usa siempre un timestamp ISO 8601 al convertir de un string a un Date.

Los formatos que solo incluyen la fecha están permitidos, pero no se admiten todos los formatos ISO 8601. Consulta la página de MDN que explica la versión simplificada.

Objeto Date

También se puede usar un objeto de fecha existente como argumento del constructor. Esto crea una copia del objeto Date existente con la misma fecha y hora.

const t1 = new Date();
const t2 = new Date(t1);
// Values of t1 and t2 will be the same.

Proporcionar valores individuales de los componentes de fecha y hora

Se puede crear una fecha que represente una fecha pasando tres números. Se puede crear una fecha que represente una fecha y una hora pasando seis números.

const date1 = new Date(95, 11, 17);
// Creates Date for Dec 17 1995 00:00 if your local timezone is equivalent to UTC.

const date2 = new Date(2013, 12, 5, 13, 24, 0);
// Creates Date for Jan 5 2014 13:24 if your local timezone is equivalent to UTC.

El segundo valor es el month, que empieza en 0 para enero y llega hasta 11 para diciembre.

Date.parse()

Es posible que encuentres menciones o referencias a una función de parseo de fechas, Date.parse. Como esta función solo tiene unas pocas invariantes (verdades) y el resto de la implementación no está especificada (y por tanto no es estándar), no deberías usarla.

Acceder a los componentes de Date

Hay varios métodos en los objetos de fecha que devuelven los componentes de la fecha:

getFullYear(); // Get the year (4 digits)
getMonth(); // Get the month, from 0 to 11.
getDate(); // Get the day of month, from 1 to 31.
getHours(); // Get the hour in a 24 clock, from 0 to 23
getMinutes(); // Get the minutes, from 0 to 59
getSeconds(); // Get the seconds, from 0 to 59
getMilliseconds(); // Get the milliseconds, from 0 and 999
getDay(); // Get the day of week, from 0 (Sunday) to 6 (Saturday).

Cada uno de ellos tiene una variante set correspondiente (por ejemplo, setFullYear) para actualizar el valor. Cualquier valor que se desborde pasa al componente siguiente:

const date = new Date('2025-02-28T12:42:00Z');
// => Fri Feb 28 2025 13:42:00 GMT+0100 (Central European Standard Time)

date.setDate(29);
// there was no February 29th in 2025.

date.getDate();
// => 1

date.toString();
// => Sat Mar 01 2025 13:42:00 GMT+0100 (Central European Standard Time)

Existen variantes UTC de todos los métodos que ignoran la zona horaria local.

Convertir desde una fecha

Los objetos de fecha tienen un método getTime() que devuelve el timestamp UNIX en milisegundos, es decir, la cantidad de milisegundos transcurridos desde la medianoche del 1 de enero de 1970, UTC. Además, hay un método toISOString() disponible para convertir un objeto de fecha a un string de timestamp ISO 8601.

Comparar fechas

El mayor que (>), el mayor o igual que (>=), el menor que (<) y el menor o igual que (<=) se pueden usar directamente entre dos fechas o entre una fecha y un número. Esto funciona porque JavaScript intentará convertir la fecha a un tipo primitivo.

Advanced

Cuando se hace una comparación entre dos fechas, o entre una fecha y un número, JavaScript llama a [Symbol.toPrimitive]("number"), que internamente llama a date.valueOf(). Esto último es lo mismo que llamar a date.getTime().

Si no quieres depender de este comportamiento, convierte primero a un número usando getTime().

Las fechas no se pueden comparar usando igualdad (== y ===), pero el resultado de .getTime() sí.

Instrucciones

En este ejercicio vas a trabajar con algunas funciones para gestionar citas. El sistema lo almacena todo en strings con formato ISO 8601, pero así no es como la gente usa el calendario. Se necesitan varias funciones para convertir entre los distintos formatos.

1. Crea una cita

Crea una cita dentro de n días, a la hora actual. La función recibe n días y devuelve la hora de la cita dentro de n días.

createAppointment(4, now);
// Given now is Sun Oct 05 2022 23:28:43 GMT+0600 (Bangladesh Standard Time)
// => Sun Oct 09 2022 23:28:43 GMT+0600 (Bangladesh Standard Time)

Si no se usa el segundo parámetro now, se debe usar la hora actual en su lugar.

2. Convierte una fecha en una marca de tiempo

Varias herramientas solo funcionan con el formato ISO 8601, estandarizado internacionalmente. Escribe la función getAppointmentTimestamp para que reciba una fecha y devuelva un string en ese formato.

const appointment = new Date(Date.UTC(2010, 6, 16, 12, 42, 0, 0));

getAppointmentTimestamp(appointment);
// => '2010-07-16T12:42:00.000Z'

3. Obtén los detalles de una cita

Las marcas de tiempo son difíciles de leer; una función para obtener los detalles de la cita debería ayudar con eso. La función getAppointmentDetails recibe una marca de tiempo en formato ISO 8601 y devuelve el año, el mes, el día, la hora y el minuto.

getAppointmentDetails('2022-04-24T08:15:00.000');
// => { year: 2022, month: 3, date: 24, hour: 8, minute: 15 }

4. Actualiza una cita con las opciones dadas

La función recibirá como primer argumento la hora de la cita y como segundo argumento un objeto con algunas opciones. Tienes que actualizar la cita según las opciones del objeto y devolver la nueva fecha de la cita. El objeto de opciones puede tener varias opciones.

updateAppointment('2022-02-09T09:20:00.000', { month: 6 });
// => { year: 2022, month: 6, date: 9, hour: 10, minute: 20 }

5. Obtén el tiempo disponible entre dos citas

La función recibirá dos citas (marcas de tiempo) como argumentos. Tienes que devolver la diferencia entre esos dos tiempos en segundos.

Como medio segundo casi no significa nada, redondea el número antes de devolverlo.

timeBetween('2022-12-12T09:20:00.000', '2022-12-18T08:30:00.000');
// => 515400

6. Comprueba si una cita es válida o no

Por último, cuando se crea la cita, el sistema necesita comprobar si es válida. En otras palabras, la cita debe estar en el futuro, y no en el pasado.

Escribe la función isValid, que recibe dos argumentos: una marca de tiempo de la cita (string) y la hora actual como marca de tiempo (string), y devuelve true si la cita está en el futuro, dada la hora actual.

isValid('2022-02-11T23:00:00.000', '2022-02-08T23:00:00.000');
// => true
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
JavaScript Exercism

¿Listo para empezar Hora de la cita?

Regístrate en Exercism para aprender y dominar JavaScript con 37 conceptos159 ejercicios y mentoría humana real, todo gratis.