Use unix timestamps in timetable logic
Parse the iso date strings into millseconds from the unix epoch and use that through the timetable logic instead of reparsing the strings over and over.
This commit is contained in:
parent
c4a6f6b3f9
commit
1ac607a712
1 changed files with 26 additions and 30 deletions
|
@ -75,7 +75,7 @@ const oneMinMs = 60 * 1000;
|
|||
type Edge = { type: "start" | "end", slot: TimeSlot };
|
||||
|
||||
/** Point in time where multiple edges meet. */
|
||||
type Junction = { ts: string, edges: Edge[] };
|
||||
type Junction = { ts: number, edges: Edge[] };
|
||||
|
||||
/** Span of time between two adjacent junctions */
|
||||
type Span = {
|
||||
|
@ -90,8 +90,8 @@ type Span = {
|
|||
and the endpoint spans are always empty and at least one hour.
|
||||
*/
|
||||
type Stretch = {
|
||||
start: string,
|
||||
end: string,
|
||||
start: number,
|
||||
end: number,
|
||||
spans: Span[];
|
||||
}
|
||||
|
||||
|
@ -156,9 +156,9 @@ function* edgesFromEvents(events: Iterable<ScheduleEvent>): Generator<Edge> {
|
|||
}
|
||||
|
||||
function junctionsFromEdges(edges: Iterable<Edge>) {
|
||||
const junctions = new Map<string, Junction>();
|
||||
const junctions = new Map<number, Junction>();
|
||||
for (const edge of edges) {
|
||||
const ts = edge.slot[edge.type];
|
||||
const ts = Date.parse(edge.slot[edge.type]);
|
||||
const junction = junctions.get(ts);
|
||||
if (junction) {
|
||||
junction.edges.push(edge);
|
||||
|
@ -204,14 +204,11 @@ function* spansFromJunctions(
|
|||
}
|
||||
|
||||
function createStretch(spans: Span[]): Stretch {
|
||||
let startTs = Date.parse(spans[0].start.ts) - oneHourMs;
|
||||
let endTs = Date.parse(spans[spans.length - 1].end.ts) + oneHourMs;
|
||||
let start = spans[0].start.ts - oneHourMs;
|
||||
let end = spans[spans.length - 1].end.ts + oneHourMs;
|
||||
// Extend stretch to nearest whole hours
|
||||
startTs = Math.floor(startTs / oneHourMs) * oneHourMs;
|
||||
endTs = Math.ceil(endTs / oneHourMs) * oneHourMs;
|
||||
// Convert back to ISO date string
|
||||
let start = isoStringFromTs(startTs);
|
||||
let end = isoStringFromTs(endTs);
|
||||
start = Math.floor(start / oneHourMs) * oneHourMs;
|
||||
end = Math.ceil(end / oneHourMs) * oneHourMs;
|
||||
return {
|
||||
spans: [
|
||||
{
|
||||
|
@ -237,7 +234,7 @@ function* stretchesFromSpans(spans: Iterable<Span>, minSeparation: number): Gene
|
|||
// Based on how spans are generated I can assume that an empty span
|
||||
// will only occur between two spans with timeslots in them.
|
||||
if (span.locations.size === 0
|
||||
&& Date.parse(span.end.ts) - Date.parse(span.start.ts) >= minSeparation
|
||||
&& span.end.ts - span.start.ts >= minSeparation
|
||||
) {
|
||||
yield createStretch(currentSpans);
|
||||
currentSpans = [];
|
||||
|
@ -251,8 +248,8 @@ function* stretchesFromSpans(spans: Iterable<Span>, minSeparation: number): Gene
|
|||
|
||||
/** Cuts up a span by whole hours that crosses it */
|
||||
function* cutSpansByHours(span: Span): Generator<Span> {
|
||||
const startHour = Date.parse(span.start.ts) / oneHourMs;
|
||||
const endHour = Date.parse(span.end.ts) / oneHourMs;
|
||||
const startHour = span.start.ts / oneHourMs;
|
||||
const endHour = span.end.ts / oneHourMs;
|
||||
let currentStart = startHour;
|
||||
let currentEnd = Math.min(Math.floor(startHour + 1), endHour);
|
||||
if (currentEnd === endHour) {
|
||||
|
@ -262,22 +259,22 @@ function* cutSpansByHours(span: Span): Generator<Span> {
|
|||
|
||||
yield {
|
||||
start: span.start,
|
||||
end: { ts: isoStringFromTs(currentEnd * oneHourMs), edges: [] },
|
||||
end: { ts: currentEnd * oneHourMs, edges: [] },
|
||||
locations: span.locations,
|
||||
}
|
||||
|
||||
currentStart = currentEnd;
|
||||
while (++currentEnd < endHour) {
|
||||
yield {
|
||||
start: { ts: isoStringFromTs(currentStart * oneHourMs), edges: [] },
|
||||
end: { ts: isoStringFromTs(currentEnd * oneHourMs), edges: [] },
|
||||
start: { ts: currentStart * oneHourMs, edges: [] },
|
||||
end: { ts: currentEnd * oneHourMs, edges: [] },
|
||||
locations: span.locations,
|
||||
}
|
||||
currentStart += 1;
|
||||
}
|
||||
|
||||
yield {
|
||||
start: { ts: isoStringFromTs(currentStart * oneHourMs), edges: [] },
|
||||
start: { ts: currentStart * oneHourMs, edges: [] },
|
||||
end: span.end,
|
||||
locations: span.locations,
|
||||
}
|
||||
|
@ -322,14 +319,14 @@ function tableElementsFromStretches(
|
|||
if (first) {
|
||||
first = false;
|
||||
startColumnGroup();
|
||||
startDay(stretch.start.slice(0, 10));
|
||||
startHour(stretch.start.slice(11, 16));
|
||||
startDay(isoStringFromTs(stretch.start).slice(0, 10));
|
||||
startHour(isoStringFromTs(stretch.start).slice(11, 16));
|
||||
for(const location of locations) {
|
||||
startLocation(location.id);
|
||||
}
|
||||
} else {
|
||||
startColumnGroup("break");
|
||||
const dayName = stretch.start.slice(0, 10)
|
||||
const dayName = isoStringFromTs(stretch.start).slice(0, 10)
|
||||
const lastDayHeader = dayHeaders[dayHeaders.length - 1]
|
||||
const sameDay = dayName === lastDayHeader.content && lastDayHeader.span;
|
||||
if (!sameDay)
|
||||
|
@ -343,7 +340,7 @@ function tableElementsFromStretches(
|
|||
startColumnGroup();
|
||||
if (!sameDay)
|
||||
startDay(dayName);
|
||||
startHour(stretch.start.slice(11, 16));
|
||||
startHour(isoStringFromTs(stretch.start).slice(11, 16));
|
||||
for(const location of locations) {
|
||||
startLocation(location.id);
|
||||
}
|
||||
|
@ -351,9 +348,8 @@ function tableElementsFromStretches(
|
|||
|
||||
for (const span of stretch.spans) {
|
||||
for (const cutSpan of cutSpansByHours(span)) {
|
||||
const startTs = Date.parse(cutSpan.start.ts);
|
||||
const endTs = Date.parse(cutSpan.end.ts);
|
||||
const durationMs = endTs - startTs;
|
||||
const end = cutSpan.end.ts;
|
||||
const durationMs = end - cutSpan.start.ts;
|
||||
|
||||
for (const location of locations) {
|
||||
const rows = locationRows.get(location.id)!;
|
||||
|
@ -365,11 +361,11 @@ function tableElementsFromStretches(
|
|||
}
|
||||
|
||||
pushColumn(durationMs / oneMinMs);
|
||||
if (endTs % oneDayMs === 0) {
|
||||
startDay(cutSpan.end.ts.slice(0, 10));
|
||||
if (end % oneDayMs === 0) {
|
||||
startDay(isoStringFromTs(cutSpan.end.ts).slice(0, 10));
|
||||
}
|
||||
if (endTs % oneHourMs === 0) {
|
||||
startHour(cutSpan.end.ts.slice(11, 16));
|
||||
if (end % oneHourMs === 0) {
|
||||
startHour(isoStringFromTs(cutSpan.end.ts).slice(11, 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue