Skip to content

Commit

Permalink
Merge pull request #4153 from aloisklink/chore/switch-to-dayjs
Browse files Browse the repository at this point in the history
Replace `moment-mini`/`moment` date library with `dayjs`
  • Loading branch information
sidharthv96 authored Feb 28, 2023
2 parents 8b5cb75 + a5db04b commit c7bdc6a
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 223 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ jobs:
run: |
pnpm run ci --coverage
- name: Run ganttDb tests using California timezone
env:
# Makes sure that gantt db works even in a timezone that has daylight savings
# since some days have 25 hours instead of 24.
TZ: America/Los_Angeles
run: |
pnpm exec vitest run ./packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts
- name: Upload Coverage to Coveralls
# it feels a bit weird to use @master, but that's what the docs use
# (coveralls also doesn't publish a @v1 we can use)
Expand Down
4 changes: 2 additions & 2 deletions docs/syntax/gantt.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ The following formatting options are supported:
| `YY` | 14 | 2 digit year |
| `Q` | 1..4 | Quarter of year. Sets month to first month in quarter. |
| `M MM` | 1..12 | Month number |
| `MMM MMMM` | January..Dec | Month name in locale set by `moment.locale()` |
| `MMM MMMM` | January..Dec | Month name in locale set by `dayjs.locale()` |
| `D DD` | 1..31 | Day of month |
| `Do` | 1st..31st | Day of month with ordinal |
| `DDD DDDD` | 1..365 | Day of year |
Expand All @@ -200,7 +200,7 @@ The following formatting options are supported:
| `SSS` | 0..999 | Thousandths of a second |
| `Z ZZ` | +12:00 | Offset from UTC as +-HH:mm, +-HHmm, or Z |

More info in: <https://momentjs.com/docs/#/parsing/string-format/>
More info in: <https://day.js.org/docs/en/parse/string-format/>

### Output date format on the axis

Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@
"cytoscape-fcose": "^2.1.0",
"d3": "^7.4.0",
"dagre-d3-es": "7.0.9",
"dayjs": "^1.11.7",
"dompurify": "2.4.3",
"elkjs": "^0.8.2",
"khroma": "^2.0.0",
"lodash-es": "^4.17.21",
"moment-mini": "^2.29.4",
"non-layered-tidy-tree-layout": "^2.0.2",
"stylis": "^4.1.2",
"ts-dedent": "^2.2.0",
Expand Down
99 changes: 76 additions & 23 deletions packages/mermaid/src/diagrams/gantt/ganttDb.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import moment from 'moment-mini';
import { sanitizeUrl } from '@braintree/sanitize-url';
import dayjs from 'dayjs';
import dayjsIsoWeek from 'dayjs/plugin/isoWeek';
import dayjsCustomParseFormat from 'dayjs/plugin/customParseFormat';
import dayjsAdvancedFormat from 'dayjs/plugin/advancedFormat';
import { log } from '../../logger';
import * as configApi from '../../config';
import utils from '../../utils';
Expand All @@ -15,6 +18,10 @@ import {
getDiagramTitle,
} from '../../commonDb';

dayjs.extend(dayjsIsoWeek);
dayjs.extend(dayjsCustomParseFormat);
dayjs.extend(dayjsAdvancedFormat);

let dateFormat = '';
let axisFormat = '';
let tickInterval = undefined;
Expand Down Expand Up @@ -162,18 +169,58 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) {
return excludes.includes(date.format(dateFormat.trim()));
};

/**
* TODO: fully document what this function does and what types it accepts
*
* @param {object} task - The task to check.
* @param {string | Date} task.startTime - Might be a `Date` or a `string`.
* TODO: is this always a Date?
* @param {string | Date} task.endTime - Might be a `Date` or a `string`.
* TODO: is this always a Date?
* @param {string} dateFormat - Dayjs date format string.
* @param {*} excludes
* @param {*} includes
*/
const checkTaskDates = function (task, dateFormat, excludes, includes) {
if (!excludes.length || task.manualEndTime) {
return;
}
let startTime = moment(task.startTime, dateFormat, true);
startTime.add(1, 'd');
let endTime = moment(task.endTime, dateFormat, true);
let renderEndTime = fixTaskDates(startTime, endTime, dateFormat, excludes, includes);
task.endTime = endTime.toDate();
let startTime;
if (task.startTime instanceof Date) {
startTime = dayjs(task.startTime);
} else {
startTime = dayjs(task.startTime, dateFormat, true);
}
startTime = startTime.add(1, 'd');

let originalEndTime;
if (task.endTime instanceof Date) {
originalEndTime = dayjs(task.endTime);
} else {
originalEndTime = dayjs(task.endTime, dateFormat, true);
}
const [fixedEndTime, renderEndTime] = fixTaskDates(
startTime,
originalEndTime,
dateFormat,
excludes,
includes
);
task.endTime = fixedEndTime.toDate();
task.renderEndTime = renderEndTime;
};

/**
* TODO: what does this function do?
*
* @param {dayjs.Dayjs} startTime - The start time.
* @param {dayjs.Dayjs} endTime - The original end time (will return a different end time if it's invalid).
* @param {string} dateFormat - Dayjs date format string.
* @param {*} excludes
* @param {*} includes
* @returns {[endTime: dayjs.Dayjs, renderEndTime: Date | null]} The new `endTime`, and the end time to render.
* `renderEndTime` may be `null` if `startTime` is newer than `endTime`.
*/
const fixTaskDates = function (startTime, endTime, dateFormat, excludes, includes) {
let invalid = false;
let renderEndTime = null;
Expand All @@ -183,11 +230,11 @@ const fixTaskDates = function (startTime, endTime, dateFormat, excludes, include
}
invalid = isInvalidDate(startTime, dateFormat, excludes, includes);
if (invalid) {
endTime.add(1, 'd');
endTime = endTime.add(1, 'd');
}
startTime.add(1, 'd');
startTime = startTime.add(1, 'd');
}
return renderEndTime;
return [endTime, renderEndTime];
};

const getStartDate = function (prevTime, dateFormat, str) {
Expand Down Expand Up @@ -223,7 +270,7 @@ const getStartDate = function (prevTime, dateFormat, str) {
}

// Check for actual date set
let mDate = moment(str, dateFormat.trim(), true);
let mDate = dayjs(str, dateFormat.trim(), true);
if (mDate.isValid()) {
return mDate.toDate();
} else {
Expand All @@ -238,11 +285,14 @@ const getStartDate = function (prevTime, dateFormat, str) {
};

/**
* Parse a string as a moment duration.
* Parse a string into the args for `dayjs.add()`.
*
* The string have to be compound by a value and a shorthand duration unit. For example `5d`
* represents 5 days.
*
* Please be aware that 1 day may be 23 or 25 hours, if the user lives in an area
* that has daylight savings time (or even 23.5/24.5 hours in Lord Howe Island!)
*
* Shorthand unit supported are:
*
* - `y` for years
Expand All @@ -254,33 +304,36 @@ const getStartDate = function (prevTime, dateFormat, str) {
* - `ms` for milliseconds
*
* @param {string} str - A string representing the duration.
* @returns {moment.Duration} A moment duration, including an invalid moment for invalid input
* string.
* @returns {[value: number, unit: dayjs.ManipulateType]} Arguments to pass to `dayjs.add()`
*/
const parseDuration = function (str) {
const statement = /^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(str.trim());
if (statement !== null) {
return moment.duration(Number.parseFloat(statement[1]), statement[2]);
return [Number.parseFloat(statement[1]), statement[2]];
}
return moment.duration.invalid();
// NaN means an invalid duration
return [NaN, 'ms'];
};

const getEndDate = function (prevTime, dateFormat, str, inclusive = false) {
str = str.trim();

// Check for actual date
let mDate = moment(str, dateFormat.trim(), true);
let mDate = dayjs(str, dateFormat.trim(), true);
if (mDate.isValid()) {
if (inclusive) {
mDate.add(1, 'd');
mDate = mDate.add(1, 'd');
}
return mDate.toDate();
}

const endTime = moment(prevTime);
const duration = parseDuration(str);
if (duration.isValid()) {
endTime.add(duration);
let endTime = dayjs(prevTime);
const [durationValue, durationUnit] = parseDuration(str);
if (!Number.isNaN(durationValue)) {
const newEndTime = endTime.add(durationValue, durationUnit);
if (newEndTime.isValid()) {
endTime = newEndTime;
}
}
return endTime.toDate();
};
Expand Down Expand Up @@ -346,7 +399,7 @@ const compileData = function (prevTask, dataStr) {

if (endTimeData) {
task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates);
task.manualEndTime = moment(endTimeData, 'YYYY-MM-DD', true).isValid();
task.manualEndTime = dayjs(endTimeData, 'YYYY-MM-DD', true).isValid();
checkTaskDates(task, dateFormat, excludes, includes);
}

Expand Down Expand Up @@ -496,7 +549,7 @@ const compileTasks = function () {
);
if (rawTasks[pos].endTime) {
rawTasks[pos].processed = true;
rawTasks[pos].manualEndTime = moment(
rawTasks[pos].manualEndTime = dayjs(
rawTasks[pos].raw.endTime.data,
'YYYY-MM-DD',
true
Expand Down
Loading

0 comments on commit c7bdc6a

Please sign in to comment.