Formatting dates and times without a library in JavaScript
Tags: javascript, webdev, beginners, tutorial
Published: 2022-11-21 13:41:27

Dates and times can be tricky in JavaScript. You always want to be sure you are doing it correctly. Luckily, because JavaScript has a built-in Date object, it makes working with dates and times much easier. In fact, there are many different methods on the Date object that can be used to do different things with dates. In this blog, I'll run through a few of these methods.

## A quick note on the `Date` object

The built-in `Date` object in JavaScript offers us a set of APIs for working with date and time data. A `Date` object instance represents a single point in time. The instance is in a platform-independent format.

## Creating an instance

### Current Date / Time

There are multiple ways you can get an instance (or representation) of the current date and time.

#### Using the constructor

```jsx
let now;

now = new Date();
console.log(now); // [object Date] { ... }
```

#### Using the `Date()` function

This returns a string representation of the current date and time

```jsx
now = Date();
console.log(now);
// "Mon Nov 21 2022 10:39:45 GMT+0200 (South Africa Standard Time)"
```

#### Using a static method, `.now()`

This returns a `number` that represents the milliseconds elasped since 1 January 1970 UTC

```jsx
now = Date.now();
console.log(now);
// 1669019985182
```

### Other ways to create an instance

#### Parsing strings

With the `new Date()` constructor (or `Date.parse()` ). Strings must be compliant with the ISO 8601 format, `YYYY-MM-DDTHH:mm:ss.sssZ`.

```jsx
const nextBirthday= new Date('2023-08-02T00:00:00')
```

The example below is discouraged and may not work in all runtimes/browsers. A library like `moment` or `dayjs` can help if other string formats are needed.

```jsx
const nextBirthday = new Date('August 02, 2023 00:00:00');
// DISCOURAGED: may not work in all runtimes
```

#### Passing integers in the constructor

This syntax is `new Date(year, month, day, hours, minutes, seconds, milliseconds);`

This `month` is 0-indexed, meaning `0` is January and `11` is December

```jsx
nextBirthday = new Date(2023, 7, 2, 0, 0, 0);
console.log(nextBirthday .toString());
// "Wed Aug 02 2023 00:00:00 GMT+0200 (South Africa Standard Time)"
```

#### Epoch (Unix) Timestamp

Epoch timestamp is the number of seconds elapsed since January 1, 1970 (midnight UTC/GMT)

Sytanx `new Date(milliseconds)`

```jsx
nextBirthday = new Date(1690927200000)
```

Get Epoch in seconds

```jsx
const seconds = Math.floor(Date.now() / 1000);
```

## Date methods

We can also manage and manipulate dates and times using the methods provided by the `Date` object.

### Accessing Date components

Get the year (4 digits, e.g., 2022)

```jsx
nextBirthday.getFullYear()
// 2023
```

Get the month. The month is zero-indexed (i.e., 0 - 11).

```jsx
nextBirthday.getMonth()
// 7
```

Get the day of the month, from 1 to 31.

```jsx
nextBirthday.getDate()
// 2
```

Get the day of the week. This is also zero-index (i.e., from 0 to 6). The first day is always Sunday, `0` and last day is Saturday, `6`. (Not so in some countries but can’t be changed).

```jsx
nextBirthday.getDay();
// 2
```

The methods, `getHours()`, `getMinutes()`, `getSeconds()` , `getMilliseconds()` get the corresponding time components.

All the methods above return the components relative to your local time zone. UTC-counterparts are available for each method which return values relative to UTC. Simply insert `UTC` right after `get` in the method name.

```jsx
// Local time is UTC +2
nextBirthday.getHours(); // 0
nextBirthday.getUTCHours(); // 22
```

Destructuring assignment example

```jsx
const date = new Date();
const [month, day, year] = [date.getMonth(), date.getDate(), date.getFullYear()];
const [hour, minutes, seconds] = [date.getHours(), date.getMinutes(), date.getSeconds()];
```

### Setting Date Components

The following methods allow to set date/time components

- `setFullYear(year, [month], [date])`
- `setMonth(month, [date])`
- `setDate(date)`
- `setHours(hour, [min], [sec], [ms])`
- `setMinutes(min, [sec], [ms])`
- `setSeconds(sec, [ms])`
- `setMilliseconds(ms)`
- `setTime(milliseconds)` (sets the whole date by milliseconds since 01.01.1970 UTC)

```jsx
let now = new Date();
now.setHours(12);
now.setFullYear(2015);
console.log(now.toString());
// "Sat Nov 21 2015 12:08:53 GMT+0200 (South Africa Standard Time)"
```

Every one of them except `setTime()` has a UTC-variant

```jsx
let now = new Date();
now.setUTCHours(2);
```

Some methods can set multiple components at once. For example, `setHours()` gives you the option to set `minutes`, `seconds` and `milliseconds` as well. These options are not modified if not included in the method call.

```jsx
let today = new Date();

today.setHours(12);
console.log(now.toString());
// "Mon Nov 21 2022 12:13:36 GMT+0200 (South Africa Standard Time)"

now.setHours(12, 12, 12, 12);
console.log(now.toString());
// "Mon Nov 21 2022 12:12:12 GMT+0200 (South Africa Standard Time)"
```

## Formatting

Variations of the `toString()` method. Returns various string representation of a `Date` instance.

```jsx
let now = new Date();

now.toString();
// "Mon Nov 21 2022 14:17:21 GMT+0200 (South Africa Standard Time)"

now.toDateString();
// "Mon Nov 21 2022"

now.toTimeString();
// "14:17:21 GMT+0200 (South Africa Standard Time)"

now.toISOString();
// "2022-11-21T12:17:21.595Z"

now.toUTCString();
// "Mon, 21 Nov 2022 12:17:21 GMT"

now.toLocaleString();
// "11/21/2022, 2:17:21 PM"

now.toLocaleDateString();
// "11/21/2022"

now.toLocaleTimeString();
// "2:17:21 PM"

now.toJSON();
// "2022-11-21T12:17:21.595Z"
```

### The `Intl.DateTimeFormat` object

On modern browsers and runtimes, JavaScript includes an Internationalization API that allows for language-sensitive date and time formatting. You can start using it right away without having to import a massive date formatting library.

```jsx
const now = new Date();

const formatted1 = Intl.DateTimeFormat('en-ZM').format(now);
const formatted2 = Intl.DateTimeFormat('en-ZM', { dateStyle: "full" }).format(now);
const formatted3 = Intl.DateTimeFormat('en-ZM', { dateStyle: "long" }).format(now);
const formatted4 = Intl.DateTimeFormat('en-ZM', { dateStyle: "medium" }).format(now);
const formatted5 = Intl.DateTimeFormat('en-ZM', { dateStyle: "short" }).format(now);

console.log(now); // [object Date] ...
console.log(formatted1); // "21/11/2022"
console.log(formatted2); // "Monday, November 21, 2022"
console.log(formatted3); // "21 November 2022"
console.log(formatted4); // "21 Nov 2022"
console.log(formatted5); // "21/11/2022"
```

## Conclusion

In today's blog post, we learned how to format date/time data in JavaScript. There are many libraries that handle this for us already, but if you're working in a legacy codebase or have performance reasons for wanting to avoid a library, you may have to handle date/time formatting natively.

Learn more about the Date object on [MDN references docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)