Skip to content

Commit f41feca

Browse files
committed
removed not retired functions and added enhanced parse date function
1 parent bb5cfd6 commit f41feca

File tree

2 files changed

+77
-7
lines changed

2 files changed

+77
-7
lines changed

src/eval/common.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,75 @@ export function sliceBlock(instuctionLines: CodeLine[], start: number): CodeLine
5252
.findIndex((cl, i) => i > start && getLineIndent(cl.line) < blockLineIndent)
5353

5454
return instuctionLines.slice(start, blockEndIndex > 0 ? blockEndIndex : undefined)
55-
}
55+
}
56+
57+
export function parseDatetimeOrNull(value: string | Date): Date | null {
58+
if (!value) { return null; }
59+
if (value instanceof Date && !isNaN(value.valueOf())) { return value; }
60+
// only string values can be converted to Date
61+
if (typeof value !== 'string') { return null; }
62+
63+
const strValue = String(value);
64+
if (!strValue.length) { return null; }
65+
66+
const parseMonth = (mm: string): number => {
67+
if (!mm || !mm.length) {
68+
return NaN;
69+
}
70+
71+
const m = parseInt(mm, 10);
72+
if (!isNaN(m)) {
73+
return m - 1;
74+
}
75+
76+
// make sure english months are coming through
77+
if (mm.startsWith('jan')) { return 0; }
78+
if (mm.startsWith('feb')) { return 1; }
79+
if (mm.startsWith('mar')) { return 2; }
80+
if (mm.startsWith('apr')) { return 3; }
81+
if (mm.startsWith('may')) { return 4; }
82+
if (mm.startsWith('jun')) { return 5; }
83+
if (mm.startsWith('jul')) { return 6; }
84+
if (mm.startsWith('aug')) { return 7; }
85+
if (mm.startsWith('sep')) { return 8; }
86+
if (mm.startsWith('oct')) { return 9; }
87+
if (mm.startsWith('nov')) { return 10; }
88+
if (mm.startsWith('dec')) { return 11; }
89+
90+
return NaN;
91+
};
92+
93+
const correctYear = (yy: number) => {
94+
if (yy < 100) {
95+
return yy < 68 ? yy + 2000 : yy + 1900;
96+
} else {
97+
return yy;
98+
}
99+
};
100+
101+
const validDateOrNull =
102+
(yyyy: number, month: number, day: number, hours: number, mins: number, ss: number): Date | null => {
103+
if (month > 11 || day > 31 || hours >= 60 || mins >= 60 || ss >= 60) { return null; }
104+
105+
const dd = new Date(yyyy, month, day, hours, mins, ss, 0);
106+
return !isNaN(dd.valueOf()) ? dd : null;
107+
};
108+
109+
const strTokens = strValue.replace('T', ' ').toLowerCase().split(/[: /-]/);
110+
const dt = strTokens.map(parseFloat);
111+
112+
// try ISO first
113+
let d = validDateOrNull(dt[0], dt[1] - 1, dt[2], dt[3] || 0, dt[4] || 0, dt[5] || 0);
114+
if (d) { return d; }
115+
116+
// then UK
117+
d = validDateOrNull(correctYear(dt[2]), parseMonth(strTokens[1]), dt[0], dt[3] || 0, dt[4] || 0, dt[5] || 0);
118+
if (d) { return d; }
119+
120+
// then US
121+
d = validDateOrNull(correctYear(dt[2]), parseMonth(strTokens[0]), correctYear(dt[1]), dt[3] || 0, dt[4] || 0, dt[5] || 0);
122+
if (d) { return d; }
123+
124+
return null;
125+
}
126+

src/interpreter.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Tokenizer, CodeLine, PackageToImport } from './tokenizer';
22
import {
33
BlockContext, AnyFunc,
4-
EvalCodeBlock, EvalInstruction, EvalExpression, getLineIndent, sliceBlock
4+
EvalCodeBlock, EvalInstruction, EvalExpression, getLineIndent, sliceBlock, parseDatetimeOrNull
55
} from './eval/index';
66

77
export { PackageToImport } from './tokenizer';
@@ -18,17 +18,16 @@ function range(start: number, stop: number = NaN, step: number = 1): number[] {
1818
}
1919
return arr;
2020
}
21-
// methods like: AND, OR are temporary until we have () support
22-
// setPropertValue, getPropertValue should be replaced with native way e.g. obj[name] = 22
21+
2322
const INITIAL_SCOPE = {
24-
dateTime: (d: number | string | any = null) => d ? new Date(d) : new Date(),
23+
dateTime: (str: number | string | any = null) => (str && str.length)
24+
? parseDatetimeOrNull(str) || new Date() : new Date(),
2525
range: range,
2626
print: (...args: any[]) => { console.log(...args); return args.length > 0 ? args[0] : null; },
2727
isNull: (v: any, defValue: any = null): boolean | any => defValue === null ? v === null : v || defValue,
28+
2829
AND: (...args: boolean[]): boolean => !(args || []).filter(r => !r).length,
2930
OR: (...args: boolean[]): boolean => !!(args || []).filter(r => r).length,
30-
setPropertValue: (obj: any, propName: string, value: any | null) => obj[propName] = value,
31-
getPropertValue: (obj: any, propName: string): any | null => obj[propName],
3231
deleteProperty: (obj: any, propName: string): boolean => delete obj[propName],
3332
Math: Math,
3433
Object: Object,

0 commit comments

Comments
 (0)