From 03847f518e6f40cb7cb57c3e06c46701493fa7a3 Mon Sep 17 00:00:00 2001 From: Yehor Date: Thu, 8 Dec 2022 14:55:20 +0200 Subject: [PATCH 01/10] change moment to dayjs in date.util.js and remove unused methods --- package.json | 1 + src/js/utils/date.util.js | 78 ++++----------------------------------- yarn.lock | 5 +++ 3 files changed, 13 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index 0a82d548a..9b9dda0ec 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "d3-selection": "^1.4.1", "d3-shape": "^1.3.7", "d3-transition": "^1.3.2", + "dayjs": "^1.11.6", "detect-browser": "5.1.0", "eslint-loader": "^3.0.3", "eslint-plugin-chai-friendly": "^0.5.0", diff --git a/src/js/utils/date.util.js b/src/js/utils/date.util.js index 2249d1bb0..fec1bfade 100644 --- a/src/js/utils/date.util.js +++ b/src/js/utils/date.util.js @@ -1,87 +1,23 @@ -import moment from 'moment' +import dayjs from 'dayjs' +import customParseFormat from 'dayjs/plugin/customParseFormat' -const INPUT_DATE_FORMAT = 'DD/MM/YYYY' +dayjs.extend(customParseFormat) export class DateUtil { - static get ISOFormat () { - return 'YYYY-MM-DDT00:00:00+00:00' - } - - /** - * Returns minimum acceptable date for the app - * @returns {string} - */ - static get minDate () { - return this.toISO('01/01/1900') + static _dayjs (date, format) { + return format ? dayjs(date, format) : dayjs(date) } /** formatters: **/ - /** - * Returns provided date in human-friendly format - * @param {string|date} date - date to format - * @param {string|null} [format] - if date is provided in custom unknown - * format - * @returns {string} - */ - static toHuman (date, format = null) { - return this._moment(date, format).calendar(null, { - sameDay: '[Today at] HH:mm', - lastDay: '[Yesterday at] HH:mm', - lastWeek: '[Last] dddd [at] HH:mm', - nextWeek: '[Next] dddd [at] HH:mm', - sameElse: 'DD/MM/YYYY', - }) - } - - /** - * Returns provided date in ISO format - * @param {string|date} date - date to format - * @param {string|null} [format] - if date is provided in custom unknown - * format - * @returns {string} - */ - static toISO (date, format = null) { - return this._moment(date, format).format(this.ISOFormat) - } - /** * Returns provided date in UNIX timestamp (in seconds) * @param {string|date} date - date to format * @param {string|null} [format] - if date is provided in custom unknown - * ormat - * @returns {string} - */ - static toTimestamp (date, format = null) { - return this._moment(date, format).format('X') - } - - /** - * Returns provided date in miliseconds - * @param {string|date} date - date to format - * @param {string|null} [format] - if date is provided in custom unknown - * format - * @returns {string} - */ - static toMs (date, format = null) { - return this._moment(date, format).format('x') - } - - /** - * Returns provided date in input format - * @param {string|date} date - date to format - * @param {string|null} [format] - if date is provided in custom unknown * format * @returns {string} */ - static toInput (date, format = null) { - return this._moment(date, format).format(INPUT_DATE_FORMAT) - } - - static _moment (date, format) { - if (format) { - return moment(date, format) - } - return moment(date) + static toTimestamp (date, format = null) { + return this._dayjs(date, format).unix() } } diff --git a/yarn.lock b/yarn.lock index 40b65b5d7..8050c6ca2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3499,6 +3499,11 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +dayjs@^1.11.6: + version "1.11.6" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.6.tgz#2e79a226314ec3ec904e3ee1dd5a4f5e5b1c7afb" + integrity sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ== + de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" From 4ce1c95be35ddd42ea74760d1f535bb714e89b60 Mon Sep 17 00:00:00 2001 From: Yehor Date: Fri, 9 Dec 2022 03:48:21 +0200 Subject: [PATCH 02/10] replaced not wrapped date methods by new methods in date.util.js, replaced momentjs by dayjs --- src/js/const/date-locales.const.js | 5 + src/js/formers/KycGeneralFormer.js | 4 +- src/js/helpers/date-helpers.js | 19 -- src/js/records/entities/poll.record.js | 8 +- src/js/records/entities/sale.record.js | 10 +- src/js/utils/date.util.js | 224 +++++++++++++++++- src/main.js | 4 +- src/validators.js | 7 +- src/vue/common/TimeoutTicker.vue | 20 +- src/vue/common/chart/Chart.Renderer.vue | 24 +- src/vue/fields/DateField.vue | 10 +- src/vue/forms/CreatePollForm.vue | 10 +- .../DepositForm/components/AddressLoader.vue | 7 +- .../components/InformationStepForm.vue | 16 +- .../wrappers/atomic-swap-bid.record.js | 5 +- .../components/coinpayments-form.vue | 5 +- .../wrappers/issuance.record.js | 5 +- .../pages/polls-all/PollUpdateEndTimeForm.vue | 17 +- src/vuex/idle-handler.module.js | 6 +- 19 files changed, 308 insertions(+), 98 deletions(-) create mode 100644 src/js/const/date-locales.const.js delete mode 100644 src/js/helpers/date-helpers.js diff --git a/src/js/const/date-locales.const.js b/src/js/const/date-locales.const.js new file mode 100644 index 000000000..713380464 --- /dev/null +++ b/src/js/const/date-locales.const.js @@ -0,0 +1,5 @@ +import ru from 'dayjs/locale/ru' + +export const LOCALES = Object.freeze({ + ru, +}) diff --git a/src/js/formers/KycGeneralFormer.js b/src/js/formers/KycGeneralFormer.js index 805833836..a0e85f55e 100644 --- a/src/js/formers/KycGeneralFormer.js +++ b/src/js/formers/KycGeneralFormer.js @@ -5,9 +5,9 @@ import { KycGeneralRecord } from '@/js/records/entities/kyc-general.record' import { KycRequestRecord } from '@/js/records/requests/kyc-request.record' import { KycRecoveryRequestRecord } from '@/js/records/requests/kyc-recovery-request.record' import { BlobRecord } from '@/js/records/entities/blob.record' -import { toRFC3339 } from '@/js/helpers/date-helpers' import { createPrivateBlob, getCurrentAccId } from '@/js/helpers/api-helpers' import { isUSResidence, buildKycRecoveryOp } from '@/js/helpers/kyc-helpers' +import { DateUtil } from '@/js/utils' import { keyValues } from '@/key-values' import get from 'lodash/get' @@ -150,7 +150,7 @@ export class KycGeneralFormer extends Former { const blobValue = JSON.stringify({ first_name: str(attrs.firstName), last_name: str(attrs.lastName), - date_of_birth: toRFC3339(attrs.dateOfBirth), + date_of_birth: DateUtil.toRFC3339(attrs.dateOfBirth), address: { line_1: str(address.line1), line_2: str(address.line2), diff --git a/src/js/helpers/date-helpers.js b/src/js/helpers/date-helpers.js deleted file mode 100644 index acbc69aaa..000000000 --- a/src/js/helpers/date-helpers.js +++ /dev/null @@ -1,19 +0,0 @@ -import moment from 'moment' - -export function toRFC3339 (date) { - if (!date) { - return '' - } - - // moment don't allow you to format date with "Z" in the end instead of - // the timezone - return moment(date).format('YYYY-MM-DDTHH:mm:ss') + 'Z' -} - -export function fromRFC3339 (date) { - if (!date) { - return '' - } - - return moment(date).format('YYYY-MM-DD') -} diff --git a/src/js/records/entities/poll.record.js b/src/js/records/entities/poll.record.js index d52444553..6a47eb554 100644 --- a/src/js/records/entities/poll.record.js +++ b/src/js/records/entities/poll.record.js @@ -1,5 +1,5 @@ -import moment from 'moment' import _get from 'lodash/get' +import { DateUtil } from '@/js/utils' const STATES = Object.freeze({ open: 1, @@ -52,16 +52,16 @@ export class PollRecord { } get isStarted () { - return moment().isSameOrAfter(this.startsAt) + return DateUtil.isSameOrAfter(undefined, this.startsAt) } get isEnded () { - return moment().isSameOrAfter(this.endsAt) + return DateUtil.isSameOrAfter(undefined, this.endsAt) } get isInProgress () { return this.isOpen && - moment().isBetween(this.startsAt, this.endsAt) + DateUtil.isBetween(undefined, this.startsAt, this.endsAt) } static get states () { diff --git a/src/js/records/entities/sale.record.js b/src/js/records/entities/sale.record.js index a03c67d46..edc2b1c34 100644 --- a/src/js/records/entities/sale.record.js +++ b/src/js/records/entities/sale.record.js @@ -1,7 +1,7 @@ -import moment from 'moment' import _get from 'lodash/get' import { SALE_DEFINITION_TYPES } from '@/js/const/sale-definition-types.const' +import { DateUtil } from '@/js/utils' const STATES = { Open: 1, @@ -114,16 +114,16 @@ export class SaleRecord { get isOpened () { return this._isInState(STATES.Open) } get isClosed () { return this._isInState(STATES.Closed) } get isCanceled () { return this._isInState(STATES.Canceled) } - get isUpcoming () { return moment(this.startTime).isAfter(moment()) } + get isUpcoming () { return DateUtil.isAfter(this.startTime) } /** progress info: **/ get daysToGo () { - return moment(this.startTime).diff(moment(), 'days') + return DateUtil.diff(this.startTime, undefined, 'days') } get daysToEnd () { - return moment(this.endTime).diff(moment(), 'days') + return DateUtil.diff(this.endTime, undefined, 'days') } get daysAfterEnd () { @@ -135,7 +135,7 @@ export class SaleRecord { } get startsIn () { - return moment(this.startTime).diff(moment().startOf('day'), 'days') + return DateUtil.diff(this.startTime, DateUtil.startOf('day'), 'days') } get hardCapProgress () { diff --git a/src/js/utils/date.util.js b/src/js/utils/date.util.js index fec1bfade..d49e2b4f0 100644 --- a/src/js/utils/date.util.js +++ b/src/js/utils/date.util.js @@ -1,23 +1,241 @@ import dayjs from 'dayjs' +import utc from 'dayjs/plugin/utc' +import duration from 'dayjs/plugin/duration' import customParseFormat from 'dayjs/plugin/customParseFormat' +import isSameOrAfter from 'dayjs/plugin/isSameOrAfter' +import isBetween from 'dayjs/plugin/isBetween' +import { LOCALES } from '@/js/const/date-locales.const' + +dayjs.extend(utc) +dayjs.extend(duration) dayjs.extend(customParseFormat) +dayjs.extend(isSameOrAfter) +dayjs.extend(isBetween) export class DateUtil { static _dayjs (date, format) { return format ? dayjs(date, format) : dayjs(date) } + /** + * Returns date instance of DateUtil + * @param {string|date|object} [date] - date + * @param {string} [format] - if date is provided in custom unknown + * format + * @returns {object} + */ + static date (date, format) { + return this._dayjs(date, format) + } + + /** + * Returns date instance of DateUtil in utc mode + * The local time will be kept + * @param {string|date|object} [date] - date + * @param {string} [format] - if date is provided in custom unknown + * format + * @returns {object} + */ + static utc (date, format) { + return this._dayjs(date, format).utc(true) + } + + /** + * Returns new duration instance of DateUtil + * @param {object} units - config with units as keys + * @returns {object} + */ + static duration (units) { + return dayjs.duration(units) + } + + /** + * Returns milliseconds of duration instance of DateUtil + * @param {object} duration - duration instance + * @returns {number} + */ + static millisecondOf (duration) { + return duration.asMilliseconds() + } + /** formatters: **/ + /** + * Returns date in given format + * @param {string|date|object} date - date to format + * @param {string} format - format, e.g. 'MM-DD-YYYY HH:mm:ss' + * @returns {string} + */ + static format (date, format) { + return this._dayjs(date).format(format) + } + /** * Returns provided date in UNIX timestamp (in seconds) - * @param {string|date} date - date to format - * @param {string|null} [format] - if date is provided in custom unknown + * @param {string|date|object} [date] - date to format + * @param {string} [format] - if date is provided in custom unknown * format * @returns {string} */ - static toTimestamp (date, format = null) { + static toTimestamp (date, format) { return this._dayjs(date, format).unix() } + + /** + * Return instance of the native Date object + * @param {string|date|object} [date] - date to format + * @param {string} [format] - if date is provided in custom unknown + * format + * @returns {date} + */ + static toDate (date, format) { + return this._dayjs(date, format).toDate() + } + + /** + * Returns date as string in ISO 8601 utc format + * @param {string|date|object} [date] - date to format + * @param {string} [format] - if date is provided in custom unknown + * format + * @returns {string} + */ + static toISO (date, format) { + return this._dayjs(date, format).toISOString() + } + + /** + * Returns utc date as string in RFC 3399 utc format + * The local time will be kept + * @param {string|date|object} [date] - date to format + * @returns {object} + */ + static toRFC3339 (date) { + if (!date) { + return '' + } + + return this._dayjs(date).utc(true).format('YYYY-MM-DDTHH:mm:ss') + 'Z' + } + + /** + * Returns the difference between two date-time in the specified unit + * Default: returns difference in the milliseconds + * @param {string|number|date|object} [targetDate] - target date + * @param {string|number|date|object} [comparisonDate] - comparison date + * @param {string} [unit] - string of unit time (e.g. 'year') + * @param {boolean} [isFloat] - set it if you want a floating point number + * @returns {number} + */ + static diff (targetDate, comparisonDate, unit, isFloat = false) { + return this._dayjs(targetDate).diff( + this._dayjs(comparisonDate), unit, isFloat + ) + } + + /** queries: **/ + + /** + * Returns true/false depending on whether the target date is earlier than the + * comparison date + * @param {string|number|date|object} [targetDate] - target date + * @param {string|number|date|object} [comparisonDate] - comparison date + * @returns {boolean} + */ + static isBefore (targetDate, comparisonDate) { + return this._dayjs(targetDate).isBefore(comparisonDate) + } + + /** + * Returns true/false depending on whether the target date is later than the + * comparison date + * @param {string|number|date|object} [targetDate] - target date + * @param {string|number|date|object} [comparisonDate] - comparison date + * @returns {boolean} + */ + static isAfter (targetDate, comparisonDate) { + return this._dayjs(targetDate).isAfter(comparisonDate) + } + + /** + * Returns true/false depending on whether the target date is same or is later + * than the comparsion date + * @param {string|number|date|object} [targetDate] - target date + * @param {string|number|date|object} [comparisonDate] - comparison date + * @returns {boolean} + */ + static isSameOrAfter (targetDate, comparisonDate) { + return this._dayjs(targetDate).isSameOrAfter(comparisonDate) + } + + /** + * Returns true/false depending on whether the target date is in the given + * range + * @param {string|number|date|object} [targetDate] - target date + * @param {string|number|date|object} [startDate] - start date of range + * @param {string|number|date|object} [endDate] - end date of range + * @param {string} [unit] - string of unit time (e.g. 'year') + * @param {string} [inclusivity] - inclusivity, e.g. + * '()' or '[)' or '(]' or '[]' + * @returns {boolean} + */ + static isBetween (targetDate, startDate, endDate, unit, inclusivity) { + return this._dayjs(targetDate).isBetween( + startDate, endDate, unit, inclusivity + ) + } + + /** manipulations: **/ + + /** + * Returns a cloned instance of DateUtil and set it to the start of a unit + * of time + * @param {string} unit - string of unit time (e.g. 'year') + * @param {string|number|date|object} [date] - date to manipulate + * @param {string} [format] - if date is provided in custom unknown + * format + * @returns {object} + */ + static startOf (unit, date, format) { + return this._dayjs(date, format).startOf(unit) + } + + /** + * Returns a new date instance of DateUtil by adding time unit to date + * @param {string|number|date|object} targetDate - target date + * @param {number} value - amount of time unit + * @param {string} [unit] - string of unit time (e.g. 'year') + * @returns {object} + */ + static add (targetDate, value, unit) { + return this._dayjs(targetDate).add(value, unit) + } + + /** + * Returns a new date instance of DateUtil by subtracting time unit from date + * @param {string|number|date|object} targetDate - target date + * @param {number} value - amount of time unit + * @param {string} [unit] - string of unit time (e.g. 'year') + * @returns {object} + */ + static subtract (targetDate, value, unit) { + return this._dayjs(targetDate).subtract(value, unit) + } + + /** + * Sets a new locale and returns the name of new locale + * @param {string|object} [preset] - a name of the new locale to set + * the locale from a preset, or an object with its own locale properties + * @param {object} [object] - object with own locale properties in case + * if name of locale defined by first parameter + * @param {boolean} [isLocal] + * @returns {string} + */ + static locale (preset, object, isLocal = false) { + if (typeof preset === 'string') { + return dayjs.locale(LOCALES[preset]) + } + + return dayjs.locale(preset, object, isLocal) + } } diff --git a/src/main.js b/src/main.js index c03325c6b..79a0b26b3 100644 --- a/src/main.js +++ b/src/main.js @@ -8,7 +8,6 @@ import VueHead from 'vue-head' import log from 'loglevel' import config from './config' import NProgress from 'nprogress' -import moment from 'moment' import router from '@/vue-router' import { buildStore } from '@/vuex' @@ -29,6 +28,7 @@ import { formatDateDMYT } from '@/vue/filters/formatDateDMYT' import { abbreviate } from '@/vue/filters/abbreviate' import { cropAddress } from '@/vue/filters/cropAddress' import { ErrorTracker } from '@/js/helpers/error-tracker' +import { DateUtil } from '@/js/utils' import { vueRoutes } from './vue-router/routes' import { useBrowserUpdateBanner } from './browser-update' import { keyValues } from '@/key-values' @@ -41,7 +41,7 @@ async function init () { await initApi() await keyValues.load() - i18n.onLanguageChanged(lang => moment.locale(lang)) + i18n.onLanguageChanged(lang => DateUtil.locale(lang)) await i18n.init() log.setDefaultLevel(config.LOG_LEVEL) diff --git a/src/validators.js b/src/validators.js index 127b7d895..c53c3b983 100644 --- a/src/validators.js +++ b/src/validators.js @@ -1,12 +1,11 @@ import WAValidator from 'wallet-address-validator' -import moment from 'moment' import iban from 'iban' import cardValidator from 'card-validator' import _isString from 'lodash/isString' import { base, Document } from '@tokend/js-sdk' -import { MathUtil } from '@/js/utils' +import { MathUtil, DateUtil } from '@/js/utils' import * as validators from 'vuelidate/lib/validators' @@ -35,10 +34,10 @@ export const amountRange = (from, to) => value => MathUtil.compare(to, value) >= 0 ) export const minDate = (minDate) => value => { - return moment(value).isAfter(moment(minDate)) + return DateUtil.isAfter(value, minDate) } export const maxDate = (maxDate) => value => { - return moment(value).isBefore(moment(maxDate)) + return DateUtil.isBefore(value, maxDate) } export const address = (asset) => value => { switch (asset) { diff --git a/src/vue/common/TimeoutTicker.vue b/src/vue/common/TimeoutTicker.vue index 61ac6f49d..fe6bcd6db 100644 --- a/src/vue/common/TimeoutTicker.vue +++ b/src/vue/common/TimeoutTicker.vue @@ -11,7 +11,7 @@