Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add custom date format #93

Merged
merged 16 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,11 @@ module.exports = {
curly: ['error', 'all'],
eqeqeq: 'error',
'prefer-arrow-callback': 'error',
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],
},
};
6 changes: 6 additions & 0 deletions schema/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
"title": "History of Cell Execution Time",
"description": "Show the historical N previous execution times since the notebook was opened as a tooltip (0 to disabled)",
"default": 5
},
"dateFormat": {
"type": "string",
"title": "Date format",
"description": "Show the formatted date string in the given format. For example \"yyy-MM-dd HH:mm:ss\" results in \"2023-02-28 14:25:57 \", \"dd/MM/YYY HH:mm:ss (O)\" results in \"28/02/2023 14:25:57 (GMT +3)\".Find out more on unicode date field symbols on this link [https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table]",
skngetich marked this conversation as resolved.
Show resolved Hide resolved
"default": "yyy-MM-dd HH:mm:ss"
skngetich marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
16 changes: 13 additions & 3 deletions src/ExecuteTimeWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface IExecuteTimeSettings {
textContrast: string;
showLiveExecutionTime: boolean;
historyCount: number;
dateFormat: string;
}

export default class ExecuteTimeWidget extends Widget {
Expand Down Expand Up @@ -271,7 +272,8 @@ export default class ExecuteTimeWidget extends Widget {
executionTimeNode.children[2].textContent = '';

msg = `Last executed at ${getTimeString(
endTime
endTime,
this._settings.dateFormat
)} in ${executionTime}`;
}
} else if (startTime) {
Expand Down Expand Up @@ -300,7 +302,10 @@ export default class ExecuteTimeWidget extends Widget {
}
}, 100);
}
msg = `Execution started at ${getTimeString(startTime)}`;
msg = `Execution started at ${getTimeString(
startTime,
this._settings.dateFormat
)}`;
} else if (queuedTime) {
const lastRunTime = executionTimeNode.getAttribute(
'data-prev-execution-time'
Expand All @@ -309,7 +314,10 @@ export default class ExecuteTimeWidget extends Widget {
executionTimeNode.children[2].textContent = `N/A (${lastRunTime})`;
}

msg = `Execution queued at ${getTimeString(queuedTime)}`;
msg = `Execution queued at ${getTimeString(
queuedTime,
this._settings.dateFormat
)}`;
}
if (executionTimeNode.textContent !== msg) {
executionTimeNode.children[0].textContent = msg;
Expand Down Expand Up @@ -346,6 +354,7 @@ export default class ExecuteTimeWidget extends Widget {
.composite as boolean;
this._settings.historyCount = settings.get('historyCount')
.composite as number;
this._settings.dateFormat = settings.get('dateFormat').composite as string;
skngetich marked this conversation as resolved.
Show resolved Hide resolved
skngetich marked this conversation as resolved.
Show resolved Hide resolved

const cells = this._panel.context.model.cells;
if (this._settings.enabled) {
Expand Down Expand Up @@ -375,5 +384,6 @@ export default class ExecuteTimeWidget extends Widget {
textContrast: 'high',
showLiveExecutionTime: true,
historyCount: 5,
dateFormat: 'yyy-MM-dd HH:mm:ss',
};
}
49 changes: 47 additions & 2 deletions src/formatters.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,52 @@
import { differenceInMilliseconds, format } from 'date-fns';

export const getTimeString = (date: Date): string => {
return format(date, 'yyy-MM-dd HH:mm:ss');
/**
skngetich marked this conversation as resolved.
Show resolved Hide resolved
* Checks if a given date format string is valid.
*
* This function checks if the input date format string contains only valid characters.
* Valid unicode date field characters include: y, G, u, q, Q, M, L, w, d, e, E, c, a, b, B, h, H, k, K, m, s, S, z, O, x, X.
* Valid unicade date field characters are based on [date-fns unicode format](https://date-fns.org/docs/format).
*
* @param {string} dateFormat - The date format string to validate.
* @returns {boolean} Returns true if the format is valid.
* @throws {Error} Throws an error if the format contains invalid characters.
*/
export const isValidDateFormat = (dateFormat: string) => {
const validCharsRegex = new RegExp(
'([^yGuqQMLwdeEcabBhHkKmsSzOxX\\W])',
'gm'
);

const invalidChars = dateFormat.match(validCharsRegex);

if (invalidChars !== null) {
const uniqueInvalidChars = [...new Set(invalidChars)];
throw new Error(
`Invalid characters in date format: ${uniqueInvalidChars.join(
', '
)} . see https://date-fns.org/docs/format for valid characters`
);
}

return true; // The format is valid.
};
skngetich marked this conversation as resolved.
Show resolved Hide resolved

export const getTimeString = (
date: Date,
dateFormat = 'yyy-MM-dd HH:mm:ss'
): string => {
try {
// Check if the dateFormat is valid before formatting
isValidDateFormat(dateFormat);

return format(date, dateFormat);
} catch (error) {
if (error instanceof RangeError) {
console.error(error.message);
} else {
throw error; // Re-throw other errors for further handling
}
}
skngetich marked this conversation as resolved.
Show resolved Hide resolved
};

export const getTimeDiff = (end: Date, start: Date): string => {
Expand Down