0

I have total 4 different input i.e.:

  1. Date string (2020-05-05)
  2. Time string (15:30)
  3. Timezone offset (-09:00)

I want to combine these strings into one datetime object like (2020-05-05T15:30:00-09:00) no-matter what my local browser timezone is. The issue is when I combine these strings and I try to make date object using new Date() function, my datetime gets converted into UTC timestamp.

I tried this:

const date =
  moment(this.actualDateOfSurgeryDate).format(YYYYMMDD) +
  'T' +
  moment(this.actualDateOfSurgeryTimeDropDown + ' ' + this.actualDateOfSurgeryTimeAM_PMDropDown, ['h:mm A']).format('HH:mm:ss') +
  offsetTime;

this.caseDetail.actualDateOfSurgery = new Date(date);

This gives me output something like: 2020-05-05T04:30:00.000Z

How can I get my desired output: 2020-05-05T15:30:00-09:00 ?? I have moment js available in my project

Faizan Saiyed
  • 453
  • 7
  • 22

2 Answers2

1

I get 16:30 due to DST

A date before March or after October will give 15:30

let dateString = "2020-05-05"+"T"+"15:30"+":00"+"-09:00"
console.log(dateString)
const date = new Date(dateString)
console.log(date)
const Anchorage = date.toLocaleString('en-US', {timeZone: 'America/Anchorage', hour12: false})
console.log(Anchorage)

let options = {}
options.timeZone = 'America/Anchorage';
options.timeZoneName = 'short';
console.log(date.toLocaleDateString('en-US'), date.toLocaleTimeString('en-US', options));
mplungjan
  • 134,906
  • 25
  • 152
  • 209
1

I want to combine these strings into one datetime object like (2020-05-05T15:30:00-09:00)

Date objects are extremely simple, they're just a time value that is an offset in milliseconds since 1970-01-01T00:00:00Z, so are inherently UTC. The built–in parser is unreliable and lacks any functionality such as format tokens.

So if you have separate values like:

  • Date string (2020-05-05)
  • Time string (15:30)
  • Timezone offset (-09:00)

then you can create a string that is compliant with the format defined in ECMA-262 and that should be parsed correctly by the built–in parser, e.g.

new Date('2020-05-05T15:30:00.000-09:00')

However, general advice is to avoid the built–in parser due to differences in implementations. Also, the format must be exact (e.g. including seconds and milliseconds in the timestamp, colon (:) in the offset) or some implementations will reject it as malformed and return an invalid date.

Once you have a Date object, getting a "local" timestamp with offset is an issue of formatting, which has been answered many times before (e.g. How to format a JavaScript date). There aren't any decent built–in formatting functions (toLocaleString with options is OK for some purposes but generally lacking in functionality), so you'll have to either write your own function, or use a library.

The following examples use Luxon, which is suggested as the upgrade path from moment.js.

With Luxon, if you specify a representative location, you'll get the offset for that location at the date's date and time. Alternatively, you can fix the offset to a set value, essentially setting it for a timezone without a representative location, so it doesn't have any reference to daylight saving or historic offset changes:

let DateTime = luxon.DateTime;

// Offset per the specified location
let d0 = DateTime.fromISO('2020-01-01', {zone: 'America/Yakutat'});
let d1 = DateTime.fromISO('2020-06-30', {zone: 'America/Yakutat'});
console.log(d0.toString());
console.log(d1.toString());

// Fixed offset per the supplied string
let d2 = DateTime.fromISO('2020-05-05T15:30:00.000-09:00', { setZone: true});
let d3 = DateTime.fromISO('2020-01-01T15:30:00.000-09:00', { setZone: true});
console.log(d2.toString());
console.log(d3.toString());
  
<script src="https://cdn.jsdelivr.net/npm/luxon@1.24.1/build/global/luxon.min.js"></script>
RobG
  • 124,520
  • 28
  • 153
  • 188