use tinyduration for ISO8601 parsing and serializing

This commit is contained in:
Elijah Duffy
2025-12-11 20:40:27 -08:00
parent 837029b598
commit ae3abad769
3 changed files with 17 additions and 21 deletions

View File

@@ -40,12 +40,12 @@
}, },
"peerDependencies": { "peerDependencies": {
"@sveltejs/kit": "^2.20.2", "@sveltejs/kit": "^2.20.2",
"svelte": "^5.0.0",
"tailwindcss": "^4.1.11",
"tailwindcss-animate": "^1.0.7",
"@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/forms": "^0.5.10", "@tailwindcss/forms": "^0.5.10",
"@tailwindcss/vite": "^4.1.11" "@tailwindcss/vite": "^4.1.11",
"svelte": "^5.0.0",
"tailwindcss": "^4.1.11",
"tailwindcss-animate": "^1.0.7"
}, },
"dependencies": { "dependencies": {
"@internationalized/date": "^3.8.2", "@internationalized/date": "^3.8.2",
@@ -56,7 +56,8 @@
"match-sorter": "^8.0.0", "match-sorter": "^8.0.0",
"melt": "^0.37.0", "melt": "^0.37.0",
"moment": "^2.30.1", "moment": "^2.30.1",
"phosphor-svelte": "^3.0.1" "phosphor-svelte": "^3.0.1",
"tinyduration": "^3.4.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.2.5", "@eslint/compat": "^1.2.5",

8
pnpm-lock.yaml generated
View File

@@ -59,6 +59,9 @@ importers:
tailwindcss-animate: tailwindcss-animate:
specifier: ^1.0.7 specifier: ^1.0.7
version: 1.0.7(tailwindcss@4.1.11) version: 1.0.7(tailwindcss@4.1.11)
tinyduration:
specifier: ^3.4.1
version: 3.4.1
devDependencies: devDependencies:
'@eslint/compat': '@eslint/compat':
specifier: ^1.2.5 specifier: ^1.2.5
@@ -1539,6 +1542,9 @@ packages:
resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==}
engines: {node: '>=18'} engines: {node: '>=18'}
tinyduration@3.4.1:
resolution: {integrity: sha512-NemFoamVYn7TmtwZKZ3OiliM9fZkr6EWiTM+wKknco6POSy2gS689xx/pXip0JYp40HXpUw6k65CUYHWYUXdaA==}
tinyglobby@0.2.14: tinyglobby@0.2.14:
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
@@ -2917,6 +2923,8 @@ snapshots:
mkdirp: 3.0.1 mkdirp: 3.0.1
yallist: 5.0.0 yallist: 5.0.0
tinyduration@3.4.1: {}
tinyglobby@0.2.14: tinyglobby@0.2.14:
dependencies: dependencies:
fdir: 6.4.6(picomatch@4.0.3) fdir: 6.4.6(picomatch@4.0.3)

View File

@@ -26,12 +26,7 @@
* @returns The ISO 8601 duration string. * @returns The ISO 8601 duration string.
*/ */
export const durationToISO8601 = (duration: TimeDuration): string => { export const durationToISO8601 = (duration: TimeDuration): string => {
let str = 'P'; return serialize(duration);
if (duration.hours || duration.minutes || duration.seconds) str += 'T';
if (duration.hours) str += `${duration.hours}H`;
if (duration.minutes) str += `${duration.minutes}M`;
if (duration.seconds) str += `${duration.seconds}S`;
return str;
}; };
/** /**
@@ -40,16 +35,7 @@
* @returns The TimeDuration object. * @returns The TimeDuration object.
*/ */
export const iso8601ToDuration = (str: string): TimeDuration => { export const iso8601ToDuration = (str: string): TimeDuration => {
const regex = /^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/; return parse(str);
const matches = str.match(regex);
if (!matches) {
throw new Error('Invalid ISO 8601 duration string');
}
return {
hours: matches[2] ? parseInt(matches[2], 10) : 0,
minutes: matches[3] ? parseInt(matches[3], 10) : 0,
seconds: matches[4] ? parseInt(matches[4], 10) : 0
};
}; };
</script> </script>
@@ -62,6 +48,7 @@
import Label from './Label.svelte'; import Label from './Label.svelte';
import { liveValidator, validate } from '@svelte-toolkit/validate'; import { liveValidator, validate } from '@svelte-toolkit/validate';
import StyledRawInput from './StyledRawInput.svelte'; import StyledRawInput from './StyledRawInput.svelte';
import { parse, serialize } from 'tinyduration';
interface Props { interface Props {
/** /**