Readme

I track how much time I work in a week in a note. This function takes that unstructured format and calculates how much time I work each day and week.

The input looks like:

Monday 9:55-12:33 lunch 1:30-6:28
Tuesday 9:58-1:35 lunch 2:28-6
Wednesday 9:16-12:57 apple, lunch travel, and break 3:25-6:45

The output looks like:

Weekly Report:
Monday 9:55am-12:33pm 1:30pm-6:28pm 7 hours 36 minutes
Tuesday 9:58am-1:35pm 2:28pm-6pm 7 hours 9 minutes
Wednesday 9:16am-12:57pm 3:25pm-6:45pm 7 hours 1 minutes
I worked 21 hours and 46 minutes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
function parseTimeRanges(daySchedule) {
// console.log(`Parsing schedule: ${daySchedule}`);
const timeRanges = daySchedule.match(/(\d{1,2}(?::\d{2})?(?:am|pm)?)/g);
if (!timeRanges) {
throw new Error("No valid time ranges found:", daySchedule);
}
const parsedSchedule = [];
let currentPeriod = "am";
let lastEndTime24;
for (let i = 0; i < timeRanges.length; i += 2) {
let start = timeRanges[i];
let end = timeRanges[i + 1];
if (!start || !end) {
throw new Error("Invalid time range:", start, end);
}
if (!start.includes(":")) {
start = start.replace(/(am|pm)/i, ":00$1");
}
if (!end.includes(":")) {
end = end.replace(/(am|pm)/i, ":00$1");
}
if (!start.toLowerCase().includes("am") && !start.toLowerCase().includes("pm")) {
start += currentPeriod;
}
if (!end.toLowerCase().includes("am") && !end.toLowerCase().includes("pm")) {
end += currentPeriod;
}
const startTime24 = convertTo24HourFormat(start);
const endTime24 = convertTo24HourFormat(end);
if (parseInt(startTime24.replace(":", "")) < lastEndTime24) {
currentPeriod = currentPeriod === "am" ? "pm" : "am";
start = start.replace(/am|pm/i, currentPeriod);
end = end.replace(/am|pm/i, currentPeriod);
}
lastEndTime24 = parseInt(endTime24.replace(":", ""));
if (endTime24 < startTime24) {
currentPeriod = "pm";
end = end.replace(/am|pm/i, "pm");
}
parsedSchedule.push({ start: start, end: end });
}
// console.log(`Parsed schedule:`, parsedSchedule);
return parsedSchedule;
}
function convertTo24HourFormat(time) {
if (!time) {
throw new Error("Invalid time input: time is undefined or empty");
}
const timeParts = time.split(/(am|pm)/i);
if (timeParts.length < 2) {
throw new Error("Invalid time input: missing AM/PM part", time);
}
const timePart = timeParts[0];
const period = timeParts[1];
if (!period) {
throw new Error("Invalid time input: missing AM/PM part", time);
}
let [hours, minutes] = timePart.trim().split(":").map(Number);
if (isNaN(hours) || (minutes !== undefined && isNaN(minutes))) {
throw new Error("Invalid time input: non-numeric values", time);
}
if (minutes === undefined) minutes = 0; // Handle hour-only times
if (minutes < 0 || minutes >= 60) {
throw new Error("Invalid time input: minutes out of range", time);
}
if (period.toLowerCase() === "pm" && hours !== 12) {
hours += 12;
} else if (period.toLowerCase() === "am" && hours === 12) {
hours = 0;
}
const result = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
// console.log(result);
return result;
}
function calculateDuration(day, startTime, endTime) {
console.log(`calculateDuration: Calculating duration on ${day} from ${startTime} to ${endTime}`);
const start24 = convertTo24HourFormat(startTime);
const end24 = convertTo24HourFormat(endTime);
const [startHours, startMinutes] = start24.split(":").map(Number);
const [endHours, endMinutes] = end24.split(":").map(Number);
const startTotalMinutes = startHours * 60 + startMinutes;
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
September 14, 2024