utc 逻辑整理, 只存储用 utc,显示还是当地时间

This commit is contained in:
2betop 2020-02-21 21:20:26 +08:00
parent 1e63764b3b
commit 8c4e8cb543
5 changed files with 146 additions and 152 deletions

View File

@ -211,8 +211,6 @@ export interface DateProps {
disabled?: boolean;
minDate?: moment.Moment;
maxDate?: moment.Moment;
minTime?: moment.Moment;
maxTime?: moment.Moment;
clearable?: boolean;
defaultValue?: any;
utc?: boolean;

View File

@ -4,18 +4,18 @@
* @author fex
*/
import React = require("react");
import moment = require("moment");
import { findDOMNode } from "react-dom";
import cx from "classnames";
import { Icon } from "./icons";
import Overlay from "./Overlay";
import { ShortCuts, ShortCutDateRange } from "./DatePicker";
import Calendar from "./calendar/Calendar";
import PopOver from "./PopOver";
import { ClassNamesFn, themeable } from "../theme";
import { PlainObject } from "../types";
import { noop } from "../utils/helper";
import React = require('react');
import moment = require('moment');
import {findDOMNode} from 'react-dom';
import cx from 'classnames';
import {Icon} from './icons';
import Overlay from './Overlay';
import {ShortCuts, ShortCutDateRange} from './DatePicker';
import Calendar from './calendar/Calendar';
import PopOver from './PopOver';
import {ClassNamesFn, themeable} from '../theme';
import {PlainObject} from '../types';
import {noop} from '../utils/helper';
export interface DateRangePickerProps {
className?: string;
@ -24,6 +24,7 @@ export interface DateRangePickerProps {
placeholder?: string;
theme?: any;
format: string;
utc?: boolean;
inputFormat?: string;
ranges?: string | Array<ShortCuts>;
clearable?: boolean;
@ -48,110 +49,110 @@ export interface DateRangePickerState {
endDate?: moment.Moment;
}
const availableRanges: { [propName: string]: any } = {
today: {
label: "今天",
const availableRanges: {[propName: string]: any} = {
'today': {
label: '今天',
startDate: (now: moment.Moment) => {
return now.startOf("day");
return now.startOf('day');
},
endDate: (now: moment.Moment) => {
return now;
}
},
yesterday: {
label: "昨天",
'yesterday': {
label: '昨天',
startDate: (now: moment.Moment) => {
return now.add(-1, "days").startOf("day");
return now.add(-1, 'days').startOf('day');
},
endDate: (now: moment.Moment) => {
return now.add(-1, "days").endOf("day");
return now.add(-1, 'days').endOf('day');
}
},
"1dayago": {
label: "最近1天",
'1dayago': {
label: '最近1天',
startDate: (now: moment.Moment) => {
return now.add(-1, "days");
return now.add(-1, 'days');
},
endDate: (now: moment.Moment) => {
return now;
}
},
"7daysago": {
label: "最近7天",
'7daysago': {
label: '最近7天',
startDate: (now: moment.Moment) => {
return now.add(-7, "days").startOf("day");
return now.add(-7, 'days').startOf('day');
},
endDate: (now: moment.Moment) => {
return now.add(-1, "days").endOf("day");
return now.add(-1, 'days').endOf('day');
}
},
"90daysago": {
label: "最近90天",
'90daysago': {
label: '最近90天',
startDate: (now: moment.Moment) => {
return now.add(-90, "days").startOf("day");
return now.add(-90, 'days').startOf('day');
},
endDate: (now: moment.Moment) => {
return now.add(-1, "days").endOf("day");
return now.add(-1, 'days').endOf('day');
}
},
prevweek: {
label: "上周",
'prevweek': {
label: '上周',
startDate: (now: moment.Moment) => {
return now.startOf("week").add(-1, "weeks");
return now.startOf('week').add(-1, 'weeks');
},
endDate: (now: moment.Moment) => {
return now
.startOf("week")
.add(-1, "days")
.endOf("day");
.startOf('week')
.add(-1, 'days')
.endOf('day');
}
},
thismonth: {
label: "本月",
'thismonth': {
label: '本月',
startDate: (now: moment.Moment) => {
return now.startOf("month");
return now.startOf('month');
},
endDate: (now: moment.Moment) => {
return now;
}
},
prevmonth: {
label: "上个月",
'prevmonth': {
label: '上个月',
startDate: (now: moment.Moment) => {
return now.startOf("month").add(-1, "month");
return now.startOf('month').add(-1, 'month');
},
endDate: (now: moment.Moment) => {
return now
.startOf("month")
.add(-1, "day")
.endOf("day");
.startOf('month')
.add(-1, 'day')
.endOf('day');
}
},
prevquarter: {
label: "上个季节",
'prevquarter': {
label: '上个季节',
startDate: (now: moment.Moment) => {
return now.startOf("quarter").add(-1, "quarter");
return now.startOf('quarter').add(-1, 'quarter');
},
endDate: (now: moment.Moment) => {
return now
.startOf("quarter")
.add(-1, "day")
.endOf("day");
.startOf('quarter')
.add(-1, 'day')
.endOf('day');
}
},
thisquarter: {
label: "本季度",
'thisquarter': {
label: '本季度',
startDate: (now: moment.Moment) => {
return now.startOf("quarter");
return now.startOf('quarter');
},
endDate: (now: moment.Moment) => {
return now;
@ -164,17 +165,17 @@ export class DateRangePicker extends React.Component<
DateRangePickerState
> {
static defaultProps = {
placeholder: "请选择日期范围",
format: "X",
inputFormat: "YYYY-MM-DD",
placeholder: '请选择日期范围',
format: 'X',
inputFormat: 'YYYY-MM-DD',
joinValues: true,
clearable: true,
delimiter: ",",
ranges: "yesterday,7daysago,prevweek,thismonth,prevmonth,prevquarter",
iconClassName: "fa fa-calendar",
resetValue: "",
delimiter: ',',
ranges: 'yesterday,7daysago,prevweek,thismonth,prevmonth,prevquarter',
iconClassName: 'fa fa-calendar',
resetValue: '',
closeOnSelect: true,
overlayPlacement: "auto"
overlayPlacement: 'auto'
};
innerDom: any;
@ -185,11 +186,14 @@ export class DateRangePicker extends React.Component<
newValue: any,
format: string,
joinValues: boolean,
delimiter: string
delimiter: string,
utc = false
) {
newValue = [
newValue.startDate.format(format),
newValue.endDate.format(format)
(utc ? moment.utc(newValue.startDate) : newValue.startDate).format(
format
),
(utc ? moment.utc(newValue.endDate) : newValue.endDate).format(format)
];
if (joinValues) {
@ -212,7 +216,7 @@ export class DateRangePicker extends React.Component<
};
}
if (joinValues && typeof value === "string") {
if (joinValues && typeof value === 'string') {
value = value.split(delimiter);
}
@ -223,7 +227,7 @@ export class DateRangePicker extends React.Component<
}
dom: React.RefObject<HTMLDivElement>;
nextMonth = moment().add(1, "months");
nextMonth = moment().add(1, 'months');
constructor(props: DateRangePickerProps) {
super(props);
@ -243,7 +247,7 @@ export class DateRangePicker extends React.Component<
this.handleKeyPress = this.handleKeyPress.bind(this);
this.handlePopOverClick = this.handlePopOverClick.bind(this);
this.renderDay = this.renderDay.bind(this);
const { format, joinValues, delimiter, value } = this.props;
const {format, joinValues, delimiter, value} = this.props;
this.state = {
isOpened: false,
@ -254,7 +258,7 @@ export class DateRangePicker extends React.Component<
componentWillReceiveProps(nextProps: DateRangePickerProps) {
const props = this.props;
const { value, format, joinValues, delimiter } = nextProps;
const {value, format, joinValues, delimiter} = nextProps;
if (props.value !== value) {
this.setState({
@ -320,7 +324,7 @@ export class DateRangePicker extends React.Component<
}
handleKeyPress(e: React.KeyboardEvent) {
if (e.key === " ") {
if (e.key === ' ') {
this.handleClick();
}
}
@ -340,7 +344,8 @@ export class DateRangePicker extends React.Component<
},
this.props.format,
this.props.joinValues,
this.props.delimiter
this.props.delimiter,
this.props.utc
)
);
this.close();
@ -365,7 +370,7 @@ export class DateRangePicker extends React.Component<
handleEndChange(newValue: moment.Moment) {
newValue =
!this.state.endDate && !this.props.timeFormat
? newValue.endOf("day")
? newValue.endOf('day')
: newValue;
if (
@ -384,7 +389,7 @@ export class DateRangePicker extends React.Component<
}
selectRannge(range: PlainObject) {
const { closeOnSelect } = this.props;
const {closeOnSelect} = this.props;
const now = moment();
this.setState(
{
@ -399,10 +404,10 @@ export class DateRangePicker extends React.Component<
if (!ranges) {
return null;
}
const { classPrefix: ns } = this.props;
const {classPrefix: ns} = this.props;
let rangeArr: Array<string | ShortCuts>;
if (typeof ranges === "string") {
rangeArr = ranges.split(",");
if (typeof ranges === 'string') {
rangeArr = ranges.split(',');
} else {
rangeArr = ranges;
}
@ -413,7 +418,7 @@ export class DateRangePicker extends React.Component<
return null;
}
let range: PlainObject = {};
if (typeof item === "string") {
if (typeof item === 'string') {
range = availableRanges[item];
range.key = item;
} else if (
@ -443,15 +448,15 @@ export class DateRangePicker extends React.Component<
clearValue(e: React.MouseEvent<any>) {
e.preventDefault();
e.stopPropagation();
const { resetValue, onChange } = this.props;
const {resetValue, onChange} = this.props;
onChange(resetValue);
}
checkStartIsValidDate(currentDate: moment.Moment) {
let { endDate } = this.state;
let {endDate} = this.state;
let { minDate, maxDate } = this.props;
let {minDate, maxDate} = this.props;
maxDate =
maxDate && endDate
@ -460,9 +465,9 @@ export class DateRangePicker extends React.Component<
: endDate
: maxDate || endDate;
if (minDate && currentDate.isBefore(minDate, "day")) {
if (minDate && currentDate.isBefore(minDate, 'day')) {
return false;
} else if (maxDate && currentDate.isAfter(maxDate, "day")) {
} else if (maxDate && currentDate.isAfter(maxDate, 'day')) {
return false;
}
@ -470,9 +475,9 @@ export class DateRangePicker extends React.Component<
}
checkEndIsValidDate(currentDate: moment.Moment) {
let { startDate } = this.state;
let {startDate} = this.state;
let { minDate, maxDate } = this.props;
let {minDate, maxDate} = this.props;
minDate =
minDate && startDate
@ -481,9 +486,9 @@ export class DateRangePicker extends React.Component<
: startDate
: minDate || startDate;
if (minDate && currentDate.isBefore(minDate, "day")) {
if (minDate && currentDate.isBefore(minDate, 'day')) {
return false;
} else if (maxDate && currentDate.isAfter(maxDate, "day")) {
} else if (maxDate && currentDate.isAfter(maxDate, 'day')) {
return false;
}
@ -491,14 +496,14 @@ export class DateRangePicker extends React.Component<
}
renderDay(props: any, currentDate: moment.Moment) {
let { startDate, endDate } = this.state;
let {startDate, endDate} = this.state;
if (
startDate &&
endDate &&
currentDate.isBetween(startDate, endDate, "day", "[]")
currentDate.isBetween(startDate, endDate, 'day', '[]')
) {
props.className += " rdtBetween";
props.className += ' rdtBetween';
}
return <td {...props}>{currentDate.date()}</td>;
@ -513,6 +518,7 @@ export class DateRangePicker extends React.Component<
popOverContainer,
inputFormat,
format,
dateFormat,
joinValues,
delimiter,
clearable,
@ -523,7 +529,7 @@ export class DateRangePicker extends React.Component<
overlayPlacement
} = this.props;
const { isOpened, isFocused, startDate, endDate } = this.state;
const {isOpened, isFocused, startDate, endDate} = this.state;
const selectedDate = DateRangePicker.unFormatValue(
value,
@ -533,10 +539,10 @@ export class DateRangePicker extends React.Component<
);
const startViewValue = selectedDate.startDate
? selectedDate.startDate.format(inputFormat)
: "";
: '';
const endViewValue = selectedDate.endDate
? selectedDate.endDate.format(inputFormat)
: "";
: '';
const arr = [];
startViewValue && arr.push(startViewValue);
endViewValue && arr.push(endViewValue);
@ -550,8 +556,8 @@ export class DateRangePicker extends React.Component<
className={cx(
`${ns}DateRangePicker`,
{
"is-disabled": disabled,
"is-focused": isFocused
'is-disabled': disabled,
'is-focused': isFocused
},
className
)}
@ -560,7 +566,7 @@ export class DateRangePicker extends React.Component<
>
{arr.length ? (
<span className={`${ns}DateRangePicker-value`}>
{arr.join(" 至 ")}
{arr.join(' 至 ')}
</span>
) : (
<span className={`${ns}DateRangePicker-placeholder`}>
@ -602,7 +608,7 @@ export class DateRangePicker extends React.Component<
value={startDate}
onChange={this.handleStartChange}
requiredConfirm={false}
dateFormat={format}
dateFormat={dateFormat}
timeFormat={timeFormat}
isValidDate={this.checkStartIsValidDate}
viewMode="days"
@ -616,7 +622,7 @@ export class DateRangePicker extends React.Component<
value={endDate}
onChange={this.handleEndChange}
requiredConfirm={false}
dateFormat={format}
dateFormat={dateFormat}
timeFormat={timeFormat}
viewDate={this.nextMonth}
isEndDate
@ -629,8 +635,8 @@ export class DateRangePicker extends React.Component<
<div key="button" className={`${ns}DateRangePicker-actions`}>
<a
className={cx("rdtBtn rdtBtnConfirm", {
"is-disabled":
className={cx('rdtBtn rdtBtnConfirm', {
'is-disabled':
!this.state.startDate || !this.state.endDate
})}
onClick={this.confirm}

View File

@ -18,15 +18,11 @@ export interface DateProps extends FormControlProps {
utc?: boolean; // 设定是否存储 utc 时间。
minDate?: string;
maxDate?: string;
maxTime?: string;
minTime?: string;
}
interface DateControlState {
minDate?: moment.Moment;
maxDate?: moment.Moment;
minTime?: moment.Moment;
maxTime?: moment.Moment;
}
export default class DateControl extends React.PureComponent<
@ -50,9 +46,6 @@ export default class DateControl extends React.PureComponent<
const {
minDate,
maxDate,
maxTime,
minTime,
timeFormat,
value,
defaultValue,
setPrinstineValue,
@ -62,16 +55,13 @@ export default class DateControl extends React.PureComponent<
} = this.props;
if (defaultValue && value === defaultValue) {
setPrinstineValue(
filterDate(defaultValue, data, format, utc).format(format)
);
const date = filterDate(defaultValue, data, format);
setPrinstineValue((utc ? moment.utc(date) : date).format(format));
}
this.setState({
minDate: minDate ? filterDate(minDate, data, format, utc) : undefined,
maxDate: maxDate ? filterDate(maxDate, data, format, utc) : undefined,
minTime: minTime ? filterDate(minTime, data, timeFormat, utc) : undefined,
maxTime: maxTime ? filterDate(maxTime, data, timeFormat, utc) : undefined
minDate: minDate ? filterDate(minDate, data, format) : undefined,
maxDate: maxDate ? filterDate(maxDate, data, format) : undefined
});
}
@ -79,8 +69,13 @@ export default class DateControl extends React.PureComponent<
const props = this.props;
if (props.defaultValue !== nextProps.defaultValue) {
const date = filterDate(
nextProps.defaultValue,
nextProps.data,
nextProps.format
);
nextProps.setPrinstineValue(
filterDate(nextProps.defaultValue, nextProps.data)
(nextProps.utc ? moment.utc(date) : date).format(nextProps.format)
);
}
@ -89,23 +84,12 @@ export default class DateControl extends React.PureComponent<
props.maxDate !== nextProps.maxDate ||
props.data !== nextProps.data
) {
const utc = nextProps.utc;
this.setState({
minDate: nextProps.minDate
? filterDate(
nextProps.minDate,
nextProps.data,
this.props.format,
utc
)
? filterDate(nextProps.minDate, nextProps.data, this.props.format)
: undefined,
maxDate: nextProps.maxDate
? filterDate(
nextProps.maxDate,
nextProps.data,
this.props.format,
utc
)
? filterDate(nextProps.maxDate, nextProps.data, this.props.format)
: undefined
});
}

View File

@ -36,11 +36,11 @@ export default class DateRangeControl extends React.Component<
constructor(props: DateRangeProps) {
super(props);
const {minDate, maxDate, data} = props;
const {minDate, maxDate, data, format} = props;
this.state = {
minDate: minDate ? filterDate(minDate, data) : undefined,
maxDate: maxDate ? filterDate(maxDate, data) : undefined
minDate: minDate ? filterDate(minDate, data, format) : undefined,
maxDate: maxDate ? filterDate(maxDate, data, format) : undefined
};
}
@ -52,7 +52,8 @@ export default class DateRangeControl extends React.Component<
format,
data,
value,
joinValues
joinValues,
utc
} = this.props;
if (defaultValue && value === defaultValue) {
@ -63,19 +64,20 @@ export default class DateRangeControl extends React.Component<
setPrinstineValue(
BaseDateRangePicker.formatValue(
{
startDate: filterDate(arr[0], data),
endDate: filterDate(arr[1], data)
startDate: filterDate(arr[0], data, format),
endDate: filterDate(arr[1], data, format)
},
format,
joinValues,
delimiter
delimiter,
utc
)
);
}
}
componentWillReceiveProps(nextProps: DateRangeProps) {
const {data, minDate, maxDate} = nextProps;
const {data, minDate, maxDate, format} = nextProps;
const props = this.props;
if (
@ -84,8 +86,8 @@ export default class DateRangeControl extends React.Component<
props.data !== data
) {
this.setState({
minDate: minDate ? filterDate(minDate, data) : undefined,
maxDate: maxDate ? filterDate(maxDate, data) : undefined
minDate: minDate ? filterDate(minDate, data, format) : undefined,
maxDate: maxDate ? filterDate(maxDate, data, format) : undefined
});
}
}
@ -94,10 +96,11 @@ export default class DateRangeControl extends React.Component<
const {
defaultValue,
delimiter,
format,
joinValues,
setPrinstineValue,
data
data,
utc,
format
} = this.props;
if (prevProps.defaultValue !== defaultValue) {
@ -110,12 +113,13 @@ export default class DateRangeControl extends React.Component<
arr
? BaseDateRangePicker.formatValue(
{
startDate: filterDate(arr[0], data),
endDate: filterDate(arr[1], data)
startDate: filterDate(arr[0], data, format),
endDate: filterDate(arr[1], data, format)
},
format,
joinValues,
delimiter
delimiter,
utc
)
: undefined
);

View File

@ -83,9 +83,11 @@ export const relativeValueRe = /^(.+)?(\+|-)(\d+)(minute|min|hour|day|week|month
export const filterDate = (
value: string,
data: object = {},
format = 'X'
format = 'X',
utc: boolean = false
): moment.Moment => {
let m;
let m,
mm = utc ? moment.utc : moment;
if (typeof value === 'string') {
value = value.trim();
@ -97,8 +99,8 @@ export const filterDate = (
const date = new Date();
const step = parseInt(m[3], 10);
const from = m[1]
? filterDate(m[1], data, format)
: moment(
? filterDate(m[1], data, format, utc)
: mm(
/(minute|min|hour|second)s?/.test(m[4])
? [
date.getFullYear(),
@ -116,12 +118,12 @@ export const filterDate = (
: from.add(step, timeUnitMap[m[4]] as moment.DurationInputArg2);
// return from[m[2] === '-' ? 'subtract' : 'add'](step, mapping[m[4]] || m[4]);
} else if (value === 'now') {
return moment();
return mm();
} else if (value === 'today') {
const date = new Date();
return moment([date.getFullYear(), date.getMonth(), date.getDate()]);
return mm([date.getFullYear(), date.getMonth(), date.getDate()]);
} else {
return moment(value, format);
return mm(value, format);
}
};