nocobase/packages/core/utils/src/date.ts
被雨水过滤的空气-Rairn fd36c970bc
refactor(client)!: upgrade antd to v5 (#2078)
* refactor: change moment to dayjs

* refactor: remove antd css

* refactor: change @formily/antd to @formily/antd-v5

* chore: add dep

* chore: upgrade babel/core and typescript

* refactor: rename moment to dayjs

* fix(dayjs): add plugins

* refactor: fix type errors

* refactor: change default export to named export

* chore: upgrade ts-loader

* refactor: rename moment to dayjs

* refactor: fix type errors

* chore: upgrade deps for build

* fix: fix build errors

* fix: add antd reset css

* fix: fix build error

* chore: add __builtins__

* chore: optimize genStyleHook

* refactor(Calendar): less to css-in-js

* refactor(acl): less to css-in-js

* refactor(board): less to css-in-js

* chore: add antd-style

* refactor(acl): use antd-style

* refactor(board): use antd-style

* refactor: schema-initializer

* refactor: refactor genStyleHook

* refactor: kanban

* refactor: filter

* refactor: upload

* refactor: markdown

* refactor: rename className to componentCls

* refactor: rich-text

* style: fix style

* fix: fix merge error

* chore: update yarn.lock

* chore: upgrade formily

* style: fix pageHeader

* style: fix add button style

* style: fix header menu color

* chore: update yarn.lock

* chore: upgrade deps

* test: fix tests

* test: fix tests

* fix: fix build error

* fix: fix style of plugin doc

* fix: fix tests

* fix: fix drag bug

* refactor: remove useless code

* fix: fix Modal style (T-621)

* fix: fix box-shadow of subMenu (T-622)

* fix: fix style of linkage rules (T-623)

* fix: fix style of DataTemplate

* fix: fix style of variable (T-620)

* chore: update yarn.lock

* fix: avoid test failed

* test: fix error

* chore: update yarn.lock

* test: fix error

* test(dayjs): fix error

* fix: should delay show menu to avoid the menu not hidden

* test: skip failure test

* fix(mouseEnterDelay): change default value from 100 to 150

* test: avoid failed

* refactor: rename component names

* chore: optimize types

* chore: lock antd version

* fix: fix build

* fix: fix build

* fix: layout bg color use variable

* fix: fix style of buttons

* feat: remove theme config

* fix(calendar): fix style

* fix(mobile-client): fix dialog style

* fix: fix test

* refactor: make code gooder

* chore: change code

* fix: fix T-847

* fix: fix T-845

* fix: display block

* fix: danger button

* refactor: make tester better

* fix: change moment to dayjs

* fix: build error

* fix: import dayjs/plugin/isSameOrBefore

* refactor: downgrade @testing-library/react to fix warning

* fix: fix CI

* fix: upgrade deps to fix build

* fix: fix test

* fix: skip some filed tests to avoid error

* fix: fix build errors that maked by merge code

* refactor: remove moment

* fix: error

* feat: update doc

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
2023-07-08 08:26:27 +08:00

179 lines
4.4 KiB
TypeScript

import _ from 'lodash';
import { dayjs } from './dayjs';
export interface Str2momentOptions {
gmt?: boolean;
picker?: 'year' | 'month' | 'week' | 'quarter';
utcOffset?: any;
utc?: boolean;
}
export const getDefaultFormat = (props: any) => {
if (props.format) {
return props.format;
}
if (props.dateFormat) {
if (props['showTime']) {
return `${props.dateFormat} ${props.timeFormat || 'HH:mm:ss'}`;
}
return props.dateFormat;
}
if (props['picker'] === 'month') {
return 'YYYY-MM';
} else if (props['picker'] === 'quarter') {
return 'YYYY-\\QQ';
} else if (props['picker'] === 'year') {
return 'YYYY';
} else if (props['picker'] === 'week') {
return 'YYYY-wo';
}
return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
};
export const toGmt = (value: dayjs.Dayjs) => {
if (!value || !dayjs.isDayjs(value)) {
return value;
}
return `${value.format('YYYY-MM-DD')}T${value.format('HH:mm:ss.SSS')}Z`;
};
export const toLocal = (value: dayjs.Dayjs) => {
if (!value) {
return value;
}
if (Array.isArray(value)) {
return value.map((val) => val.startOf('second').toISOString());
}
if (dayjs.isDayjs(value)) {
return value.startOf('second').toISOString();
}
};
const toMoment = (val: any, options?: Str2momentOptions) => {
if (!val) {
return;
}
const offset = options.utcOffset || -1 * new Date().getTimezoneOffset();
const { gmt, picker, utc = true } = options;
if (!utc) {
return dayjs(val);
}
if (dayjs.isDayjs(val)) {
return val.utcOffset(offsetFromString(offset));
}
if (gmt || picker) {
return dayjs(val).utcOffset(0);
}
return dayjs(val).utcOffset(offsetFromString(offset));
};
export const str2moment = (value?: string | string[], options: Str2momentOptions = {}): any => {
return Array.isArray(value)
? value.map((val) => {
return toMoment(val, options);
})
: value
? toMoment(value, options)
: value;
};
const toStringByPicker = (value, picker) => {
if (picker === 'year') {
return value.format('YYYY') + '-01-01T00:00:00.000Z';
}
if (picker === 'month') {
return value.format('YYYY-MM') + '-01T00:00:00.000Z';
}
if (picker === 'quarter') {
return value.format('YYYY-MM') + '-01T00:00:00.000Z';
}
if (picker === 'week') {
return value.format('YYYY-MM-DD') + 'T00:00:00.000Z';
}
return value.format('YYYY-MM-DD') + 'T00:00:00.000Z';
};
const toGmtByPicker = (value: dayjs.Dayjs | dayjs.Dayjs[], picker?: any) => {
if (!value) {
return value;
}
if (Array.isArray(value)) {
return value.map((val) => toStringByPicker(val, picker));
}
if (dayjs.isDayjs(value)) {
return toStringByPicker(value, picker);
}
};
export interface Moment2strOptions {
showTime?: boolean;
gmt?: boolean;
picker?: 'year' | 'month' | 'week' | 'quarter';
}
export const moment2str = (value?: dayjs.Dayjs, options: Moment2strOptions = {}) => {
const { showTime, gmt, picker } = options;
if (!value) {
return value;
}
if (showTime) {
return gmt ? toGmt(value) : toLocal(value);
}
return toGmtByPicker(value, picker);
};
/**
* from https://github.com/moment/moment/blob/dca02edaeceda3fcd52b20b51c130631a058a022/src/lib/units/offset.js#L55-L70
*/
export function offsetFromString(string: string | number) {
if (!_.isString(string)) {
return string;
}
// timezone chunker
// '+10:00' > ['10', '00']
// '-1530' > ['-15', '30']
const chunkOffset = /([+-]|\d\d)/gi;
const matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
let matches = (string || '').match(matchShortOffset);
if (matches === null) {
matches = (string || '').match(matchTimestamp);
}
if (matches === null) {
return null;
}
const chunk = matches[matches.length - 1] || [];
const parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
const minutes = +(Number(parts[1]) * 60) + toInt(parts[2]);
return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
}
function toInt(argumentForCoercion) {
// eslint-disable-next-line prefer-const
let coercedNumber = +argumentForCoercion,
value = 0;
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
value = absFloor(coercedNumber);
}
return value;
}
function absFloor(number) {
if (number < 0) {
// -0 -> 0
return Math.ceil(number) || 0;
} else {
return Math.floor(number);
}
}