Fix multiple issues in calculation and structure code better

This commit is contained in:
Marko Korhonen 2023-11-11 16:50:08 +02:00
parent 92e756977d
commit 5726f76b3a
Signed by: FunctionalHacker
GPG key ID: A7F78BCB859CD890
2 changed files with 39 additions and 34 deletions

View file

@ -2,7 +2,7 @@ build: node_modules bin
bin: tsc target/workTimeCalculator bin: tsc target/workTimeCalculator
tsc: tsc: node_modules
npm run build npm run build
target/workTimeCalculator: target/main.js target/workTimeCalculator: target/main.js

View file

@ -9,19 +9,25 @@ dayjs.extend(duration);
const { log, error } = console; const { log, error } = console;
const defaultStartTime = '08:00'; const defaultStartTime = '08:00';
const durationFormat = 'HH[ hours and ]mm [minutes]';
const lunchBreakDuration = dayjs.duration(30, 'minutes'); const lunchBreakDuration = dayjs.duration(30, 'minutes');
const defaultWorkDayDuration = '08:00'; const defaultWorkDayDuration = dayjs.duration({ hours: 7, minutes: 30 });
const parseTime = (time: string): Dayjs => dayjs(time, 'HH:mm', true); const formatTimestamp = (timestamp: dayjs.Dayjs): string => timestamp.format('YYYY-MM-DD HH:mm');
const formatDuration = (unLogged: duration.Duration): string => unLogged.format('HH[ hours and ]mm [minutes]');
const parseTimestamp = (time: string): Dayjs => dayjs(time, 'H:mm', true);
const parseDuration = (time: string): Duration => {
const [hours, minutes] = time.split(':').map(Number);
return dayjs.duration({ hours, minutes });
};
const getHoursRounded = (duration: Duration) => { const getHoursRounded = (duration: Duration) => {
// Get total minutes in the duration
let minutes = duration.as('minutes');
// Round up to the next multiple of 15 // Round up to the next multiple of 15
minutes = Math.ceil(minutes / 15) * 15; const minutes = Math.ceil(duration.as('minutes') / 15) * 15;
// Return as hours
return dayjs.duration(minutes, 'minutes').asHours(); return dayjs.duration(minutes, 'minutes').asHours();
}; };
@ -40,34 +46,40 @@ const main = async () => {
// Get work day duration // Get work day duration
let workDayDuration: Duration | undefined = undefined; let workDayDuration: Duration | undefined = undefined;
const durationAnswer = await rl.question(`How long is your work day today, including the lunch break? [${defaultWorkDayDuration}] `); const durationAnswer = await rl.question(
if (durationAnswer === '') { `How long is your work day today, excluding the lunch break? [${defaultWorkDayDuration.format('HH:mm')}] `,
const [hours, minutes] = durationAnswer.split(':').map(Number); );
workDayDuration = dayjs.duration({ hours, minutes }); if (durationAnswer !== '') {
workDayDuration = parseDuration(durationAnswer);
if (workDayDuration.asMinutes() <= 0) { if (workDayDuration.asMinutes() <= 0) {
error( error(
`Failed to parse ${durationAnswer} to duration, using default work day duration ${defaultWorkDayDuration}`, chalk.red(
`Failed to parse ${durationAnswer} to duration, using default work day duration ${defaultWorkDayDuration}`,
),
); );
workDayDuration = undefined; workDayDuration = undefined;
} }
} }
if (!workDayDuration) { if (!workDayDuration) {
const [hours, minutes] = defaultWorkDayDuration.split(':').map(Number); workDayDuration = defaultWorkDayDuration;
workDayDuration = dayjs.duration({ hours, minutes });
} }
// Calculate worked time // Calculate worked time
const startTimeAnswer = await rl.question(`What time did you start work today? [${defaultStartTime}] `); const startTimeAnswer = await rl.question(`What time did you start work today? [${defaultStartTime}] `);
if (startTimeAnswer !== '') { if (startTimeAnswer !== '') {
started = parseTime(startTimeAnswer); started = parseTimestamp(startTimeAnswer);
if (!started.isValid()) { if (!started.isValid()) {
error(`Failed to parse ${startTimeAnswer} to time, using default start time ${defaultStartTime}`); error(
chalk.red(
`Failed to parse ${startTimeAnswer} to time, using default start time ${defaultStartTime}`,
),
);
} }
} }
if (!started || !started.isValid()) { if (!started?.isValid()) {
started = parseTime(defaultStartTime); started = parseTimestamp(defaultStartTime);
} }
let stopped: Dayjs | undefined = undefined; let stopped: Dayjs | undefined = undefined;
@ -78,7 +90,7 @@ const main = async () => {
if (stoppedAnswer === '') { if (stoppedAnswer === '') {
stopped = dayjs(); stopped = dayjs();
} else { } else {
stopped = parseTime(stoppedAnswer); stopped = parseTimestamp(stoppedAnswer);
if (!stopped.isValid()) { if (!stopped.isValid()) {
error(`Failed to parse ${stoppedAnswer} to time, using current time`); error(`Failed to parse ${stoppedAnswer} to time, using current time`);
stopped = dayjs(); stopped = dayjs();
@ -98,28 +110,21 @@ const main = async () => {
if (loggedAnswer === '') { if (loggedAnswer === '') {
loggedAnswer = '00:00'; loggedAnswer = '00:00';
} }
const [hours, minutes] = loggedAnswer.split(':').map(Number); const logged = parseDuration(loggedAnswer);
const logged = dayjs.duration({ hours, minutes }); const unLoggedDuration = workDayDuration.subtract(logged);
const unLoggedDuration = workDayDuration.subtract(worked.subtract(logged));
log('logged minutes', logged.asMinutes());
log('unlogged minutes', unLoggedDuration.asMinutes());
if (unLoggedDuration.asMinutes() > 0) { if (unLoggedDuration.asMinutes() > 0) {
unLogged = unLoggedDuration; unLogged = unLoggedDuration;
} }
// Log output // Log result
log(); log();
log('Started working at', started.format('YYYY-MM-DD HH:mm')); log('Started working at', formatTimestamp(started));
log('Stopped working at', stopped.format('YYYY-MM-DD HH:mm')); log('Stopped working at', formatTimestamp(stopped));
log( log('Total worked today:', chalk.green(formatDuration(worked)), chalk.yellow(getHoursRoundedStr(worked)));
'Total worked today:',
chalk.green(worked.format(durationFormat)),
chalk.yellow(getHoursRoundedStr(worked)),
);
log( log(
'Unlogged today:', 'Unlogged today:',
unLogged unLogged
? `${chalk.red(unLogged.format(durationFormat))} ${chalk.yellow(getHoursRoundedStr(unLogged))}` ? `${chalk.red(formatDuration(unLogged))} ${chalk.yellow(getHoursRoundedStr(unLogged))}`
: chalk.green('none'), : chalk.green('none'),
); );
} finally { } finally {