diff --git a/README.md b/README.md index f3a23ef153..4f4fb43502 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,7 @@ monthFormat: PropTypes.string, weekDayFormat: PropTypes.string, phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerPhrases)), dayAriaLabelFormat: PropTypes.string, +predefinedHours: PropTypes.bool, ``` #### SingleDatePicker @@ -288,6 +289,7 @@ monthFormat: PropTypes.string, weekDayFormat: PropTypes.string, phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerPhrases)), dayAriaLabelFormat: PropTypes.string, +predefinedHours: PropTypes.bool, ``` #### DayPickerRangeController diff --git a/src/components/DateRangePicker.jsx b/src/components/DateRangePicker.jsx index 040d1fa597..fa3c68ca34 100644 --- a/src/components/DateRangePicker.jsx +++ b/src/components/DateRangePicker.jsx @@ -132,6 +132,7 @@ const defaultProps = { weekDayFormat: 'dd', phrases: DateRangePickerPhrases, dayAriaLabelFormat: undefined, + predefinedHours: false }; class DateRangePicker extends React.PureComponent { @@ -613,6 +614,7 @@ class DateRangePicker extends React.PureComponent { small, regular, styles, + predefinedHours, } = this.props; const { isDateRangePickerInputFocused } = this.state; @@ -667,6 +669,7 @@ class DateRangePicker extends React.PureComponent { small={small} regular={regular} verticalSpacing={verticalSpacing} + predefinedHours={predefinedHours} > {this.maybeRenderDayPickerWithPortal()} diff --git a/src/components/DateRangePickerInputController.jsx b/src/components/DateRangePickerInputController.jsx index d644b55037..a4f2d4c2da 100644 --- a/src/components/DateRangePickerInputController.jsx +++ b/src/components/DateRangePickerInputController.jsx @@ -84,6 +84,7 @@ const propTypes = forbidExtraProps({ phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerInputPhrases)), isRTL: PropTypes.bool, + predefinedHours: PropTypes.bool, }); const defaultProps = { @@ -102,7 +103,6 @@ const defaultProps = { isEndDateFocused: false, endDateAriaLabel: undefined, endDateTitleText: undefined, - screenReaderMessage: '', showClearDates: false, showCaret: false, @@ -143,6 +143,7 @@ const defaultProps = { phrases: DateRangePickerInputPhrases, isRTL: false, + predefinedHours: false, }; export default class DateRangePickerInputController extends React.PureComponent { @@ -177,9 +178,10 @@ export default class DateRangePickerInputController extends React.PureComponent minimumNights, keepOpenOnDateSelect, onDatesChange, + predefinedHours, } = this.props; - const endDate = toMomentObject(endDateString, this.getDisplayFormat()); + const endDate = toMomentObject(endDateString, this.getDisplayFormat(), predefinedHours); const isEndDateValid = endDate && !isOutsideRange(endDate) && !isDayBlocked(endDate) @@ -222,9 +224,10 @@ export default class DateRangePickerInputController extends React.PureComponent onDatesChange, onFocusChange, disabled, + predefinedHours, } = this.props; - const startDate = toMomentObject(startDateString, this.getDisplayFormat()); + const startDate = toMomentObject(startDateString, this.getDisplayFormat(), predefinedHours); const isEndDateBeforeStartDate = startDate && isBeforeDay(endDate, startDate.clone().add(minimumNights, 'days')); const isStartDateValid = startDate diff --git a/src/components/SingleDatePicker.jsx b/src/components/SingleDatePicker.jsx index c449f7e2fb..030bcf1db7 100644 --- a/src/components/SingleDatePicker.jsx +++ b/src/components/SingleDatePicker.jsx @@ -124,6 +124,7 @@ const defaultProps = { weekDayFormat: 'dd', phrases: SingleDatePickerPhrases, dayAriaLabelFormat: undefined, + predefinedHours: false }; class SingleDatePicker extends React.PureComponent { @@ -579,6 +580,7 @@ class SingleDatePicker extends React.PureComponent { styles, isOutsideRange, isDayBlocked, + predefinedHours, } = this.props; const { isInputFocused } = this.state; @@ -623,6 +625,7 @@ class SingleDatePicker extends React.PureComponent { verticalSpacing={verticalSpacing} reopenPickerOnClearDate={reopenPickerOnClearDate} keepOpenOnDateSelect={keepOpenOnDateSelect} + predefinedHours={predefinedHours} > {this.maybeRenderDayPickerWithPortal()} diff --git a/src/components/SingleDatePickerInputController.jsx b/src/components/SingleDatePickerInputController.jsx index ccaf469369..419e75c2d8 100644 --- a/src/components/SingleDatePickerInputController.jsx +++ b/src/components/SingleDatePickerInputController.jsx @@ -72,6 +72,7 @@ const propTypes = forbidExtraProps({ phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerInputPhrases)), isRTL: PropTypes.bool, + predefinedHours: PropTypes.bool, }); const defaultProps = { @@ -118,6 +119,7 @@ const defaultProps = { phrases: SingleDatePickerInputPhrases, isRTL: false, + predefinedHours: false, }; export default class SingleDatePickerInputController extends React.PureComponent { @@ -138,8 +140,9 @@ export default class SingleDatePickerInputController extends React.PureComponent onDateChange, onFocusChange, onClose, + predefinedHours, } = this.props; - const newDate = toMomentObject(dateString, this.getDisplayFormat()); + const newDate = toMomentObject(dateString, this.getDisplayFormat(), predefinedHours); const isValid = newDate && !isOutsideRange(newDate) && !isDayBlocked(newDate); if (isValid) { diff --git a/src/shapes/DateRangePickerShape.js b/src/shapes/DateRangePickerShape.js index a54126932b..eb38f36e6b 100644 --- a/src/shapes/DateRangePickerShape.js +++ b/src/shapes/DateRangePickerShape.js @@ -107,4 +107,5 @@ export default { weekDayFormat: PropTypes.string, phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerPhrases)), dayAriaLabelFormat: PropTypes.string, + predefinedHours: PropTypes.bool, }; diff --git a/src/shapes/SingleDatePickerShape.js b/src/shapes/SingleDatePickerShape.js index ef9edcb4e0..6e31885a41 100644 --- a/src/shapes/SingleDatePickerShape.js +++ b/src/shapes/SingleDatePickerShape.js @@ -96,4 +96,5 @@ export default { weekDayFormat: PropTypes.string, phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerPhrases)), dayAriaLabelFormat: PropTypes.string, + predefinedHours: PropTypes.bool }; diff --git a/src/utils/toMomentObject.js b/src/utils/toMomentObject.js index 743a320f35..5a1ecba377 100644 --- a/src/utils/toMomentObject.js +++ b/src/utils/toMomentObject.js @@ -2,11 +2,15 @@ import moment from 'moment'; import { DISPLAY_FORMAT, ISO_FORMAT } from '../constants'; -export default function toMomentObject(dateString, customFormat) { +export default function toMomentObject(dateString, customFormat, withDefaultTime = true) { const dateFormats = customFormat ? [customFormat, DISPLAY_FORMAT, ISO_FORMAT] : [DISPLAY_FORMAT, ISO_FORMAT]; const date = moment(dateString, dateFormats, true); - return date.isValid() ? date.hour(12) : null; + if (!date.isValid()) { + return null + } + + return withDefaultTime ? date.hour(12) : date; } diff --git a/test/utils/toMomentObject_spec.js b/test/utils/toMomentObject_spec.js index a60b7a1abe..dff8e658ea 100644 --- a/test/utils/toMomentObject_spec.js +++ b/test/utils/toMomentObject_spec.js @@ -43,6 +43,28 @@ describe('toMomentObject', () => { expect(date.year()).to.equal(1991); }); + describe('parses format with time', () => { + it('using default hours', () => { + const date = toMomentObject('Dec 02 1993 06:15', 'MMM DD YYYY HH:mm'); + expect(date).not.to.equal(null); + expect(date.month()).to.equal(12); + expect(date.date()).to.equal(2); + expect(date.year()).to.equal(1993); + expect(date.hours()).to.equal(12); + expect(date.minutes()).to.equal(15); + }) + + it('using input hours', () => { + const date = toMomentObject('Dec 02 1993 06:15', 'MMM DD YYYY HH:mm', false); + expect(date).not.to.equal(null); + expect(date.month()).to.equal(12); + expect(date.date()).to.equal(2); + expect(date.year()).to.equal(1993); + expect(date.hours()).to.equal(6); + expect(date.minutes()).to.equal(15); + }) + }) + describe('Daylight Savings Time issues', () => { it('last of February does not equal first of March', () => { expect(isSameDay(toMomentObject('2017-02-28'), toMomentObject('2017-03-01'))).to.equal(false);