How to create new Date() in the format of "2023-12-14T15:11:12-05:00"?

317 Views Asked by At

Original code

const start = new Date();

console.log(start);

Result

2023-12-14T20:11:12.388Z

My time zone is America/New_York, 5 hours behind UTC.

Question

How should I convert a new Date object in the format of?

2023-12-14T15:11:12-05:00

I've been trying things like this but no luck yet,

const start = new Date();

const dateFormat = new Intl.DateTimeFormat("en-US", {
  timeZone: "America/New_York",
  dateStyle: "short",
  timeStyle: "long"
});

console.log(dateFormat.format(start));

Either native JS, or date-fns is fine.

3

There are 3 best solutions below

3
user3552178 On

Seems formatISO from date-fns works:

import formatISO from 'date-fns/formatISO';

const start = new Date();
console.log(formatISO(start));

The output of last run is

2023-12-14T16:43:15-05:00
0
Mr. Polywhirl On

You don't really need to use a library for this.

You can achieve this simply by:

  • Grabbing the ISO string
  • Removing some bits (milliseconds and Zulu) off the end
  • Appending the offset formatted (formatted in HH:MM)

const now = new Date();

// YYYY-MM-DD'T'HH:mm:ss'[+-]'HH:MM
console.log(formatLocalDateInIsoWithTimeZone(now));

function formatLocalDateInIsoWithTimeZone(date) {
  const
    offsetMillis = date.getTimezoneOffset() * 6e4,
    offsetDate = new Date(date.getTime() - offsetMillis),
    localDateString = offsetDate.toISOString().replace(/(\.\d{3})?Z$/, '');
  return localDateString + formatOffset(date);
}

function formatOffset(date) {
  const
    offsetInMinutes = date.getTimezoneOffset(),
    sign = offsetInMinutes > 0 ? '-' : '+',
    offset = Math.abs(offsetInMinutes),
    hours = Math.floor(offset / 60).toString().padStart(2, '0'),
    minutes = (offset % 60).toString().padStart(2, '0');
  return `${sign}${hours}:${minutes}`;
}

If you want to do this withe built-in l10n/l16n library, you can use the Swedish locale; as others have suggested.

const now = new Date();

const localDateWithTimeZoneFormatter = new Intl.DateTimeFormat('sv-SE', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour12: false,
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
  timeZoneName: 'longOffset'
});

// YYYY-MM-DD'T'HH:mm:ss'[+-]'HH:MM
console.log(formatLocalDateInIsoWithTimeZone(now));

function formatLocalDateInIsoWithTimeZone(date) {
  return localDateWithTimeZoneFormatter
    .format(date)
    .replace('−', '-')   // time-zone divider
    .replace(' ', 'T')   // date-time divider
    .replace(' GMT', '') // Not needed
}

Either way, this is not going to be done in just a few lines of code or the use of a 3rd party library.

4
2hihuang On

You can just use toLocaleString() along with some options. There is a trick here as the locale 'sv-SE' (Swedish - Sweden) is used. This is a way to get a more ISO-like date format (YYYY-MM-DD) as it's the default date format for this locale.

const date = new Date();
const options = {
  timeZone: "America/New_York",
  year: 'numeric', 
  month: '2-digit', 
  day: '2-digit', 
  hour: '2-digit', 
  minute: '2-digit', 
  second: '2-digit', 
  timeZoneName: 'longOffset'
};
const dateString = date.toLocaleString('sv-SE', options).replace(' ', 'T').replace(' GMT', '');
console.log(dateString);