Skip to content

Instantly share code, notes, and snippets.

@metaquanta
Last active November 26, 2020 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save metaquanta/06326f00fe9a3167c0bc684f4c8db899 to your computer and use it in GitHub Desktop.
Save metaquanta/06326f00fe9a3167c0bc684f4c8db899 to your computer and use it in GitHub Desktop.
#!/bin/env -S deno -q run
import yargs from 'https://deno.land/x/yargs/deno.ts'
function readStdin(): AsyncIterable<string> {
return {
[Symbol.asyncIterator]: async function* () {
const buffer = new Uint8Array(1024);
const decoder = new TextDecoder();
while (true) {
const bytesRead = await Deno.stdin.read(buffer);
if (bytesRead == null) return;
yield decoder.decode(buffer.slice(0, bytesRead));
}
}
}
}
async function scan(search: RegExp, replace: (s: string) => string) {
const encoder = new TextEncoder();
const memo = new Map<string, string>();
const replacement = (a: string[]): string => {
//console.log(a);
const [s, open, date, ...rest] = a;
if (!memo.has(date)) {
memo.set(date, replace(date));
}
return open + memo.get(date) + rest[rest.length - 1];
}
for await (const s of readStdin()) {
let replaced = s;
for (const match of s.matchAll(search)) {
replaced = replaced.replaceAll(match[0], replacement(match))
}
Deno.stdout.write(encoder.encode(replaced));
}
}
const laxStart = /(^|[\s{\[=(:;,'")\]}|])/.source;
const laxStop = /($|[\s{\[=(;'")\]}|])/.source;
const start = /(^|[\s'"])/.source;
const stop = /($|[\s'"])/.source;
// These match epoch times in a 250+ year interval beginning September 9th, 2001.
const microEpoch = /(\d{16})/.source;
const milliEpoch = /(\d{13})/.source;
const epoch = /(\d{10})/.source;
// These cover 2020-11-25T22:14Z or 2020-11-25T22:14:00.000Z or 2020-11-25T22:14:00-05 or 20201126T031400Z etc (ISO8601)
const basicIso = /\d{8}T\d{6}(Z|[+-−]\d\d(|\d\d))/.source;
// The date can by separated by either a hyphen (‐) or a minus-hyphen (-).
const extendedIsoDate = /\d{4}[-‐]\d\d[-‐]\d\d/.source;
// The fractional prefix can begin with either a period (.) or a comma (,).
const extendedIsoTime = /\d\d(|:\d\d(|:\d\d))(|[\.,]\d+)/.source;
// Western hemisphere timezones can begin with either a minus (−) or a minus-hyphen (-).
const extendedIsoZone = /(Z|[+-−]\d\d(|:\d\d))/.source;
const extendedIso = new RegExp(`${extendedIsoDate}T${extendedIsoTime}${extendedIsoZone}`).source;
const iso = new RegExp(`(${basicIso}|${extendedIso})`).source;
const reg = (s: string, argv: { lax: boolean, iso: boolean }) => new RegExp(`${(argv.iso && !argv.lax) ? start : laxStart}${s}${(argv.iso && !argv.lax) ? stop : laxStop}`, "g");
const fromMicroEpoch = (s: string) => new Date(parseInt(s) / 1000);
const fromMilliEpoch = (s: string) => new Date(parseInt(s));
const fromEpoch = (s: string) => new Date(parseInt(s) * 1000);
const fromIso = (s: string) => new Date(Date.parse(s));
const argv = yargs(Deno.args)
.usage('Usage: $0 [--iso] [--micro] [--milli] [--utc] [--lax]')
.options({
iso: { type: 'boolean', default: false },
micro: { type: 'boolean', default: false },
milli: { type: 'boolean', default: false },
utc: { type: 'boolean', default: false },
lax: { type: 'boolean', default: false },
})
.argv;
function getSearch(argv: { iso: boolean, micro: boolean, milli: boolean, utc: boolean }): string {
if (argv.iso) return iso;
if (argv.micro) return microEpoch;
if (argv.milli) return milliEpoch;
return epoch;
}
function getTransform(argv: { iso: boolean, micro: boolean, milli: boolean, utc: boolean }): ((s: string) => Date) {
if (argv.iso) return fromIso;
if (argv.micro) return fromMicroEpoch;
if (argv.milli) return fromMilliEpoch;
return fromEpoch;
}
function getFormatter(argv: { micro: boolean, milli: boolean, utc: boolean }): ((s: Date) => string) {
if (argv.utc) return (date) => date.toUTCString();
return (date) => date.toLocaleString();
}
scan(reg(getSearch(argv), argv), (s) => getFormatter(argv)(getTransform(argv)(s)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment