File size: 1,155 Bytes
d9494a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { isValid, parse } from 'date-fns';
import { Temporal } from 'temporal-polyfill';

import { NON_ISO_DATE_FORMATS } from '@/utils/date/dateInputFormats';
import { turnJSDateToPlainDate } from '@/utils/date/turnJSDateToPlainDate';
import { isDefined } from '@/utils/validation';

const getIsoInstant = (stringDateTime: string): Temporal.Instant | null => {
  try {
    return Temporal.Instant.from(stringDateTime);
  } catch {
    try {
      return Temporal.PlainDateTime.from(stringDateTime)
        .toZonedDateTime('UTC')
        .toInstant();
    } catch {
      return null;
    }
  }
};

export const parseToInstantOrThrow = (
  stringDateTime: string,
): Temporal.Instant => {
  const isoInstant = getIsoInstant(stringDateTime);

  if (isDefined(isoInstant)) {
    return isoInstant;
  }

  for (const format of NON_ISO_DATE_FORMATS) {
    const parsedDate = parse(stringDateTime, format, new Date());

    if (isValid(parsedDate)) {
      return turnJSDateToPlainDate(parsedDate)
        .toZonedDateTime('UTC')
        .toInstant();
    }
  }

  throw new Error(
    `Cannot parse date-time string as Instant: "${stringDateTime}"`,
  );
};