diff --git a/README.md b/README.md
index 1098b6ad..5760dee8 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,7 @@ API
| showHour | Boolean | true | whether show hour | |
| showMinute | Boolean | true | whether show minute |
| showSecond | Boolean | true | whether show second |
-| format | String | - | moment format |
+| format | String \| String[] | - | moment format. When an array is provided, all values are used for parsing and first value for display |
| disabledHours | Function | - | disabled hour options |
| disabledMinutes | Function | - | disabled minute options |
| disabledSeconds | Function | - | disabled second options |
diff --git a/examples/format.js b/examples/format.js
index 6b6d1126..3cb99f5e 100644
--- a/examples/format.js
+++ b/examples/format.js
@@ -12,6 +12,14 @@ const App = () => (
+
+
+
>
);
diff --git a/index.d.ts b/index.d.ts
index 101a6eec..cd31035f 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -20,7 +20,7 @@ declare module "rc-time-picker" {
showHour?: boolean;
showMinute?: boolean;
showSecond?: boolean;
- format?: string;
+ format?: string | string[];
disabledHours?: () => number[];
disabledMinutes?: (hour: number) => number[];
disabledSeconds?: (hour: number, minute: number) => number[];
diff --git a/src/Combobox.jsx b/src/Combobox.jsx
index 77dc4119..964d9e4e 100644
--- a/src/Combobox.jsx
+++ b/src/Combobox.jsx
@@ -161,7 +161,7 @@ class Combobox extends Component {
}
const AMPMOptions = ['am', 'pm'] // If format has A char, then we should uppercase AM/PM
- .map(c => (format.match(/\sA/) ? c.toUpperCase() : c))
+ .map(c => (format[0].match(/\sA/) ? c.toUpperCase() : c))
.map(c => ({ value: c }));
const selected = isAM ? 0 : 1;
diff --git a/src/Header.jsx b/src/Header.jsx
index 4932382b..abcc3ff8 100644
--- a/src/Header.jsx
+++ b/src/Header.jsx
@@ -11,7 +11,7 @@ class Header extends Component {
super(props);
const { value, format } = props;
this.state = {
- str: (value && value.format(format)) || '',
+ str: (value && value.format(format[0])) || '',
invalid: false,
};
}
@@ -35,7 +35,7 @@ class Header extends Component {
if (value !== prevProps.value) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
- str: (value && value.format(format)) || '',
+ str: (value && value.format(format[0])) || '',
invalid: false,
});
}
@@ -53,7 +53,6 @@ class Header extends Component {
str,
});
const {
- format,
hourOptions,
minuteOptions,
secondOptions,
@@ -66,13 +65,16 @@ class Header extends Component {
if (str) {
const { value: originalValue } = this.props;
const value = this.getProtoValue().clone();
- const parsed = moment(str, format, true);
- if (!parsed.isValid()) {
+
+ const parsed = this.parseValue(str);
+
+ if (parsed === null) {
this.setState({
invalid: true,
});
return;
}
+
value
.hour(parsed.hour())
.minute(parsed.minute())
@@ -163,6 +165,24 @@ class Header extends Component {
);
}
+ parseValue = str => {
+ const { format } = this.props;
+
+ let parsedDate = null;
+ format.find(singleFormat => {
+ const date = moment(str, singleFormat, true);
+
+ if (date.isValid()) {
+ parsedDate = date;
+ return true;
+ }
+
+ return false;
+ });
+
+ return parsedDate;
+ };
+
render() {
const { prefixCls } = this.props;
return
{this.getInput()}
;
diff --git a/src/TimePicker.jsx b/src/TimePicker.jsx
index 3cb29ed9..179be29f 100644
--- a/src/TimePicker.jsx
+++ b/src/TimePicker.jsx
@@ -11,6 +11,14 @@ function refFn(field, component) {
this[field] = component;
}
+function toArray(val) {
+ if (val === null || val === undefined) {
+ return [];
+ }
+
+ return Array.isArray(val) ? val : [val];
+}
+
class Picker extends Component {
static defaultProps = {
clearText: 'clear',
@@ -115,7 +123,7 @@ class Picker extends Component {
getFormat() {
const { format, showHour, showMinute, showSecond, use12Hours } = this.props;
if (format) {
- return format;
+ return toArray(format);
}
if (use12Hours) {
@@ -123,12 +131,14 @@ class Picker extends Component {
.filter(item => !!item)
.join(':');
- return fmtString.concat(' a');
+ return toArray(fmtString.concat(' a'));
}
- return [showHour ? 'HH' : '', showMinute ? 'mm' : '', showSecond ? 'ss' : '']
- .filter(item => !!item)
- .join(':');
+ return toArray(
+ [showHour ? 'HH' : '', showMinute ? 'mm' : '', showSecond ? 'ss' : '']
+ .filter(item => !!item)
+ .join(':'),
+ );
}
getPanelElement() {
@@ -314,7 +324,7 @@ class Picker extends Component {
name={name}
onKeyDown={this.onKeyDown}
disabled={disabled}
- value={(value && value.format(this.getFormat())) || ''}
+ value={(value && value.format(this.getFormat()[0])) || ''}
autoComplete={autoComplete}
onFocus={onFocus}
onBlur={onBlur}
diff --git a/tests/Select.spec.jsx b/tests/Select.spec.jsx
index eb25614c..6c790d0f 100644
--- a/tests/Select.spec.jsx
+++ b/tests/Select.spec.jsx
@@ -199,6 +199,32 @@ describe('Select', () => {
expect(picker.state().open).toBeTruthy();
});
+ it('ampm correctly format value', async () => {
+ const onAmPmChange = jest.fn();
+ const picker = renderPicker({
+ onAmPmChange,
+ defaultValue: moment()
+ .hour(0)
+ .minute(0)
+ .second(0),
+ format: 'hh:mm a',
+ showSecond: false,
+ use12Hours: true,
+ });
+ expect(picker.state().open).toBeFalsy();
+ clickInput(picker);
+
+ expect(picker.state().open).toBeTruthy();
+
+ matchValue(picker, '12:00 am');
+ clickSelectItem(picker, 2, 1);
+
+ expect(onAmPmChange).toBeCalled();
+ expect(onAmPmChange.mock.calls[0][0]).toBe('PM');
+ matchValue(picker, '12:00 pm');
+ expect(picker.state().open).toBeTruthy();
+ });
+
it('disabled correctly', async () => {
const onChange = jest.fn();
const picker = renderPicker({
@@ -269,6 +295,52 @@ describe('Select', () => {
});
});
+ describe('multi format parsing mode', () => {
+ it('renders correctly', async () => {
+ const picker = renderPicker({
+ use12Hours: true,
+ defaultValue: moment()
+ .hour(14)
+ .minute(0)
+ .second(0),
+ format: ['h:mm a', 'h-mm a'],
+ showSecond: false,
+ });
+
+ expect(picker.state().open).toBeFalsy();
+ clickInput(picker);
+ expect(picker.state().open).toBeTruthy();
+
+ matchValue(picker, '2:00 pm');
+
+ expect(picker.find('.rc-time-picker-panel-select').length).toBe(3);
+ });
+
+ it('renders 12am/pm correctly', async () => {
+ const picker = renderPicker({
+ use12Hours: true,
+ defaultValue: moment()
+ .hour(0)
+ .minute(0)
+ .second(0),
+ showSecond: false,
+ format: ['hh:mm a', 'hh-mm a'],
+ });
+
+ expect(picker.state().open).toBeFalsy();
+ clickInput(picker);
+ expect(picker.state().open).toBeTruthy();
+
+ matchValue(picker, '12:00 am');
+
+ clickSelectItem(picker, 2, 1);
+ matchValue(picker, '12:00 pm');
+
+ clickSelectItem(picker, 2, 0);
+ matchValue(picker, '12:00 am');
+ });
+ });
+
describe('select in 12 hours mode', () => {
it('renders correctly', async () => {
const picker = renderPicker({