I want a TypeScript function that checks if an ISO 8601 datetime string is in UTC. So the output should be:
isUTC('2020-01-01T00:00:00Z') // true
isUTC('2020-01-01T00:00:00 00') // true
isUTC('2020-01-01T00:00:00 0000) // true
isUTC('2020-01-01T00:00:00 00:00') // true
isUTC('2020-01-01T00:00:00 01) // false
isUTC('2020-01-01T00:00:00 0100) // false
isUTC('2020-01-01T00:00:00 01:00') // false
If possible I would like to avoid regular expressions and use an existing parser or decomposer instead. Ideally there would be a library that decomposes ISO 8601 strings, so that I can check Iso8601Decomposer(value).timezoneOffset === 0
. Does something like this exist in TypeScript/JavaScript?
I found some answers that were checking if value === new Date(Date.parse(value)).toISOString()
, but this does not work for lines 2 and 3 above.
CodePudding user response:
You can use the luxon
library to parse ISO date strings.
One can then get the UTC offset in minutes, if this is 0 we're in UTC (or GMT)
I've wrapped this all up in the required isUTC()
function.
let { DateTime } = luxon;
let inputs = [
'2020-01-01T00:00:00Z',
'2020-01-01T00:00:00 00',
'2020-01-01T00:00:00 0000',
'2020-01-01T00:00:00 00:00',
'2020-01-01T00:00:00 01',
'2020-01-01T00:00:00 0100',
'2020-01-01T00:00:00 01:00'
];
function isUTC(input) {
const dt = DateTime.fromISO(input, { setZone: true })
return dt.offset === 0;
}
console.log('Input'.padEnd(30), 'isUTC');
for(let input of inputs) {
console.log(input.padEnd(30), isUTC(input));
}
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.3.1/luxon.min.js" integrity="sha512-Nw0Abk Ywwk5FzYTxtB70/xJRiCI0S2ORbXI3VBlFpKJ44LM6cW2WxIIolyKEOxOuMI90GIfXdlZRJepu7cczA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
You can do this with RegEx too:
let inputs = [
'2020-01-01T00:00:00Z',
'2020-01-01T00:00:00 00',
'2020-01-01T00:00:00 0000',
'2020-01-01T00:00:00 00:00',
'2020-01-01T00:00:00 01',
'2020-01-01T00:00:00 0100',
'2020-01-01T00:00:00 01:00'
];
function isUTC(input) {
return getUTCOffsetMinutes(input) === 0;
}
function getUTCOffsetMinutes(isoDate) {
// The pattern will be ±[hh]:[mm], ±[hh][mm], or ±[hh], or 'Z'
const offsetPattern = /([ -]\d{2}|Z):?(\d{2})?\s*$/;
if (!offsetPattern.test(isoDate)) {
throw new Error("Cannot parse UTC offset.")
}
const result = offsetPattern.exec(isoDate);
return ( result[1] || 0) * 60 ( result[2] || 0);
}
console.log('Input'.padEnd(30), 'isUTC');
for(let input of inputs) {
console.log(input.padEnd(30), isUTC(input));
}
.as-console-wrapper { max-height: 100% !important; }