Tracks
/
JavaScript
JavaScript
/
Exercises
/
Appointment Time
Appointment Time

Appointment Time

Learning Exercise

Introduction

JavaScript has a built-in object Date which stores date and time, and provides methods for their management.

Caution

It was based on Java's java.util.Date class, which was replaced in the early 2010s, but for backwards compatibility, JavaScript's Date sticks around.

Because of how hard it is to work with Dates in general and because of how bad or non-existing timezone handling is, many libraries exist such as moment.js, day.js, date-fns and luxon. None of these are available on Exercism.

In your own projects, do not use a deprecated / unmaintained package such as moment.js but rely on more modern alternatives like luxon, or the not yet widely available Temporal. This exercise focusses on Date, which will remain relevant until the end of JavaScript.

Creation

A Date object is an instance of the Date class. It can be created without passing any arguments to the constructor function. This results in a Date object that represents the current date and time:

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).

Unix timestamp (number)

If a number is passed in, this will be interpreted as a timestamp. A timestamp is an integer number representing the number of milliseconds that has passed since 1 January 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)

One may expect new Date(0) to generate the "earliest" date object, but JavaScript will convert the date to your local timezone, which means that only those around GMT / with an UTC+0 timezone will actually get the Unix epoch value.

ISO 8601 timestamp (string)

You can pass a string value representing a date to the Date constructor. The only format that is consistent across implementations is the simplified version of the internationally recognized and standardized so-called ISO 8601 timestamp strings.

A moment in time at UTC looks like this:

YYYY-MM-DDTHH:MM:SSZ
YYYYMMDDTHHMMSSZ

Where the following substitutions take place:

Key Description
YYYY The calendar year, represented in 4 digits
MM The calendar month, represented in 2 digits
DD The calendar day, represented in 2 digits
HH The hours in a 24-hour clock, 2 digits
MM The minutes, 2 digits
SS The seconds, 2 digits

The letter T separates the date from the time. The letter Z indicates UTC (no timezone, no Day Light Savings).

Caution

Other formats that are accepted by Date.parse may or may not work. When working with Dates in JavaScript, always use an ISO 8601 timestamp when converting from a string to a Date.

Date-only forms are allowed, but not all ISO 8601 formats are supported. Consult the simplified version explanation page on MDN.

If the timestamp does not end in Z, and it does not end with +HH:MM or -HH:MM, indicating a timezone offset, because of historical reasons, the following applies:

When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time. The interpretation as a UTC time is due to a historical spec error that was not consistent with ISO 8601 but could not be changed due to web compatibility. See Broken Parser – A Web Reality Issue.

Date object

An existing date object can also be used as a constructor argument. This makes a copy of the existing Date object with the same date and time.

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

Supplying individual date and time component values

A date representing a date can be created by passing three numbers. A date representing a date and time can be created by passing in 6 numbers.

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.

The second value is the month, which starts at 0 for January, up to 11 for December.

Date.parse()

You may find mentions of or references to a date parsing function Date.parse. Because there are only a few invariants (truths) for this function and because the rest of the implementation is not specified (and thus not standard), one should not use it.

Accessing Date components

There are various methods on date objects that return the components of the date:

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).

Each of these has an applicable set variant (e.g. setFullYear) to update the value. Any overflowing value rolls over to the next component:

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)

There are UTC variants for all the methods that disregard the local timezone.

Converting from date

Date objects have a method getTime() that returns the UNIX timestamp in milliseconds, ie. amount of milliseconds the midnight at the beginning of January 1, 1970, UTC. Additionally, a method toISOString() is available to convert from a date object to a ISO 8601 timestamp string.

Comparing Dates

Greater than (>) and greater than or equals (>=) as well as less than (<) and less than or equals (<=) can be used directly between two dates or a date and a number. This works because JavaScript will try to coerce the date to a primitive.

Advanced

When doing a comparison between two dates or date and a number, JavaScript calls [Symbol.toPrimitive]("number") which internally calls date.valueOf(). The latter is the same as calling date.getTime().

If you do not want to rely on this behaviour, convert to a number using getTime() first.

Dates cannot be compared using equality (==, and ===), but the result of .getTime() can.

Instructions

In this exercise you will work on some functions in order to manage appointments. The system stores everything in ISO 8601 formatted strings, but that's not how people use the calendar. Various functions are necessary to convert between the various formats.

1. Create an appointment

Create an appointment n days from now at current time. The function takes n days and return the appointment time of n days from now.

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)

If the second parameter now is unused, the current time should be used instead.

2. Convert a date into a timestamp

Various tools only work with the internationally standardized ISO 8601 format. Write the function getAppointmentTimestamp to take a date and return a string in that format.

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

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

3. Get the details of an appointment

Timestamps are hard to read; a function to get the appointment details should help with that. The function getAppointmentDetails takes a timestamp in the ISO 8601 format, and returns the year, month, date, hour, and minute.

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

4. Update an appointment with the given options

The function will receive first argument as appointment time and second argument of object of some options. You have to update the appointment according to the options in the object and return the new appointment date. The options object could have multiple options.

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

5. Get the available time between two appointments

The function will receive two appointments (timestamps) as arguments. You have to return the difference between those two times in seconds.

Because half a second is almost meaningless, round the number before returning it.

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

6. Check if an appointment is now valid or not

Finally, when the appointment is made, the system needs to check if it's valid. In other words, the appointment must be in the future, and not the past.

Write the function isValid which takes two arguments, an appointment timestamp (string), and the current time as a timestamp (string) and returns true if the appointment is in the future, given the current time.

isValid('2022-02-11T23:00:00.000', '2022-02-08T23:00:00.000');
// => true
Edit via GitHub The link opens in a new window or tab
JavaScript Exercism

Ready to start Appointment Time?

Sign up to Exercism to learn and master JavaScript with 35 concepts, 152 exercises, and real human mentoring, all for free.