Replaced moment.js with Javascript date.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu 2025-10-17 00:26:11 +03:00
parent 8c5b43295d
commit cb6afe67a7
18 changed files with 933 additions and 222 deletions

View file

@ -1,6 +1,25 @@
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import { DatePicker } from '/client/lib/datepicker';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
import Cards from '/models/cards';
import { CustomFieldStringTemplate } from '/client/lib/customFields'
@ -134,18 +153,18 @@ CardCustomField.register('cardCustomField');
super.onCreated();
const self = this;
self.date = ReactiveVar();
self.now = ReactiveVar(moment());
self.now = ReactiveVar(now());
window.setInterval(() => {
self.now.set(moment());
self.now.set(now());
}, 60000);
self.autorun(() => {
self.date.set(moment(self.data().value));
self.date.set(new Date(self.data().value));
});
}
showWeek() {
return this.date.get().week().toString();
return getISOWeek(this.date.get()).toString();
}
showWeekOfYear() {
@ -153,12 +172,7 @@ CardCustomField.register('cardCustomField');
}
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
// until then, the date is displayed in the "L" format
return this.date.get().calendar(null, {
sameElse: 'llll',
});
return calendar(this.date.get());
}
showISODate() {
@ -167,8 +181,8 @@ CardCustomField.register('cardCustomField');
classes() {
if (
this.date.get().isBefore(this.now.get(), 'minute') &&
this.now.get().isBefore(this.data().value)
isBefore(this.date.get(), this.now.get(), 'minute') &&
isBefore(this.now.get(), this.data().value, 'minute')
) {
return 'current';
}
@ -176,7 +190,7 @@ CardCustomField.register('cardCustomField');
}
showTitle() {
return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`;
return `${TAPi18n.__('card-start-on')} ${this.date.get().toLocaleString()}`;
}
events() {
@ -195,7 +209,7 @@ CardCustomField.register('cardCustomField');
const self = this;
self.card = Utils.getCurrentCard();
self.customFieldId = this.data()._id;
this.data().value && this.date.set(moment(this.data().value));
this.data().value && this.date.set(new Date(this.data().value));
}
_storeDate(date) {

View file

@ -1,17 +1,36 @@
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import { DatePicker } from '/client/lib/datepicker';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
// editCardReceivedDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
super.onCreated(formatDateTime(now()));
this.data().getReceived() &&
this.date.set(moment(this.data().getReceived()));
this.date.set(new Date(this.data().getReceived()));
}
_storeDate(date) {
this.card.setReceived(moment(date).format('YYYY-MM-DD HH:mm'));
this.card.setReceived(formatDateTime(date));
}
_deleteDate() {
@ -22,8 +41,8 @@ import { DatePicker } from '/client/lib/datepicker';
// editCardStartDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getStart() && this.date.set(moment(this.data().getStart()));
super.onCreated(formatDateTime(now()));
this.data().getStart() && this.date.set(new Date(this.data().getStart()));
}
onRendered() {
@ -37,7 +56,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setStart(moment(date).format('YYYY-MM-DD HH:mm'));
this.card.setStart(formatDateTime(date));
}
_deleteDate() {
@ -49,7 +68,7 @@ import { DatePicker } from '/client/lib/datepicker';
(class extends DatePicker {
onCreated() {
super.onCreated('1970-01-01 17:00:00');
this.data().getDue() && this.date.set(moment(this.data().getDue()));
this.data().getDue() && this.date.set(new Date(this.data().getDue()));
}
onRendered() {
@ -60,7 +79,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setDue(moment(date).format('YYYY-MM-DD HH:mm'));
this.card.setDue(formatDateTime(date));
}
_deleteDate() {
@ -71,8 +90,8 @@ import { DatePicker } from '/client/lib/datepicker';
// editCardEndDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getEnd() && this.date.set(moment(this.data().getEnd()));
super.onCreated(formatDateTime(now()));
this.data().getEnd() && this.date.set(new Date(this.data().getEnd()));
}
onRendered() {
@ -83,7 +102,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setEnd(moment(date).format('YYYY-MM-DD HH:mm'));
this.card.setEnd(formatDateTime(date));
}
_deleteDate() {
@ -100,14 +119,14 @@ const CardDate = BlazeComponent.extendComponent({
onCreated() {
const self = this;
self.date = ReactiveVar();
self.now = ReactiveVar(moment());
self.now = ReactiveVar(now());
window.setInterval(() => {
self.now.set(moment());
self.now.set(now());
}, 60000);
},
showWeek() {
return this.date.get().week().toString();
return getISOWeek(this.date.get()).toString();
},
showWeekOfYear() {
@ -115,12 +134,7 @@ const CardDate = BlazeComponent.extendComponent({
},
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
// until then, the date is displayed in the "L" format
return this.date.get().calendar(null, {
sameElse: 'llll',
});
return calendar(this.date.get());
},
showISODate() {
@ -133,7 +147,7 @@ class CardReceivedDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getReceived()));
self.date.set(new Date(self.data().getReceived()));
});
}
@ -173,7 +187,7 @@ class CardStartDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getStart()));
self.date.set(new Date(self.data().getStart()));
});
}
@ -208,7 +222,7 @@ class CardDueDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getDue()));
self.date.set(new Date(self.data().getDue()));
});
}
@ -244,7 +258,7 @@ class CardEndDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getEnd()));
self.date.set(new Date(self.data().getEnd()));
});
}
@ -279,12 +293,12 @@ class CardCustomFieldDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().value));
self.date.set(new Date(self.data().value));
});
}
showWeek() {
return this.date.get().week().toString();
return getISOWeek(this.date.get()).toString();
}
showWeekOfYear() {
@ -316,31 +330,31 @@ CardCustomFieldDate.register('cardCustomFieldDate');
(class extends CardReceivedDate {
showDate() {
return this.date.get().format('L');
return format(this.date.get(), 'L');
}
}.register('minicardReceivedDate'));
(class extends CardStartDate {
showDate() {
return this.date.get().format('YYYY-MM-DD HH:mm');
return format(this.date.get(), 'YYYY-MM-DD HH:mm');
}
}.register('minicardStartDate'));
(class extends CardDueDate {
showDate() {
return this.date.get().format('YYYY-MM-DD HH:mm');
return format(this.date.get(), 'YYYY-MM-DD HH:mm');
}
}.register('minicardDueDate'));
(class extends CardEndDate {
showDate() {
return this.date.get().format('YYYY-MM-DD HH:mm');
return format(this.date.get(), 'YYYY-MM-DD HH:mm');
}
}.register('minicardEndDate'));
(class extends CardCustomFieldDate {
showDate() {
return this.date.get().format('L');
return format(this.date.get(), 'L');
}
}.register('minicardCustomFieldDate'));
@ -349,7 +363,7 @@ class VoteEndDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getVoteEnd()));
self.date.set(new Date(self.data().getVoteEnd()));
});
}
classes() {
@ -357,10 +371,10 @@ class VoteEndDate extends CardDate {
return classes;
}
showDate() {
return this.date.get().format('L LT');
return format(this.date.get(), 'L') + ' ' + format(this.date.get(), 'HH:mm');
}
showTitle() {
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
return `${TAPi18n.__('card-end-on')} ${this.date.get().toLocaleString()}`;
}
events() {
@ -376,7 +390,7 @@ class PokerEndDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getPokerEnd()));
self.date.set(new Date(self.data().getPokerEnd()));
});
}
classes() {

View file

@ -1,7 +1,26 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import { DatePicker } from '/client/lib/datepicker';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
import Cards from '/models/cards';
import Boards from '/models/boards';
import Checklists from '/models/checklists';
@ -455,7 +474,7 @@ BlazeComponent.extendComponent({
'click .js-poker-finish'(e) {
if ($(e.target).hasClass('js-poker-finish')) {
e.preventDefault();
const now = moment().format('YYYY-MM-DD HH:mm');
const now = formatDateTime(new Date());
this.data().setPokerEnd(now);
}
},
@ -1106,8 +1125,8 @@ BlazeComponent.extendComponent({
// editVoteEndDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getVoteEnd() && this.date.set(moment(this.data().getVoteEnd()));
super.onCreated(formatDateTime(now()));
this.data().getVoteEnd() && this.date.set(new Date(this.data().getVoteEnd()));
}
events() {
return [
@ -1118,12 +1137,12 @@ BlazeComponent.extendComponent({
// if no time was given, init with 12:00
const time =
evt.target.time.value ||
moment(new Date().setHours(12, 0, 0)).format('LT');
formatTime(new Date().setHours(12, 0, 0));
const dateString = `${evt.target.date.value} ${time}`;
/*
const newDate = moment(dateString, 'L LT', true);
const newDate = parseDate(dateString, ['L LT'], true);
if (newDate.isValid()) {
// if active vote - store it
if (this.currentData().getVoteQuestion()) {
@ -1137,28 +1156,27 @@ BlazeComponent.extendComponent({
*/
// Try to parse different date formats of all languages.
// This code is same for vote and planning poker.
const usaDate = moment(dateString, 'L LT', true);
const euroAmDate = moment(dateString, 'DD.MM.YYYY LT', true);
const euro24hDate = moment(dateString, 'DD.MM.YYYY HH.mm', true);
const eurodotDate = moment(dateString, 'DD.MM.YYYY HH:mm', true);
const minusDate = moment(dateString, 'YYYY-MM-DD HH:mm', true);
const slashDate = moment(dateString, 'DD/MM/YYYY HH.mm', true);
const dotDate = moment(dateString, 'DD/MM/YYYY HH:mm', true);
const brezhonegDate = moment(dateString, 'DD/MM/YYYY h[e]mm A', true);
const hrvatskiDate = moment(dateString, 'DD. MM. YYYY H:mm', true);
const latviaDate = moment(dateString, 'YYYY.MM.DD. H:mm', true);
const nederlandsDate = moment(dateString, 'DD-MM-YYYY HH:mm', true);
// greekDate does not work: el Greek Ελληνικά ,
// it has date format DD/MM/YYYY h:mm MM like 20/06/2021 11:15 MM
// where MM is maybe some text like AM/PM ?
// Also some other languages that have non-ascii characters in dates
// do not work.
const greekDate = moment(dateString, 'DD/MM/YYYY h:mm A', true);
const macedonianDate = moment(dateString, 'D.MM.YYYY H:mm', true);
// Try to parse different date formats using native Date parsing
const formats = [
'YYYY-MM-DD HH:mm',
'MM/DD/YYYY HH:mm',
'DD.MM.YYYY HH:mm',
'DD/MM/YYYY HH:mm',
'DD-MM-YYYY HH:mm'
];
if (usaDate.isValid()) {
let parsedDate = null;
for (const format of formats) {
parsedDate = parseDate(dateString, [format], true);
if (parsedDate) break;
}
// Fallback to native Date parsing
if (!parsedDate) {
parsedDate = new Date(dateString);
}
if (isValidDate(parsedDate)) {
// if active poker - store it
if (this.currentData().getPokerQuestion()) {
this._storeDate(usaDate.toDate());
@ -1337,9 +1355,9 @@ BlazeComponent.extendComponent({
// editPokerEndDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
super.onCreated(formatDateTime(now()));
this.data().getPokerEnd() &&
this.date.set(moment(this.data().getPokerEnd()));
this.date.set(new Date(this.data().getPokerEnd()));
}
/*
@ -1357,7 +1375,7 @@ BlazeComponent.extendComponent({
return moment.localeData().longDateFormat('LT');
}
const newDate = moment(dateString, dateformat() + ' ' + timeformat(), true);
const newDate = parseDate(dateString, [dateformat() + ' ' + timeformat()], true);
*/
events() {
@ -1369,7 +1387,7 @@ BlazeComponent.extendComponent({
// if no time was given, init with 12:00
const time =
evt.target.time.value ||
moment(new Date().setHours(12, 0, 0)).format('LT');
formatTime(new Date().setHours(12, 0, 0));
const dateString = `${evt.target.date.value} ${time}`;
@ -1380,7 +1398,7 @@ BlazeComponent.extendComponent({
Maybe client/components/lib/datepicker.jade could have hidden input field for
datepicker format that could be used to detect date format?
const newDate = moment(dateString, dateformat() + ' ' + timeformat(), true);
const newDate = parseDate(dateString, [dateformat() + ' ' + timeformat()], true);
if (newDate.isValid()) {
// if active poker - store it
@ -1393,28 +1411,27 @@ BlazeComponent.extendComponent({
}
*/
// Try to parse different date formats of all languages.
// This code is same for vote and planning poker.
const usaDate = moment(dateString, 'L LT', true);
const euroAmDate = moment(dateString, 'DD.MM.YYYY LT', true);
const euro24hDate = moment(dateString, 'DD.MM.YYYY HH.mm', true);
const eurodotDate = moment(dateString, 'DD.MM.YYYY HH:mm', true);
const minusDate = moment(dateString, 'YYYY-MM-DD HH:mm', true);
const slashDate = moment(dateString, 'DD/MM/YYYY HH.mm', true);
const dotDate = moment(dateString, 'DD/MM/YYYY HH:mm', true);
const brezhonegDate = moment(dateString, 'DD/MM/YYYY h[e]mm A', true);
const hrvatskiDate = moment(dateString, 'DD. MM. YYYY H:mm', true);
const latviaDate = moment(dateString, 'YYYY.MM.DD. H:mm', true);
const nederlandsDate = moment(dateString, 'DD-MM-YYYY HH:mm', true);
// greekDate does not work: el Greek Ελληνικά ,
// it has date format DD/MM/YYYY h:mm MM like 20/06/2021 11:15 MM
// where MM is maybe some text like AM/PM ?
// Also some other languages that have non-ascii characters in dates
// do not work.
const greekDate = moment(dateString, 'DD/MM/YYYY h:mm A', true);
const macedonianDate = moment(dateString, 'D.MM.YYYY H:mm', true);
// Try to parse different date formats using native Date parsing
const formats = [
'YYYY-MM-DD HH:mm',
'MM/DD/YYYY HH:mm',
'DD.MM.YYYY HH:mm',
'DD/MM/YYYY HH:mm',
'DD-MM-YYYY HH:mm'
];
if (usaDate.isValid()) {
let parsedDate = null;
for (const format of formats) {
parsedDate = parseDate(dateString, [format], true);
if (parsedDate) break;
}
// Fallback to native Date parsing
if (!parsedDate) {
parsedDate = new Date(dateString);
}
if (isValidDate(parsedDate)) {
// if active poker - store it
if (this.currentData().getPokerQuestion()) {
this._storeDate(usaDate.toDate());

View file

@ -1,7 +1,26 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { Blaze } from 'meteor/blaze';
import { Session } from 'meteor/session';
import moment from 'moment/min/moment-with-locales';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
Blaze.registerHelper('currentBoard', () => {
const ret = Utils.getCurrentBoard();
@ -47,7 +66,7 @@ Blaze.registerHelper('isTouchScreenOrShowDesktopDragHandles', () =>
Blaze.registerHelper('moment', (...args) => {
args.pop(); // hash
const [date, format] = args;
return moment(date).format(format ?? 'LLLL');
return format(new Date(date), format ?? 'LLLL');
});
Blaze.registerHelper('canModifyCard', () =>

View file

@ -1,12 +1,29 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import moment from 'moment/min/moment-with-locales';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
// Helper function to replace HH with H for 24 hours format, because H allows also single-digit hours
// Helper function to get time format for 24 hours
function adjustedTimeFormat() {
return moment
.localeData()
.longDateFormat('LT');
return 'HH:mm';
}
// .replace(/HH/i, 'H');
@ -19,7 +36,7 @@ export class DatePicker extends BlazeComponent {
onCreated(defaultTime = '1970-01-01 08:00:00') {
this.error = new ReactiveVar('');
this.card = this.data();
this.date = new ReactiveVar(moment.invalid());
this.date = new ReactiveVar(new Date('invalid'));
this.defaultTime = defaultTime;
}
@ -34,35 +51,35 @@ export class DatePicker extends BlazeComponent {
onRendered() {
// Set initial values for native HTML inputs
if (this.date.get().isValid()) {
if (isValidDate(this.date.get())) {
const dateInput = this.find('#date');
const timeInput = this.find('#time');
if (dateInput) {
dateInput.value = this.date.get().format('YYYY-MM-DD');
dateInput.value = formatDate(this.date.get());
}
if (timeInput && !timeInput.value && this.defaultTime) {
const defaultMoment = moment(this.defaultTime);
timeInput.value = defaultMoment.format('HH:mm');
} else if (timeInput && this.date.get().isValid()) {
timeInput.value = this.date.get().format('HH:mm');
const defaultDate = new Date(this.defaultTime);
timeInput.value = formatTime(defaultDate);
} else if (timeInput && isValidDate(this.date.get())) {
timeInput.value = formatTime(this.date.get());
}
}
}
showDate() {
if (this.date.get().isValid()) return this.date.get().format('YYYY-MM-DD');
if (isValidDate(this.date.get())) return formatDate(this.date.get());
return '';
}
showTime() {
if (this.date.get().isValid()) return this.date.get().format('HH:mm');
if (isValidDate(this.date.get())) return formatTime(this.date.get());
return '';
}
dateFormat() {
return moment.localeData().longDateFormat('L');
return 'L';
}
timeFormat() {
return moment.localeData().longDateFormat('LT');
return 'LT';
}
events() {
@ -72,8 +89,8 @@ export class DatePicker extends BlazeComponent {
// Native HTML date input validation
const dateValue = this.find('#date').value;
if (dateValue) {
const dateMoment = moment(dateValue, 'YYYY-MM-DD', true);
if (dateMoment.isValid()) {
const dateObj = new Date(dateValue);
if (isValidDate(dateObj)) {
this.error.set('');
} else {
this.error.set('invalid-date');
@ -84,8 +101,8 @@ export class DatePicker extends BlazeComponent {
// Native HTML time input validation
const timeValue = this.find('#time').value;
if (timeValue) {
const timeMoment = moment(timeValue, 'HH:mm', true);
if (timeMoment.isValid()) {
const timeObj = new Date(`1970-01-01T${timeValue}`);
if (isValidDate(timeObj)) {
this.error.set('');
} else {
this.error.set('invalid-time');
@ -104,14 +121,14 @@ export class DatePicker extends BlazeComponent {
return;
}
const newCompleteDate = moment(`${dateValue} ${timeValue}`, 'YYYY-MM-DD HH:mm', true);
const newCompleteDate = new Date(`${dateValue}T${timeValue}`);
if (!newCompleteDate.isValid()) {
if (!isValidDate(newCompleteDate)) {
this.error.set('invalid');
return;
}
this._storeDate(newCompleteDate.toDate());
this._storeDate(newCompleteDate);
Popup.back();
},
'click .js-delete-date'(evt) {

View file

@ -1,5 +1,24 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
// Filtered view manager
// We define local filter objects for each different type of field (SetFilter,
@ -30,7 +49,7 @@ class DateFilter {
this.reset();
return;
}
this._filter = { $lte: moment().toDate() };
this._filter = { $lte: now() };
this._updateState('past');
}
@ -72,13 +91,8 @@ class DateFilter {
return;
}
var startDay = moment()
.startOf('day')
.toDate(),
endDay = moment()
.endOf('day')
.add(offset, 'day')
.toDate();
var startDay = startOf(now(), 'day'),
endDay = endOf(add(now(), offset, 'day'), 'day');
if (offset >= 0) {
this._filter = { $gte: startDay, $lte: endDay };
@ -112,33 +126,21 @@ class DateFilter {
const weekStartDay = currentUser ? currentUser.getStartDayOfWeek() : 1;
if (week === 'this') {
// Moments are mutable so they must be cloned before modification
var WeekStart = moment()
.startOf('day')
.startOf('week')
.add(weekStartDay, 'days');
var WeekEnd = WeekStart
.clone()
.add(6, 'days')
.endOf('day');
// Create week start and end dates
var WeekStart = startOf(add(startOf(now(), 'week'), weekStartDay, 'days'), 'day');
var WeekEnd = endOf(add(WeekStart, 6, 'days'), 'day');
this._updateState('thisweek');
} else if (week === 'next') {
// Moments are mutable so they must be cloned before modification
var WeekStart = moment()
.startOf('day')
.startOf('week')
.add(weekStartDay + 7, 'days');
var WeekEnd = WeekStart
.clone()
.add(6, 'days')
.endOf('day');
// Create next week start and end dates
var WeekStart = startOf(add(startOf(now(), 'week'), weekStartDay + 7, 'days'), 'day');
var WeekEnd = endOf(add(WeekStart, 6, 'days'), 'day');
this._updateState('nextweek');
}
var startDate = WeekStart.toDate();
var endDate = WeekEnd.toDate();
var startDate = WeekStart;
var endDate = WeekEnd;
if (offset >= 0) {
this._filter = { $gte: startDate, $lte: endDate };

View file

@ -1,5 +1,24 @@
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
import {
OPERATOR_ASSIGNEE,
OPERATOR_BOARD,
@ -421,43 +440,44 @@ export class Query {
switch (duration) {
case PREDICATE_WEEK:
// eslint-disable-next-line no-case-declarations
const week = moment().week();
const week = getISOWeek(now());
if (week === 52) {
date = moment(1, 'W');
date.set('year', date.year() + 1);
date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year
} else {
date = moment(week + 1, 'W');
// Calculate the date for the next week
const currentDate = now();
const daysToAdd = (week + 1) * 7 - (currentDate.getDay() + 6) % 7;
date = add(currentDate, daysToAdd, 'days');
}
break;
case PREDICATE_MONTH:
// eslint-disable-next-line no-case-declarations
const month = moment().month();
// .month() is zero indexed
const month = now().getMonth();
// .getMonth() is zero indexed
if (month === 11) {
date = moment(1, 'M');
date.set('year', date.year() + 1);
date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year
} else {
date = moment(month + 2, 'M');
date = new Date(now().getFullYear(), month + 1, 1); // First day of next month
}
break;
case PREDICATE_QUARTER:
// eslint-disable-next-line no-case-declarations
const quarter = moment().quarter();
const quarter = Math.floor(now().getMonth() / 3) + 1;
if (quarter === 4) {
date = moment(1, 'Q');
date.set('year', date.year() + 1);
date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year
} else {
date = moment(quarter + 1, 'Q');
const nextQuarterMonth = quarter * 3; // 3, 6, 9 for quarters 2, 3, 4
date = new Date(now().getFullYear(), nextQuarterMonth, 1); // First day of next quarter
}
break;
case PREDICATE_YEAR:
date = moment(moment().year() + 1, 'YYYY');
date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year
break;
}
if (date) {
value = {
operator: '$lt',
value: date.format('YYYY-MM-DD'),
value: formatDate(date),
};
}
} else if (
@ -466,7 +486,7 @@ export class Query {
) {
value = {
operator: '$lt',
value: moment().format('YYYY-MM-DD'),
value: formatDate(now()),
};
} else {
this.addError(OPERATOR_DUE, {
@ -478,16 +498,12 @@ export class Query {
} else if (operator === OPERATOR_DUE) {
value = {
operator: '$lt',
value: moment(moment().format('YYYY-MM-DD'))
.add(days + 1, duration ? duration : 'days')
.format(),
value: formatDate(add(add(now(), 1, 'days'), days + 1, duration ? duration : 'days')),
};
} else {
value = {
operator: '$gte',
value: moment(moment().format('YYYY-MM-DD'))
.subtract(days, duration ? duration : 'days')
.format(),
value: formatDate(subtract(now(), days, duration ? duration : 'days')),
};
}
} else if (operator === OPERATOR_SORT) {

View file

@ -1,6 +1,5 @@
import { TAPi18n } from './tap';
import './accounts';
import './moment';
if (Meteor.isClient) {
import './blaze';

View file

@ -1,13 +1,5 @@
import { Tracker } from 'meteor/tracker';
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from './tap';
// Reactively adjust Moment.js translations
Tracker.autorun(() => {
const language = TAPi18n.getLanguage();
try {
moment.locale(language);
} catch (err) {
console.error(err);
}
});
// Note: moment.js has been removed and replaced with native JavaScript Date functions
// Locale handling is now done through native Date.toLocaleString() methods

492
imports/lib/dateUtils.js Normal file
View file

@ -0,0 +1,492 @@
/**
* Date utility functions to replace moment.js with native JavaScript Date
*/
/**
* Format a date to YYYY-MM-DD HH:mm format
* @param {Date|string} date - Date to format
* @returns {string} Formatted date string
*/
export function formatDateTime(date) {
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}`;
}
/**
* Format a date to YYYY-MM-DD format
* @param {Date|string} date - Date to format
* @returns {string} Formatted date string
*/
export function formatDate(date) {
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
/**
* Format a time to HH:mm format
* @param {Date|string} date - Date to format
* @returns {string} Formatted time string
*/
export function formatTime(date) {
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
return `${hours}:${minutes}`;
}
/**
* Get ISO week number (ISO 8601)
* @param {Date|string} date - Date to get week number for
* @returns {number} ISO week number
*/
export function getISOWeek(date) {
const d = new Date(date);
if (isNaN(d.getTime())) return 0;
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
const target = new Date(d);
const dayNr = (d.getDay() + 6) % 7;
target.setDate(target.getDate() - dayNr + 3);
// ISO week date weeks start on monday, so correct the day number
const firstThursday = target.valueOf();
target.setMonth(0, 1);
if (target.getDay() !== 4) {
target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
}
return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000
}
/**
* Check if a date is valid
* @param {Date|string} date - Date to check
* @returns {boolean} True if date is valid
*/
export function isValidDate(date) {
const d = new Date(date);
return !isNaN(d.getTime());
}
/**
* Check if a date is before another date
* @param {Date|string} date1 - First date
* @param {Date|string} date2 - Second date
* @param {string} unit - Unit of comparison ('minute', 'hour', 'day', etc.)
* @returns {boolean} True if date1 is before date2
*/
export function isBefore(date1, date2, unit = 'millisecond') {
const d1 = new Date(date1);
const d2 = new Date(date2);
if (isNaN(d1.getTime()) || isNaN(d2.getTime())) return false;
switch (unit) {
case 'year':
return d1.getFullYear() < d2.getFullYear();
case 'month':
return d1.getFullYear() < d2.getFullYear() ||
(d1.getFullYear() === d2.getFullYear() && d1.getMonth() < d2.getMonth());
case 'day':
return d1.getFullYear() < d2.getFullYear() ||
(d1.getFullYear() === d2.getFullYear() && d1.getMonth() < d2.getMonth()) ||
(d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() < d2.getDate());
case 'hour':
return d1.getTime() < d2.getTime() && Math.floor(d1.getTime() / (1000 * 60 * 60)) < Math.floor(d2.getTime() / (1000 * 60 * 60));
case 'minute':
return d1.getTime() < d2.getTime() && Math.floor(d1.getTime() / (1000 * 60)) < Math.floor(d2.getTime() / (1000 * 60));
default:
return d1.getTime() < d2.getTime();
}
}
/**
* Check if a date is after another date
* @param {Date|string} date1 - First date
* @param {Date|string} date2 - Second date
* @param {string} unit - Unit of comparison ('minute', 'hour', 'day', etc.)
* @returns {boolean} True if date1 is after date2
*/
export function isAfter(date1, date2, unit = 'millisecond') {
return isBefore(date2, date1, unit);
}
/**
* Check if a date is the same as another date
* @param {Date|string} date1 - First date
* @param {Date|string} date2 - Second date
* @param {string} unit - Unit of comparison ('minute', 'hour', 'day', etc.)
* @returns {boolean} True if dates are the same
*/
export function isSame(date1, date2, unit = 'millisecond') {
const d1 = new Date(date1);
const d2 = new Date(date2);
if (isNaN(d1.getTime()) || isNaN(d2.getTime())) return false;
switch (unit) {
case 'year':
return d1.getFullYear() === d2.getFullYear();
case 'month':
return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth();
case 'day':
return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate();
case 'hour':
return Math.floor(d1.getTime() / (1000 * 60 * 60)) === Math.floor(d2.getTime() / (1000 * 60 * 60));
case 'minute':
return Math.floor(d1.getTime() / (1000 * 60)) === Math.floor(d2.getTime() / (1000 * 60));
default:
return d1.getTime() === d2.getTime();
}
}
/**
* Add time to a date
* @param {Date|string} date - Base date
* @param {number} amount - Amount to add
* @param {string} unit - Unit ('years', 'months', 'days', 'hours', 'minutes', 'seconds')
* @returns {Date} New date
*/
export function add(date, amount, unit) {
const d = new Date(date);
if (isNaN(d.getTime())) return new Date();
switch (unit) {
case 'years':
d.setFullYear(d.getFullYear() + amount);
break;
case 'months':
d.setMonth(d.getMonth() + amount);
break;
case 'days':
d.setDate(d.getDate() + amount);
break;
case 'hours':
d.setHours(d.getHours() + amount);
break;
case 'minutes':
d.setMinutes(d.getMinutes() + amount);
break;
case 'seconds':
d.setSeconds(d.getSeconds() + amount);
break;
default:
d.setTime(d.getTime() + amount);
}
return d;
}
/**
* Subtract time from a date
* @param {Date|string} date - Base date
* @param {number} amount - Amount to subtract
* @param {string} unit - Unit ('years', 'months', 'days', 'hours', 'minutes', 'seconds')
* @returns {Date} New date
*/
export function subtract(date, amount, unit) {
return add(date, -amount, unit);
}
/**
* Get start of a time unit
* @param {Date|string} date - Base date
* @param {string} unit - Unit ('year', 'month', 'day', 'hour', 'minute', 'second')
* @returns {Date} Start of unit
*/
export function startOf(date, unit) {
const d = new Date(date);
if (isNaN(d.getTime())) return new Date();
switch (unit) {
case 'year':
d.setMonth(0, 1);
d.setHours(0, 0, 0, 0);
break;
case 'month':
d.setDate(1);
d.setHours(0, 0, 0, 0);
break;
case 'day':
d.setHours(0, 0, 0, 0);
break;
case 'hour':
d.setMinutes(0, 0, 0);
break;
case 'minute':
d.setSeconds(0, 0);
break;
case 'second':
d.setMilliseconds(0);
break;
}
return d;
}
/**
* Get end of a time unit
* @param {Date|string} date - Base date
* @param {string} unit - Unit ('year', 'month', 'day', 'hour', 'minute', 'second')
* @returns {Date} End of unit
*/
export function endOf(date, unit) {
const d = new Date(date);
if (isNaN(d.getTime())) return new Date();
switch (unit) {
case 'year':
d.setMonth(11, 31);
d.setHours(23, 59, 59, 999);
break;
case 'month':
d.setMonth(d.getMonth() + 1, 0);
d.setHours(23, 59, 59, 999);
break;
case 'day':
d.setHours(23, 59, 59, 999);
break;
case 'hour':
d.setMinutes(59, 59, 999);
break;
case 'minute':
d.setSeconds(59, 999);
break;
case 'second':
d.setMilliseconds(999);
break;
}
return d;
}
/**
* Format date for display with locale
* @param {Date|string} date - Date to format
* @param {string} format - Format string (simplified)
* @returns {string} Formatted date string
*/
export function format(date, format = 'L') {
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
switch (format) {
case 'L':
return `${month}/${day}/${year}`;
case 'LL':
return d.toLocaleDateString();
case 'LLL':
return d.toLocaleString();
case 'llll':
return d.toLocaleString();
case 'YYYY-MM-DD':
return `${year}-${month}-${day}`;
case 'YYYY-MM-DD HH:mm':
return `${year}-${month}-${day} ${hours}:${minutes}`;
case 'HH:mm':
return `${hours}:${minutes}`;
default:
return d.toLocaleString();
}
}
/**
* Parse a date string with multiple formats
* @param {string} dateString - Date string to parse
* @param {string[]} formats - Array of format strings to try
* @param {boolean} strict - Whether to use strict parsing
* @returns {Date|null} Parsed date or null if invalid
*/
export function parseDate(dateString, formats = [], strict = true) {
if (!dateString) return null;
// Try native Date parsing first
const nativeDate = new Date(dateString);
if (!isNaN(nativeDate.getTime())) {
return nativeDate;
}
// Try common formats
const commonFormats = [
'YYYY-MM-DD HH:mm',
'YYYY-MM-DD',
'MM/DD/YYYY HH:mm',
'MM/DD/YYYY',
'DD.MM.YYYY HH:mm',
'DD.MM.YYYY',
'DD/MM/YYYY HH:mm',
'DD/MM/YYYY',
'DD-MM-YYYY HH:mm',
'DD-MM-YYYY'
];
const allFormats = [...formats, ...commonFormats];
for (const format of allFormats) {
const parsed = parseWithFormat(dateString, format);
if (parsed && isValidDate(parsed)) {
return parsed;
}
}
return null;
}
/**
* Parse date with specific format
* @param {string} dateString - Date string to parse
* @param {string} format - Format string
* @returns {Date|null} Parsed date or null
*/
function parseWithFormat(dateString, format) {
// Simple format parsing - can be extended as needed
const formatMap = {
'YYYY': '\\d{4}',
'MM': '\\d{2}',
'DD': '\\d{2}',
'HH': '\\d{2}',
'mm': '\\d{2}',
'ss': '\\d{2}'
};
let regex = format;
for (const [key, value] of Object.entries(formatMap)) {
regex = regex.replace(new RegExp(key, 'g'), `(${value})`);
}
const match = dateString.match(new RegExp(regex));
if (!match) return null;
const groups = match.slice(1);
let year, month, day, hour = 0, minute = 0, second = 0;
let groupIndex = 0;
for (let i = 0; i < format.length; i++) {
if (format[i] === 'Y' && format[i + 1] === 'Y' && format[i + 2] === 'Y' && format[i + 3] === 'Y') {
year = parseInt(groups[groupIndex++]);
i += 3;
} else if (format[i] === 'M' && format[i + 1] === 'M') {
month = parseInt(groups[groupIndex++]) - 1;
i += 1;
} else if (format[i] === 'D' && format[i + 1] === 'D') {
day = parseInt(groups[groupIndex++]);
i += 1;
} else if (format[i] === 'H' && format[i + 1] === 'H') {
hour = parseInt(groups[groupIndex++]);
i += 1;
} else if (format[i] === 'm' && format[i + 1] === 'm') {
minute = parseInt(groups[groupIndex++]);
i += 1;
} else if (format[i] === 's' && format[i + 1] === 's') {
second = parseInt(groups[groupIndex++]);
i += 1;
}
}
if (year === undefined || month === undefined || day === undefined) {
return null;
}
return new Date(year, month, day, hour, minute, second);
}
/**
* Get current date and time
* @returns {Date} Current date
*/
export function now() {
return new Date();
}
/**
* Create a date from components
* @param {number} year - Year
* @param {number} month - Month (0-based)
* @param {number} day - Day
* @param {number} hour - Hour (optional)
* @param {number} minute - Minute (optional)
* @param {number} second - Second (optional)
* @returns {Date} Created date
*/
export function createDate(year, month, day, hour = 0, minute = 0, second = 0) {
return new Date(year, month, day, hour, minute, second);
}
/**
* Get relative time string (e.g., "2 hours ago")
* @param {Date|string} date - Date to compare
* @param {Date|string} now - Current date (optional)
* @returns {string} Relative time string
*/
export function fromNow(date, now = new Date()) {
const d = new Date(date);
const n = new Date(now);
if (isNaN(d.getTime()) || isNaN(n.getTime())) return '';
const diffMs = n.getTime() - d.getTime();
const diffSeconds = Math.floor(diffMs / 1000);
const diffMinutes = Math.floor(diffSeconds / 60);
const diffHours = Math.floor(diffMinutes / 60);
const diffDays = Math.floor(diffHours / 24);
const diffWeeks = Math.floor(diffDays / 7);
const diffMonths = Math.floor(diffDays / 30);
const diffYears = Math.floor(diffDays / 365);
if (diffSeconds < 60) return 'a few seconds ago';
if (diffMinutes < 60) return `${diffMinutes} minute${diffMinutes !== 1 ? 's' : ''} ago`;
if (diffHours < 24) return `${diffHours} hour${diffHours !== 1 ? 's' : ''} ago`;
if (diffDays < 7) return `${diffDays} day${diffDays !== 1 ? 's' : ''} ago`;
if (diffWeeks < 4) return `${diffWeeks} week${diffWeeks !== 1 ? 's' : ''} ago`;
if (diffMonths < 12) return `${diffMonths} month${diffMonths !== 1 ? 's' : ''} ago`;
return `${diffYears} year${diffYears !== 1 ? 's' : ''} ago`;
}
/**
* Get calendar format (e.g., "Today", "Yesterday", "Tomorrow")
* @param {Date|string} date - Date to format
* @param {Date|string} now - Current date (optional)
* @returns {string} Calendar format string
*/
export function calendar(date, now = new Date()) {
const d = new Date(date);
const n = new Date(now);
if (isNaN(d.getTime()) || isNaN(n.getTime())) return format(d);
const diffMs = d.getTime() - n.getTime();
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
if (diffDays === 0) return 'Today';
if (diffDays === 1) return 'Tomorrow';
if (diffDays === -1) return 'Yesterday';
if (diffDays > 1 && diffDays < 7) return `In ${diffDays} days`;
if (diffDays < -1 && diffDays > -7) return `${Math.abs(diffDays)} days ago`;
return format(d, 'L');
}

View file

@ -1,5 +1,24 @@
import { ReactiveCache, ReactiveMiniMongoIndex } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
import {
ALLOWED_COLORS,
TYPE_CARD,
@ -1492,8 +1511,8 @@ Cards.helpers({
expiredVote() {
let end = this.getVoteEnd();
if (end) {
end = moment(end);
return end.isBefore(new Date());
end = new Date(end);
return isBefore(end, new Date());
}
return false;
},
@ -1586,8 +1605,8 @@ Cards.helpers({
expiredPoker() {
let end = this.getPokerEnd();
if (end) {
end = moment(end);
return end.isBefore(new Date());
end = new Date(end);
return isBefore(end, new Date());
}
return false;
},
@ -3201,9 +3220,7 @@ if (Meteor.isServer) {
// change list modifiedAt, when user modified the key values in
// timingaction array, if it's endAt, put the modifiedAt of list
// back to one year ago for sorting purpose
const modifiedAt = moment()
.subtract(1, 'year')
.toISOString();
const modifiedAt = add(now(), -1, 'year').toISOString();
const boardId = list.boardId;
Lists.direct.update(
{

View file

@ -1,7 +1,26 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
const Papa = require('papaparse');
import { TAPi18n } from '/imports/i18n';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
//const stringify = require('csv-stringify');
@ -302,15 +321,15 @@ export class Exporter {
labels = `${labels + label.name}-${label.color} `;
});
currentRow.push(labels.trim());
currentRow.push(card.startAt ? moment(card.startAt).format() : ' ');
currentRow.push(card.dueAt ? moment(card.dueAt).format() : ' ');
currentRow.push(card.endAt ? moment(card.endAt).format() : ' ');
currentRow.push(card.startAt ? new Date(card.startAt).toISOString() : ' ');
currentRow.push(card.dueAt ? new Date(card.dueAt).toISOString() : ' ');
currentRow.push(card.endAt ? new Date(card.endAt).toISOString() : ' ');
currentRow.push(card.isOvertime ? 'true' : 'false');
currentRow.push(card.spentTime);
currentRow.push(card.createdAt ? moment(card.createdAt).format() : ' ');
currentRow.push(card.modifiedAt ? moment(card.modifiedAt).format() : ' ');
currentRow.push(card.createdAt ? new Date(card.createdAt).toISOString() : ' ');
currentRow.push(card.modifiedAt ? new Date(card.modifiedAt).toISOString() : ' ');
currentRow.push(
card.dateLastActivity ? moment(card.dateLastActivity).format() : ' ',
card.dateLastActivity ? new Date(card.dateLastActivity).toISOString() : ' ',
);
if (card.vote && card.vote.question !== '') {
let positiveVoters = '';
@ -343,7 +362,7 @@ export class Exporter {
if (field.value !== null) {
if (customFieldMap[field._id].type === 'date') {
customFieldValuesToPush[customFieldMap[field._id].position] =
moment(field.value).format();
new Date(field.value).toISOString();
} else if (customFieldMap[field._id].type === 'dropdown') {
const dropdownOptions = result.customFields.find(
({ _id }) => _id === field._id,

View file

@ -1,6 +1,26 @@
import { ReactiveCache } from '/imports/reactiveCache';
// exporter maybe is broken since Gridfs introduced, add fs and path
import { createWorkbook } from './createWorkbook';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
class ExporterCardPDF {
constructor(boardId) {
@ -353,8 +373,8 @@ class ExporterCardPDF {
//add data +8 hours
function addTZhours(jdate) {
const curdate = new Date(jdate);
const checkCorrectDate = moment(curdate);
if (checkCorrectDate.isValid()) {
const checkCorrectDate = new Date(curdate);
if (isValidDate(checkCorrectDate)) {
return curdate;
} else {
return ' ';

View file

@ -1,7 +1,26 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import { createWorkbook } from './createWorkbook';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
// exporter maybe is broken since Gridfs introduced, add fs and path
@ -379,8 +398,8 @@ class ExporterExcel {
function addTZhours(jdate) {
if (!jdate) { return ' '; }
const curdate = new Date(jdate);
const checkCorrectDate = moment(curdate);
if (checkCorrectDate.isValid()) {
const checkCorrectDate = new Date(curdate);
if (isValidDate(checkCorrectDate)) {
return curdate;
} else {
return ' ';

View file

@ -1,10 +1,29 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import { TAPi18n } from '/imports/i18n';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
const DateString = Match.Where(function(dateAsString) {
check(dateAsString, String);
return moment(dateAsString, moment.ISO_8601).isValid();
return isValidDate(new Date(dateAsString));
});
export class TrelloCreator {

View file

@ -1,9 +1,28 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
const DateString = Match.Where(function(dateAsString) {
check(dateAsString, String);
return moment(dateAsString, moment.ISO_8601).isValid();
return isValidDate(new Date(dateAsString));
});
export class WekanCreator {

View file

@ -47,7 +47,6 @@
"markdown-it-mathjax3": "^4.3.2",
"meteor-accounts-t9n": "^2.6.0",
"meteor-node-stubs": "^1.2.24",
"moment": "^2.30.1",
"os": "^0.1.2",
"papaparse": "^5.5.3",
"pretty-ms": "^7.0.1",

View file

@ -1,7 +1,26 @@
import { ReactiveCache } from '/imports/reactiveCache';
import moment from 'moment/min/moment-with-locales';
import escapeForRegex from 'escape-string-regexp';
import Users from '../../models/users';
import {
formatDateTime,
formatDate,
formatTime,
getISOWeek,
isValidDate,
isBefore,
isAfter,
isSame,
add,
subtract,
startOf,
endOf,
format,
parseDate,
now,
createDate,
fromNow,
calendar
} from '/imports/lib/dateUtils';
import Boards from '../../models/boards';
import Lists from '../../models/lists';
import Swimlanes from '../../models/swimlanes';
@ -730,9 +749,7 @@ function findCards(sessionId, query) {
userId,
modifiedAt: {
$lt: new Date(
moment()
.subtract(1, 'day')
.format(),
subtract(now(), 1, 'day').toISOString(),
),
},
});