Repository: gpbl/react-day-picker
Pull request #518 (2017-10-15 14:49:19)

Replace moment specifier with format/parse functions
This PR will remove moment dependency in favour of parse and format helpers which can be handled with library chosen in a team.


Patch:
diff --git a/docs/gatsby-node.js b/docs/gatsby-node.js
index 41038318a..c53ea1063 100644
--- a/docs/gatsby-node.js
+++ b/docs/gatsby-node.js
@@ -44,6 +44,10 @@ exports.modifyWebpackConfig = ({ config, stage }) => {
               __dirname,
               '../src/DayPickerInput.js'
             ),
+            'react-day-picker/moment$': path.resolve(
+              __dirname,
+              '../src/addons/MomentLocaleUtils.js'
+            ),
           },
         },
       });
diff --git a/docs/src/code-samples/examples/input-custom-overlay.js b/docs/src/code-samples/examples/input-custom-overlay.js
index 005f46044..798136c15 100644
--- a/docs/src/code-samples/examples/input-custom-overlay.js
+++ b/docs/src/code-samples/examples/input-custom-overlay.js
@@ -1,8 +1,5 @@
 import React from 'react';
-
 import DayPickerInput from 'react-day-picker/DayPickerInput';
-import { LocaleUtils } from 'react-day-picker';
-
 import 'react-day-picker/lib/style.css';
 
 function CustomOverlay({ classNames, selectedDay, children }) {
@@ -23,7 +20,6 @@ function CustomOverlay({ classNames, selectedDay, children }) {
 export default function Example() {
   return (
     <DayPickerInput
-      placeholder="MM/DD/YYYY"
       overlayComponent={CustomOverlay}
       dayPickerProps={{
         todayButton: 'Today',
diff --git a/docs/src/code-samples/examples/input-from-to.js b/docs/src/code-samples/examples/input-from-to.js
index f023c7ecc..e3d5c2045 100644
--- a/docs/src/code-samples/examples/input-from-to.js
+++ b/docs/src/code-samples/examples/input-from-to.js
@@ -5,6 +5,8 @@ import Helmet from 'react-helmet';
 import DayPickerInput from 'react-day-picker/DayPickerInput';
 import 'react-day-picker/lib/style.css';
 
+import { formatDate, parseDate } from 'react-day-picker/moment';
+
 export default class Example extends React.Component {
   constructor(props) {
     super(props);
@@ -34,29 +36,26 @@ export default class Example extends React.Component {
   }
   handleFromChange(from) {
     // Change the from date and focus the "to" input field
-    this.setState({ from: from ? from.toDate() : undefined }, () => {
+    this.setState({ from }, () => {
       if (!this.state.to) {
         this.focusTo();
       }
     });
   }
-  handleToChange(day) {
-    const to = day ? day.toDate() : undefined;
+  handleToChange(to) {
     this.setState({ to }, this.showFromMonth);
   }
   render() {
-    const format = 'YYYY-MM-DD';
     const { from, to } = this.state;
-    const fromFormatted = from ? moment(from).format(format) : '';
-    const toFormatted = to ? moment(to).format(format) : '';
     const modifiers = { start: from, end: to };
     return (
       <div className="InputFromTo">
         <DayPickerInput
-          value={fromFormatted}
-          onDayChange={this.handleFromChange}
+          value={from}
           placeholder="From"
-          format={format}
+          format="LL"
+          formatDate={formatDate}
+          parseDate={parseDate}
           dayPickerProps={{
             selectedDays: [from, { from, to }],
             disabledDays: { after: to },
@@ -64,16 +63,17 @@ export default class Example extends React.Component {
             modifiers,
             numberOfMonths: 2,
           }}
+          onDayChange={this.handleFromChange}
         />{' '}
         —{' '}
         <span className="InputFromTo-to">
           <DayPickerInput
             ref={el => (this.to = el)}
-            value={toFormatted}
-            onDayChange={this.handleToChange}
+            value={to}
             placeholder="To"
-            format={format}
-            hideOnDayClick={false}
+            format="LL"
+            formatDate={formatDate}
+            parseDate={parseDate}
             dayPickerProps={{
               selectedDays: [from, { from, to }],
               disabledDays: { before: from },
@@ -82,6 +82,7 @@ export default class Example extends React.Component {
               fromMonth: from,
               numberOfMonths: 2,
             }}
+            onDayChange={this.handleToChange}
           />
         </span>
         <Helmet>
@@ -105,7 +106,7 @@ export default class Example extends React.Component {
     width: 550px;
   }
   .InputFromTo-to .DayPickerInput-Overlay {
-    margin-left: -198px;
+    margin-left: -224.5px;
   }
 `}</style>
         </Helmet>
diff --git a/docs/src/code-samples/examples/input-moment.js b/docs/src/code-samples/examples/input-moment.js
new file mode 100644
index 000000000..f7a1d148c
--- /dev/null
+++ b/docs/src/code-samples/examples/input-moment.js
@@ -0,0 +1,37 @@
+import React from 'react';
+
+import DayPickerInput from 'react-day-picker/DayPickerInput';
+import 'react-day-picker/lib/style.css';
+
+import MomentLocaleUtils, {
+  formatDate,
+  parseDate,
+} from 'react-day-picker/moment';
+
+import 'moment/locale/it';
+
+export default function Example() {
+  return (
+    <div>
+      <p>In English (default):</p>
+      <DayPickerInput
+        formatDate={formatDate}
+        parseDate={parseDate}
+        placeholder={`${formatDate(new Date())}`}
+      />
+      <p>
+        In Italian, using <code>{'format="LL"'}</code>:
+      </p>
+      <DayPickerInput
+        formatDate={formatDate}
+        parseDate={parseDate}
+        format="LL"
+        placeholder={`${formatDate(new Date(), 'LL', 'it')}`}
+        dayPickerProps={{
+          locale: 'it',
+          localeUtils: MomentLocaleUtils,
+        }}
+      />
+    </div>
+  );
+}
diff --git a/docs/src/code-samples/examples/input-state.js b/docs/src/code-samples/examples/input-state.js
index 2a51e9ecc..04cd79e29 100644
--- a/docs/src/code-samples/examples/input-state.js
+++ b/docs/src/code-samples/examples/input-state.js
@@ -1,5 +1,4 @@
 import React from 'react';
-import moment from 'moment';
 import DayPickerInput from 'react-day-picker/DayPickerInput';
 import 'react-day-picker/lib/style.css';
 
@@ -15,29 +14,25 @@ export default class Example extends React.Component {
   handleDayChange(selectedDay, modifiers) {
     this.setState({
       selectedDay,
-      isDisabled: modifiers.disabled,
+      isDisabled: modifiers.disabled === true,
     });
   }
   render() {
     const { selectedDay, isDisabled } = this.state;
-    const formattedDay = selectedDay
-      ? moment(selectedDay).format('DD/MM/YYYY')
-      : '';
     return (
       <div>
         <p>
           {!selectedDay && '🤔 Type or pick a valid day'}
           {selectedDay && isDisabled && '😡 This day is disabled'}
-          {selectedDay && !isDisabled && `😄 You chose ${formattedDay}`}
+          {selectedDay &&
+            !isDisabled &&
+            `😄 You chose ${selectedDay.toLocaleDateString()}`}
         </p>
         <DayPickerInput
-          value={formattedDay}
+          value={selectedDay}
           onDayChange={this.handleDayChange}
-          format="DD/MM/YYYY"
-          placeholder={`E.g. ${moment()
-            .locale('en')
-            .format('DD/MM/YYYY')}`}
           dayPickerProps={{
+            selectedDays: selectedDay,
             disabledDays: {
               daysOfWeek: [0, 6],
             },
diff --git a/docs/src/code-samples/examples/input.js b/docs/src/code-samples/examples/input.js
index 79fd39846..42e8d146e 100644
--- a/docs/src/code-samples/examples/input.js
+++ b/docs/src/code-samples/examples/input.js
@@ -6,10 +6,7 @@ export default function Example() {
   return (
     <div>
       <p>Please type a day:</p>
-      <DayPickerInput
-        onDayChange={day => console.log(day)}
-        placeholder="MM/DD/YYYY"
-      />
+      <DayPickerInput onDayChange={day => console.log(day)} />
     </div>
   );
 }
diff --git a/docs/src/code-samples/input-01.js b/docs/src/code-samples/input-01.js
index de9e0c5d2..3969fe020 100644
--- a/docs/src/code-samples/input-01.js
+++ b/docs/src/code-samples/input-01.js
@@ -17,13 +17,9 @@ export default class MyForm extends React.Component {
     const { selectedDay } = this.state;
     return (
       <div>
-        <DayPickerInput
-          name="birthday"
-          placeholder="DD/MM/YYYY"
-          format="DD/MM/YYYY"
-          onDayChange={this.handleDayChange}
-        />
-        {selectedDay && <p>Selected: {<p>{selectedDay.format('LLL')}</p>}</p>}
+        {selectedDay && <p>Day: {selectedDay.toLocaleDateString()}</p>}
+        {!selectedDay && <p>Choose a day</p>}
+        <DayPickerInput onDayChange={this.handleDayChange} />
       </div>
     );
   }
diff --git a/docs/src/code-samples/input-02.js b/docs/src/code-samples/input-02.js
index 8a052caf3..77d945738 100644
--- a/docs/src/code-samples/input-02.js
+++ b/docs/src/code-samples/input-02.js
@@ -5,12 +5,10 @@ import 'react-day-picker/lib/style.css';
 export default function MyDatePicker() {
   return (
     <DayPickerInput
-      name="birthday"
-      placeholder="DD/MM/YYYY"
-      format="DD/MM/YYYY"
       dayPickerProps={{
         month: new Date(2018, 10),
         showWeekNumbers: true,
+        todayButton: 'Today',
       }}
     />
   );
diff --git a/docs/src/containers/DocPage.js b/docs/src/containers/DocPage.js
index 88fa407e7..cdf9fbe17 100644
--- a/docs/src/containers/DocPage.js
+++ b/docs/src/containers/DocPage.js
@@ -23,7 +23,7 @@ export default function DocPage({ title, children }) {
               <Menu.Item to="/docs/matching-days">Matching days</Menu.Item>
               <Menu.Item to="/docs/styling">Styling</Menu.Item>
               <Menu.Item to="/docs/localization">Localization</Menu.Item>
-              <Menu.Item to="/docs/input">Using the input field</Menu.Item>
+              <Menu.Item to="/docs/input">DayPickerInput</Menu.Item>
             </Menu>
             <Menu title="API">
               <Menu.Item to="/api/DayPicker">DayPicker</Menu.Item>
diff --git a/docs/src/containers/ExamplePage.js b/docs/src/containers/ExamplePage.js
index 45339484a..955f7bdd7 100644
--- a/docs/src/containers/ExamplePage.js
+++ b/docs/src/containers/ExamplePage.js
@@ -89,6 +89,9 @@ export default function ExamplePage({ children, title }) {
               <Menu.Item to="/examples/input-custom-overlay">
                 Customize the overlay
               </Menu.Item>
+              <Menu.Item to="/examples/input-moment">
+                Using moment.js to parse and format dates
+              </Menu.Item>
               <Menu.Item to="/examples/input-from-to">
                 Range with two inputs
               </Menu.Item>
diff --git a/docs/src/pages/api/DayPickerInput.js b/docs/src/pages/api/DayPickerInput.js
index 50f480c25..bd54a4680 100644
--- a/docs/src/pages/api/DayPickerInput.js
+++ b/docs/src/pages/api/DayPickerInput.js
@@ -18,11 +18,12 @@ export default () => (
       <a href="#clickUnselectsDay">clickUnselectsDay</a>,{' '}
       <a href="#component">component</a>,{' '}
       <a href="#dayPickerProps">dayPickerProps</a>, <a href="#format">format</a>,{' '}
+      <a href="#formatDate">formatDate</a>,{' '}
       <a href="#hideOnDayClick">hideOnDayClick</a>,{' '}
       <a href="#inputProps">inputProps</a>,{' '}
       <a href="#overlayComponent">overlayComponent</a>,{' '}
-      <a href="#placeholder">placeholder</a>,{' '}
-      <a href="#showOverlay">showOverlay</a>
+      <a href="#parseDate">parseDate</a>, <a href="#placeholder">placeholder</a>,{' '}
+      <a href="#showOverlay">showOverlay</a>, <a href="#value">value</a>
     </p>
     <h4>Event handlers</h4>
     <p>
@@ -108,15 +109,45 @@ function MyDayPickerInput(props) {
 
       <h3>
         <Anchor id="format" />
-        format <code>string | [string]</code>
+        format <code>string</code>
       </h3>
       <p>
-        The format strings used for parsing the date entered in the input field.
-        It accepts all the{' '}
-        <a href="https://momentjs.com/docs/#/displaying/format/">
-          format strings
+        The format strings used for formatting and parsing dates. It works with{' '}
+        <a href="#parseDate">
+          <code>parseDate</code>
         </a>{' '}
-        used by moment.js.
+        and{' '}
+        <a href="#formatDate">
+          <code>formatDate</code>
+        </a>
+      </p>
+
+      <h3>
+        <Anchor id="formatDate" />
+        formatDate{' '}
+        <code>(date: Date?, format: string?, locale: string?) ⇒ string</code>
+      </h3>
+      <p>
+        Date formatter used for displaying the selected date as value of the
+        input field. As default, it returns dates formatted as{' '}
+        <code>YYYY-M-D</code>.<br />
+        Arguments: <code>format</code> is the value coming from the{' '}
+        <a href="#format">
+          <code>format</code>
+        </a>{' '}
+        prop, while <code>locale</code> is from{' '}
+        <a href="#dayPickerProps">
+          <code>dayPickerProps</code>
+        </a>.<br />
+        See also{' '}
+        <a href="#parseDate">
+          <code>parseDate</code>
+        </a>.
+      </p>
+      <p>
+        If you are using <a href="http://momentjs.com/">moment.js</a> in your
+        app, we already provide this function as addon: see{' '}
+        <Link to="/examples/input-moment">this example</Link>.
       </p>
 
       <h3>
@@ -159,6 +190,34 @@ function MyDayPickerInput(props) {
       <p>
         See also <Link to="/examples/input-custom-overlay">this example</Link>.
       </p>
+
+      <h3>
+        <Anchor id="parseDate" />
+        parseDate{' '}
+        <code>(str: string?, format: string?, locale: string?) ⇒ string</code>
+      </h3>
+      <p>
+        Date parser used for parsing the string typed in the input field. As
+        default, it parses only dates formatted as <code>YYYY-M-D</code>.
+        <br />
+        Arguments: <code>format</code> is the value coming from the{' '}
+        <a href="#format">
+          <code>format</code>
+        </a>{' '}
+        prop, while <code>locale</code> is from{' '}
+        <a href="#dayPickerProps">
+          <code>dayPickerProps</code>
+        </a>.<br />See also{' '}
+        <a href="#formatDate">
+          <code>formatDate</code>
+        </a>.
+      </p>
+      <p>
+        If you are using <a href="http://momentjs.com/">moment.js</a> in your
+        app, we already provide this function as addon: see{' '}
+        <Link to="/examples/input-moment">this example</Link>.
+      </p>
+
       <h3>
         <Anchor id="placeholder" />
         placeholder <code>string</code>
@@ -174,6 +233,13 @@ function MyDayPickerInput(props) {
         Show the overlay during the initial rendering of the component. This is
         useful if you want to keep the overlay visibile while styling it.
       </p>
+      <h3>
+        <Anchor id="value" />
+        value <code>string | Date</code>
+      </h3>
+      <p>
+        The value of the <code>input</code> field.
+      </p>
 
       <hr />
       <h2>Event handlers</h2>
diff --git a/docs/src/pages/docs/getting-started.js b/docs/src/pages/docs/getting-started.js
index e693fc2be..2a4c3fb42 100644
--- a/docs/src/pages/docs/getting-started.js
+++ b/docs/src/pages/docs/getting-started.js
@@ -37,14 +37,6 @@ export default () => (
 $ yarn add react-day-picker`}
     </CodeBlock>
 
-    <blockquote>
-      <p>
-        If you want to use the{' '}
-        <Link to="/api/DayPickerInput">DayPickerInput component</Link>, you must
-        install moment.js as well.
-      </p>
-    </blockquote>
-
     <p>Then import the component and its style into your component:</p>
 
     <CodeBlock>
diff --git a/docs/src/pages/docs/input.js b/docs/src/pages/docs/input.js
index 29342deee..a13fa962c 100644
--- a/docs/src/pages/docs/input.js
+++ b/docs/src/pages/docs/input.js
@@ -6,36 +6,28 @@ import CodeBlock from '../../ui/CodeBlock';
 import CodeSample from '../../ui/CodeSample';
 
 export default () => (
-  <DocPage title="Using the input field">
+  <DocPage title="Using DayPickerInput">
     <p>
-      The package includes <code>{`<DayPickerInput />`}</code>, a component
-      rendering an input field and displaying react-day-picker in an overlay.
+      The package includes{' '}
+      <Link to="/api/DayPickerInput">
+        <code>{`<DayPickerInput />`}</code>
+      </Link>, a component rendering an input field and displaying
+      react-day-picker in an overlay.
     </p>
-    <h3>Add moment.js dependency</h3>
-    <p>
-      <a href="http://momentjs.com">moment.js</a> is required as it is used to
-      validate and format the date typed by the user. Make sure you have
-      installed it in your dependencies:
-    </p>
-    <CodeBlock language="bash">{`npm install moment --save
-# or with yarn
-yarn add moment`}</CodeBlock>
-    <h3>Import the component</h3>
     <CodeBlock
     >{`import DayPickerInput from 'react-day-picker/DayPickerInput';`}</CodeBlock>
     <p>
-      If you are using <a href="https://unpkg.com/">unpkg</a>, the component is
-      available as <code>DayPicker.Input</code> global variable:
+      <small>
+        If you are using <a href="https://unpkg.com/">unpkg</a>, the component
+        is available as <code>DayPicker.Input</code> global variable.
+      </small>
     </p>
 
-    <CodeBlock
-    >{`<script src="https://unpkg.com/moment@2/min/moment.min.js"></script>
-<script src="https://unpkg.com/react-day-picker/lib/daypicker.min.js"></script>
-<script type="text/javascript">
-  DayPickerInput = DayPicker.Input;
-</script>`}</CodeBlock>
-
     <h3>Example</h3>
+    <p>
+      In its simple form, you use <code>DayPickerInput</code> to get the day
+      typed in the input field, or the day picked in the calendar:
+    </p>
     <CodeSample name="input-01" />
 
     <h2>Customizing the DayPicker</h2>
@@ -46,13 +38,34 @@ yarn add moment`}</CodeBlock>
     </p>
     <CodeSample name="input-02" />
 
-    <h2>Localization</h2>
+    <h2>Changing the date format</h2>
+
     <p>
-      You can use the locale and format methods of moment.js to format the value
-      displayed in the input field. Remember to add the <code>locale</code>{' '}
-      value to the <code>dayPickerProps</code>.
+      As default, the date format is the ”ugly” <code>YYYY-M-D</code>. This is
+      because parsing JavaScript dates from strings is not an easy task, and we
+      don’t want to depend on an external library for doing this.
     </p>
-    <p>For example, this implementation display the input field in Italian:</p>
-    <CodeSample name="input-03" />
+
+    <p>
+      To customize the way dates are parsed and formatted, for example using
+      your date library of choice, use the{' '}
+      <Link to="/api/DayPickerInput#parsedate">
+        <code>parseDate</code>
+      </Link>{' '}
+      and the{' '}
+      <Link to="/api/DayPickerInput#formatDate">
+        <code>formatDate</code>
+      </Link>{' '}
+      props.
+    </p>
+
+    <h3>Use moment.js to parse and format dates</h3>
+    <p>
+      If you use <a href="http://momentjs.com">moment.js</a>, we provide an
+      utility for using its parser and formatter functions. See{' '}
+      <Link to="/examples/input-moment">this example</Link>.
+    </p>
+
+    <CodeSample name="examples/input-moment" />
   </DocPage>
 );
diff --git a/docs/src/pages/docs/localization.js b/docs/src/pages/docs/localization.js
index 12574b250..d1a8ee42d 100644
--- a/docs/src/pages/docs/localization.js
+++ b/docs/src/pages/docs/localization.js
@@ -2,6 +2,7 @@ import React from 'react';
 import Link from 'gatsby-link';
 
 import DocPage from '../../containers/DocPage';
+import Anchor from '../../ui/Anchor';
 import CodeSample from '../../ui/CodeSample';
 import NextButton from '../../ui/NextButton';
 
@@ -40,7 +41,9 @@ export default () => (
 
     <CodeSample name="localization-01" />
 
-    <h2>Localization with moment.js</h2>
+    <h2>
+      <Anchor id="localization-moment" />Localization with moment.js
+    </h2>
     <p>
       If you already include <a href="http://www.momentjs.com">moment.js</a> in
       your dependencies, you may find convenient to use moment’s translation
@@ -87,6 +90,6 @@ export default () => (
 
     <CodeSample name="localization-03" />
 
-    <NextButton to="/docs/input" label="Using the input field" />
+    <NextButton to="/docs/input" label="Using DayPickerInput" />
   </DocPage>
 );
diff --git a/docs/src/pages/examples/input-moment.js b/docs/src/pages/examples/input-moment.js
new file mode 100644
index 000000000..f71b175aa
--- /dev/null
+++ b/docs/src/pages/examples/input-moment.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import Link from 'gatsby-link';
+
+import ExamplePage from '../../containers/ExamplePage';
+import CodeSample from '../../ui/CodeSample';
+
+export default () => (
+  <ExamplePage title="Using moment.js to parse and format dates">
+    <p>
+      Use the{' '}
+      <Link to="/api/DayPickerInput#parseDate">
+        <code>parseDate</code>
+      </Link>{' '}
+      prop to parse the input typed by the user, and the{' '}
+      <Link to="/api/DayPickerInput#formatDate">
+        <code>formatDate</code>
+      </Link>{' '}
+      prop to format them.
+    </p>
+    <p>
+      In the following example, we are importing the functions included in the
+      <code>react-day-picker/moment</code> package, that use moment.js.
+    </p>
+    <CodeSample name="examples/input-moment" />
+  </ExamplePage>
+);
diff --git a/docs/src/pages/examples/input.js b/docs/src/pages/examples/input.js
index be5560bee..4e435f41f 100644
--- a/docs/src/pages/examples/input.js
+++ b/docs/src/pages/examples/input.js
@@ -7,9 +7,13 @@ export default () => (
   <ExamplePage title="Input field">
     <p>
       <Link to="/api/DayPickerInput">DayPickerInput</Link> binds the DayPicker
-      with an input field. See also how to{' '}
-      <Link to="/examples/input-state">use it with state</Link> and how to{' '}
-      <Link to="/examples/input-custom-overlay">customize the overlay</Link>.
+      with an input field.
+    </p>
+    <p>
+      See also how to <Link to="/examples/input-state">use it with state</Link>,
+      how to{' '}
+      <Link to="/examples/input-custom-overlay">customize the overlay</Link> and
+      how to <Link to="/examples/input-moment">change the date format</Link>.
     </p>
     <CodeSample name="examples/input" />
   </ExamplePage>
diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js
index ee1bf3ae0..6f94f62d0 100644
--- a/docs/src/pages/index.js
+++ b/docs/src/pages/index.js
@@ -13,6 +13,7 @@ import styles from './index.module.scss';
 
 import FeatureModifiers from '../code-samples/examples/modifiers-styles';
 import FeatureInput from '../code-samples/examples/input';
+import FeatureInput2 from '../code-samples/examples/input-from-to';
 import FeatureLocalization from '../code-samples/examples/localization';
 import FeatureRange from '../code-samples/examples/selected-range';
 
@@ -35,7 +36,8 @@ export default function HomePage() {
             <a href="https://facebook.github.io/react/">React</a>
           </h2>
           <p>
-            Flexible, highly customizable, localizable and with ARIA support.
+            Flexible, highly customizable, localizable, with ARIA support, no
+            external dependencies, ~9KB gzipped
           </p>
           <p>
             <LinkButton to="/docs">Read the docs</LinkButton>
@@ -50,7 +52,7 @@ export default function HomePage() {
             <h3>Style days with modifiers</h3>
             <p>
               Define the disabled or selected days and change the aspect of each
-              day cell with <a href="/docs/modifiers.html">modifiers</a>.
+              day cell with <Link to="/docs/matching-days">modifiers</Link>.
             </p>
             <div className={styles.feature}>
               <FeatureModifiers />
@@ -60,20 +62,19 @@ export default function HomePage() {
             <h3>Works with input fields</h3>
             <p>
               Display the date picker in an overlay using the{' '}
-              <a href="/docs/input.html">DayPickerInput</a> component.{' '}
-              <small>
-                Requires <a href="https://momentjs.com/">moment.js</a>.
-              </small>
+              <Link to="/docs/input">DayPickerInput</Link> component.
             </p>
             <div className={styles.feature}>
               <FeatureInput />
+              <p>...or choose a range of days:</p>
+              <FeatureInput2 />
             </div>
           </div>
           <div>
             <h3>Localizable</h3>
             <p>
-              Use your own translation strings or import those from moment.js
-              (if you use it).
+              Use your own translation strings or import those from moment.js,
+              if you use it.
             </p>
             <div className={styles.feature}>
               <FeatureLocalization />
@@ -82,7 +83,9 @@ export default function HomePage() {
           <div>
             <h3>Select range of days</h3>
             <p>
-              Specify which days should be selected in your component’s state (<Link to="/examples/selected-range">source</Link>).
+              Specify which days should be selected in your component’s state (<Link to="/examples/selected-range">
+                source
+              </Link>).
             </p>
             <div className={styles.feature}>
               <FeatureRange numberOfMonths={1} />
diff --git a/src/DayPickerInput.js b/src/DayPickerInput.js
index 00f4d9857..34233800e 100644
--- a/src/DayPickerInput.js
+++ b/src/DayPickerInput.js
@@ -1,25 +1,62 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import moment from 'moment'; // eslint-disable-line import/no-extraneous-dependencies
 
 import DayPicker from './DayPicker';
 import { getModifiersForDay } from './ModifiersUtils';
-import MomentLocaleUtils from './addons/MomentLocaleUtils';
 import { ESC } from './keys';
 
 // When clicking on a day cell, overlay will be hidden after this timeout
 export const HIDE_TIMEOUT = 100;
 
+function isDate(date) {
+  return date instanceof Date && !isNaN(date.valueOf());
+}
+
+export function defaultFormat(d) {
+  if (isDate(d)) {
+    const year = d.getFullYear();
+    const month = `${d.getMonth() + 1}`;
+    const day = `${d.getDate()}`;
+    return `${year}-${month}-${day}`;
+  }
+  return '';
+}
+
+export function defaultParse(str) {
+  if (typeof str !== 'string') {
+    return undefined;
+  }
+  const split = str.split('-');
+  if (split.length !== 3) {
+    return undefined;
+  }
+  const year = parseInt(split[0], 10);
+  const month = parseInt(split[1], 10) - 1;
+  const day = parseInt(split[2], 10);
+  if (
+    isNaN(year) ||
+    isNaN(month) ||
+    isNaN(day) ||
+    day <= 0 ||
+    day > 31 ||
+    month <= 0 ||
+    month >= 12
+  ) {
+    return undefined;
+  }
+
+  return new Date(year, month, day);
+}
+
 export default class DayPickerInput extends React.Component {
   static propTypes = {
-    value: PropTypes.string,
+    value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
     inputProps: PropTypes.object,
     placeholder: PropTypes.string,
 
-    format: PropTypes.oneOfType([
-      PropTypes.arrayOf(PropTypes.string),
-      PropTypes.string,
-    ]),
+    format: PropTypes.string,
+    formatDate: PropTypes.func,
+    parseDate: PropTypes.func,
 
     showOverlay: PropTypes.bool,
     dayPickerProps: PropTypes.object,
@@ -45,7 +82,10 @@ export default class DayPickerInput extends React.Component {
   static defaultProps = {
     dayPickerProps: {},
     value: '',
+    placeholder: 'YYYY-M-D',
     format: 'L',
+    formatDate: defaultFormat,
+    parseDate: defaultParse,
     showOverlay: false,
     hideOnDayClick: true,
     clickUnselectsDay: false,
@@ -86,7 +126,7 @@ export default class DayPickerInput extends React.Component {
     const selectedDaysFromProps = this.props.dayPickerProps.selectedDays;
     const nextSelectedDaysFromProps = nextProps.dayPickerProps.selectedDays;
 
-    const nextValue = nextProps.value;
+    let nextValue = nextProps.value;
     const currentValue = this.props.value;
 
     const monthChanged =
@@ -96,7 +136,16 @@ export default class DayPickerInput extends React.Component {
           nextMonthFromProps.getMonth() !== monthFromProps.getMonth()));
 
     if (nextValue !== currentValue) {
-      this.setState({ value: nextValue });
+      if (isDate(nextValue)) {
+        nextValue = this.props.formatDate(
+          nextValue,
+          this.props.format,
+          this.props.dayPickerProps.locale
+        );
+      }
+      this.setState({
+        value: nextValue,
+      });
     }
     if (monthChanged) {
       this.setState({ month: nextMonthFromProps });
@@ -113,13 +162,19 @@ export default class DayPickerInput extends React.Component {
   }
 
   getStateFromProps(props) {
-    const { dayPickerProps, format, value } = props;
+    const { dayPickerProps, formatDate, format } = props;
+    let { value } = props;
     let month;
-    if (value) {
-      // Display the month specified in the value prop
-      const m = moment(value, format, true);
-      if (m.isValid()) {
-        month = m.toDate();
+    let day;
+    if (props.value) {
+      if (isDate(props.value)) {
+        day = props.value;
+        value = formatDate(props.value, format, dayPickerProps.locale);
+      } else {
+        day = props.parseDate(props.value, format, dayPickerProps.locale);
+      }
+      if (day) {
+        month = day;
       }
     } else {
       // Otherwise display the month coming from `dayPickerProps` or the current month
@@ -175,7 +230,7 @@ export default class DayPickerInput extends React.Component {
         },
         {}
       );
-      onDayChange(moment(day), modifiers);
+      onDayChange(day, modifiers);
     });
   }
 
@@ -248,13 +303,18 @@ export default class DayPickerInput extends React.Component {
   }
 
   handleInputChange(e) {
-    const { inputProps, onDayChange, format } = this.props;
+    const {
+      dayPickerProps,
+      format,
+      inputProps,
+      onDayChange,
+      parseDate,
+    } = this.props;
     if (inputProps.onChange) {
       e.persist();
       inputProps.onChange(e);
     }
     const { value } = e.target;
-    const m = moment(value, format, true);
     if (value.trim() === '') {
       this.setState({ value });
       if (onDayChange) {
@@ -262,11 +322,11 @@ export default class DayPickerInput extends React.Component {
       }
       return;
     }
-    if (!m.isValid()) {
+    const day = parseDate(value, format, dayPickerProps.locale);
+    if (!day) {
       this.setState({ value });
       return;
     }
-    const day = m.toDate();
     this.updateState(day, value);
   }
 
@@ -284,6 +344,7 @@ export default class DayPickerInput extends React.Component {
       clickUnselectsDay,
       dayPickerProps,
       onDayChange,
+      formatDate,
       format,
     } = this.props;
     if (dayPickerProps.onDayClick) {
@@ -303,7 +364,7 @@ export default class DayPickerInput extends React.Component {
         selectedDays = selectedDays.slice(0);
         const selectedDayIdx = selectedDays.indexOf(day);
         selectedDays.splice(selectedDayIdx, 1);
-      } else if (moment(selectedDays).isValid()) {
+      } else if (selectedDays) {
         selectedDays = null;
       }
       this.setState({ value: '', selectedDays }, this.hideAfterDayClick);
@@ -313,24 +374,29 @@ export default class DayPickerInput extends React.Component {
       return;
     }
 
-    const m = moment(day).locale(dayPickerProps.locale || 'en');
-    const value = m.format(typeof format === 'string' ? format : format[0]);
+    const value = formatDate(day, format, dayPickerProps.locale);
     this.setState({ value, month: day }, () => {
       if (onDayChange) {
-        onDayChange(m, modifiers);
+        onDayChange(day, modifiers);
       }
       this.hideAfterDayClick();
     });
   }
 
   renderOverlay() {
-    const { format, classNames, dayPickerProps } = this.props;
+    const {
+      classNames,
+      dayPickerProps,
+      parseDate,
+      formatDate,
+      format,
+    } = this.props;
     const { selectedDays, value } = this.state;
     let selectedDay;
     if (!selectedDays && value) {
-      const m = moment(value, format, true);
-      if (m.isValid()) {
-        selectedDay = m.toDate();
+      const day = parseDate(value, format, dayPickerProps.locale);
+      if (day) {
+        selectedDay = day;
       }
     } else if (selectedDays) {
       selectedDay = selectedDays;
@@ -341,9 +407,7 @@ export default class DayPickerInput extends React.Component {
       onTodayButtonClick = () =>
         this.updateState(
           new Date(),
-          moment()
-            .locale(dayPickerProps.locale || 'en')
-            .format(this.props.format),
+          formatDate(new Date(), format, dayPickerProps.locale),
           this.hideAfterDayClick
         );
     }
@@ -357,7 +421,6 @@ export default class DayPickerInput extends React.Component {
       >
         <DayPicker
           ref={el => (this.daypicker = el)}
-          localeUtils={MomentLocaleUtils}
           onTodayButtonClick={onTodayButtonClick}
           {...dayPickerProps}
           month={this.state.month}
diff --git a/src/addons/MomentLocaleUtils.js b/src/addons/MomentLocaleUtils.js
index 1fd1051af..8f921386c 100644
--- a/src/addons/MomentLocaleUtils.js
+++ b/src/addons/MomentLocaleUtils.js
@@ -46,6 +46,20 @@ export function getMonths(locale = 'en') {
   return months;
 }
 
+export function formatDate(date, format = 'L', locale = 'en') {
+  return moment(date)
+    .locale(locale)
+    .format(format);
+}
+
+export function parseDate(str, format = 'L', locale = 'en') {
+  const m = moment(str, format, locale);
+  if (m.isValid()) {
+    return m.toDate();
+  }
+  return undefined;
+}
+
 export default {
   formatDay,
   formatMonthTitle,
@@ -53,4 +67,6 @@ export default {
   formatWeekdayLong,
   getFirstDayOfWeek,
   getMonths,
+  formatDate,
+  parseDate,
 };


Test patch:
diff --git a/test/addons/MomentLocaleUtils.js b/test/addons/MomentLocaleUtils.js
index b68d64b3c..34fca8a89 100644
--- a/test/addons/MomentLocaleUtils.js
+++ b/test/addons/MomentLocaleUtils.js
@@ -54,4 +54,44 @@ describe('MomentLocaleUtils', () => {
       expect(MomentLocaleUtils.getMonths()).toHaveLength(12);
     });
   });
+
+  describe('getMonths', () => {
+    it('return twelve months for it locale', () => {
+      const months = MomentLocaleUtils.getMonths('it');
+      expect(months).toHaveLength(12);
+      expect(months[0]).toBe('gennaio');
+    });
+    it('return twelve months for default locale', () => {
+      expect(MomentLocaleUtils.getMonths()).toHaveLength(12);
+    });
+  });
+
+  describe('formatDate', () => {
+    it('format a date', () => {
+      const formatted = MomentLocaleUtils.formatDate(new Date(2018, 1, 20));
+      expect(formatted).toBe('02/20/2018');
+    });
+    it('format a date according to locale and format', () => {
+      const formatted = MomentLocaleUtils.formatDate(
+        new Date(2018, 1, 20),
+        'LL',
+        'it'
+      );
+      expect(formatted).toBe('20 febbraio 2018');
+    });
+  });
+  describe('parseDate', () => {
+    it('parse a date', () => {
+      const parsed = MomentLocaleUtils.parseDate(new Date(2018, 1, 20));
+      expect(parsed).toEqual(new Date(2018, 1, 20));
+    });
+    it('parse a date according to locale and format', () => {
+      const parsed = MomentLocaleUtils.parseDate('02/20/2018');
+      expect(parsed).toEqual(new Date(2018, 1, 20));
+    });
+    it('return undefined if date is not valid', () => {
+      const parsed = MomentLocaleUtils.parseDate('20 foo 2018', 'LL', 'it');
+      expect(parsed).toBeUndefined();
+    });
+  });
 });
diff --git a/test/daypickerinput/events.js b/test/daypickerinput/events.js
index 8dc46dd34..8103a29ea 100644
--- a/test/daypickerinput/events.js
+++ b/test/daypickerinput/events.js
@@ -2,6 +2,8 @@ import React from 'react';
 
 import { mount } from 'enzyme';
 
+import moment from 'moment';
+
 import * as keys from '../../src/keys';
 
 import DayPickerInput, { HIDE_TIMEOUT } from '../../src/DayPickerInput';
@@ -102,13 +104,13 @@ describe('DayPickerInput', () => {
         const input = wrapper.find('input');
         wrapper.instance().showDayPicker();
         wrapper.update();
-        input.simulate('change', { target: { value: '12/16/2013' } });
+        input.simulate('change', { target: { value: '2013-12-16' } });
         expect(wrapper.find('.DayPicker-Caption').first()).toHaveText(
           'December 2013'
         );
-        input.simulate('change', { target: { value: '11/10/2015' } });
+        input.simulate('change', { target: { value: '2015-10-11' } });
         expect(wrapper.find('.DayPicker-Caption').first()).toHaveText(
-          'November 2015'
+          'October 2015'
         );
       });
       it('should call `onDayChange` with modifiers', () => {
@@ -127,9 +129,9 @@ describe('DayPickerInput', () => {
         const input = wrapper.find('input');
         wrapper.instance().showDayPicker();
         wrapper.update();
-        input.simulate('change', { target: { value: '12/20/2015' } });
+        input.simulate('change', { target: { value: '2015-12-20' } });
         expect(onDayChange).toHaveBeenCalledTimes(1);
-        expect(onDayChange.mock.calls[0][0].format('L')).toBe('12/20/2015');
+        expect(onDayChange.mock.calls[0][0]).toEqual(new Date(2015, 11, 20));
         expect(onDayChange.mock.calls[0][1]).toEqual({
           foo: true,
           selected: true,
@@ -176,7 +178,7 @@ describe('DayPickerInput', () => {
           .find('.DayPicker-Day')
           .at(10)
           .simulate('click');
-        expect(wrapper.find('input')).toHaveProp('value', '02/08/2017');
+        expect(wrapper.find('input')).toHaveProp('value', '2017-2-8');
         expect(wrapper.find('.DayPicker-Caption')).toHaveText('February 2017');
         expect(wrapper.find('.DayPicker-Day--selected')).toHaveText('8');
       });
@@ -197,27 +199,10 @@ describe('DayPickerInput', () => {
           .find('.DayPicker-Day')
           .at(10)
           .simulate('click');
-        expect(onDayChange.mock.calls[0][0].format('L')).toBe('02/08/2017');
-        expect(onDayChange.mock.calls[0][1]).toEqual({ foo: true });
-      });
-      it('should work also when `format` is an array', () => {
-        const onDayChange = jest.fn();
-        const wrapper = mount(
-          <DayPickerInput
-            onDayChange={onDayChange}
-            format={['L', 'LL']}
-            dayPickerProps={{
-              month: new Date(2017, 1),
-            }}
-          />
+        expect(moment(onDayChange.mock.calls[0][0]).format('L')).toBe(
+          '02/08/2017'
         );
-        wrapper.instance().showDayPicker();
-        wrapper.update();
-        wrapper
-          .find('.DayPicker-Day')
-          .at(10)
-          .simulate('click');
-        expect(onDayChange.mock.calls[0][0].format('L')).toBe('02/08/2017');
+        expect(onDayChange.mock.calls[0][1]).toEqual({ foo: true });
       });
       it('should hide the day picker when clicking on a day', done => {
         const wrapper = mount(<DayPickerInput />);
@@ -245,14 +230,14 @@ describe('DayPickerInput', () => {
         expect(wrapper.instance().hideTimeout).toBeNull();
         expect(wrapper.find('.DayPicker')).toBeDefined();
       });
-      it('should unselect the clicked day if already selected', () => {
+      it('should unselect the clicked day if already selected (clickUnselectsDay)', () => {
         const wrapper = mount(
           <DayPickerInput
-            value="02/08/2017"
+            value="2017-11-8"
             clickUnselectsDay
             dayPickerProps={{
               month: new Date(2017, 1),
-              selectedDays: new Date(2017, 1, 8),
+              selectedDays: new Date(2017, 10, 8),
             }}
           />
         );
@@ -265,14 +250,14 @@ describe('DayPickerInput', () => {
         expect(wrapper.find('input')).toHaveProp('value', '');
         expect(wrapper.find('.DayPicker-Day--selected')).toHaveLength(0);
       });
-      it('should unselect the clicked day if already selected', () => {
+      it('should unselect the clicked day if already selected (clickUnselectsDay)', () => {
         const wrapper = mount(
           <DayPickerInput
-            value="02/08/2017"
+            value="2017-11-8"
             clickUnselectsDay
             dayPickerProps={{
               month: new Date(2017, 1),
-              selectedDays: [new Date(2017, 1, 8), new Date(2017, 1, 9)],
+              selectedDays: [new Date(2017, 10, 8), new Date(2017, 10, 7)],
             }}
           />
         );
@@ -289,7 +274,7 @@ describe('DayPickerInput', () => {
         const onDayChange = jest.fn();
         const wrapper = mount(
           <DayPickerInput
-            value="02/08/2017"
+            value="2017-2-8"
             onDayChange={onDayChange}
             clickUnselectsDay
             dayPickerProps={{
@@ -314,7 +299,7 @@ describe('DayPickerInput', () => {
         const onDayChange = jest.fn();
         const wrapper = mount(
           <DayPickerInput
-            value="02/08/2017"
+            value="2017-2-8"
             onDayChange={onDayChange}
             dayPickerProps={{
               month: new Date(2017, 1),
diff --git a/test/daypickerinput/methods.js b/test/daypickerinput/methods.js
new file mode 100644
index 000000000..2bb6c1c82
--- /dev/null
+++ b/test/daypickerinput/methods.js
@@ -0,0 +1,53 @@
+import React from 'react';
+import { mount } from 'enzyme';
+
+import DayPickerInput, {
+  defaultFormat,
+  defaultParse,
+} from '../../src/DayPickerInput';
+import DayPicker from '../../src/DayPicker';
+
+describe('DayPickerInput', () => {
+  describe('methods', () => {
+    it('getInput should return the input field', () => {
+      const wrapper = mount(<DayPickerInput />);
+      const instance = wrapper.instance();
+      expect(instance.getInput().tagName.toLowerCase()).toBe('input');
+    });
+    it('getDayPicker should return the input field', () => {
+      const wrapper = mount(<DayPickerInput />);
+      const instance = wrapper.instance();
+      instance.showDayPicker();
+      wrapper.update();
+      expect(instance.getDayPicker()).toBeInstanceOf(DayPicker);
+    });
+  });
+  describe('defaultFormat', () => {
+    it('should return an empty string for invalid dates', () => {
+      const formatted = defaultFormat('foo');
+      expect(formatted).toBe('');
+    });
+    it('should format a date', () => {
+      const formatted = defaultFormat(new Date(2018, 6, 12));
+      expect(formatted).toBe('2018-7-12');
+    });
+  });
+  describe('defaultParse', () => {
+    it('should return `undefined` for not valid dates', () => {
+      expect(defaultParse('foo')).toBeUndefined();
+      expect(defaultParse({})).toBeUndefined();
+      expect(defaultParse(null)).toBeUndefined();
+      expect(defaultParse(new Date())).toBeUndefined();
+      expect(defaultParse('foo-10-11')).toBeUndefined();
+      expect(defaultParse('2017-foo-10')).toBeUndefined();
+      expect(defaultParse('2017-10-foo')).toBeUndefined();
+      expect(defaultParse('2012-2-0')).toBeUndefined();
+      expect(defaultParse('2012-0-20')).toBeUndefined();
+      expect(defaultParse('2012-13-20')).toBeUndefined();
+    });
+    it('should return a parsed date', () => {
+      const parsed = defaultParse('2018-7-12');
+      expect(parsed).toEqual(new Date(2018, 6, 12));
+    });
+  });
+});
diff --git a/test/daypickerinput/rendering.js b/test/daypickerinput/rendering.js
index 03d0a0fde..a1926750d 100644
--- a/test/daypickerinput/rendering.js
+++ b/test/daypickerinput/rendering.js
@@ -1,7 +1,6 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
 import { shallow, mount } from 'enzyme';
-import moment from 'moment';
 
 import DayPickerInput from '../../src/DayPickerInput';
 import DayPicker from '../../src/DayPicker';
@@ -12,7 +11,8 @@ describe('DayPickerInput', () => {
       const dayPicker = <DayPickerInput />;
       expect(dayPicker.props.dayPickerProps).toEqual({});
       expect(dayPicker.props.value).toBe('');
-      expect(dayPicker.props.format).toBe('L');
+      expect(typeof dayPicker.props.formatDate).toBe('function');
+      expect(typeof dayPicker.props.parseDate).toBe('function');
       expect(dayPicker.props.hideOnDayClick).toBe(true);
       expect(dayPicker.props.component).toBe('input');
     });
@@ -20,29 +20,6 @@ describe('DayPickerInput', () => {
       const wrapper = shallow(<DayPickerInput />);
       expect(wrapper).toHaveClassName('DayPickerInput');
     });
-    it('should set the month based on the specified format', () => {
-      const wrapper = shallow(
-        <DayPickerInput value="12/05/2010" format="DD/MM/YYYY" />
-      );
-      expect(wrapper.instance().state.month.getMonth()).toBe(4);
-      expect(wrapper.instance().state.month.getFullYear()).toBe(2010);
-    });
-    it('should not set the month if the value is not valid acording to `format`', () => {
-      const wrapper = shallow(
-        <DayPickerInput value="12/17/2010" format="DD/MM/YYYY" />
-      );
-      expect(wrapper.instance().state.month).toBeUndefined();
-    });
-    it('should accept multiple `format`s', () => {
-      const wrapper = shallow(
-        <DayPickerInput
-          value="2010/05/12"
-          format={['DD/MM/YYYY', 'YYYY/MM/DD']}
-        />
-      );
-      expect(wrapper.instance().state.month.getMonth()).toBe(4);
-      expect(wrapper.instance().state.month.getFullYear()).toBe(2010);
-    });
     it('should render an input field with the passed attributes', () => {
       const wrapper = shallow(
         <DayPickerInput value="12/14/2017" placeholder="bar" />
@@ -52,7 +29,7 @@ describe('DayPickerInput', () => {
       expect(input).toHaveProp('value', '12/14/2017');
       expect(input).toHaveProp('placeholder', 'bar');
     });
-    it('should work with not value dates', () => {
+    it('should work with not valid date as value', () => {
       const wrapper = shallow(
         <DayPickerInput value="very wrong" placeholder="bar" />
       );
@@ -62,6 +39,13 @@ describe('DayPickerInput', () => {
       wrapper.update();
       expect(wrapper.find(DayPicker)).toBeDefined();
     });
+    it('should work with a date object as value', () => {
+      const wrapper = shallow(
+        <DayPickerInput value={new Date(2018, 4, 12)} placeholder="bar" />
+      );
+      const input = wrapper.find('input');
+      expect(input).toHaveProp('value', '2018-5-12');
+    });
     it('should show the DayPicker', () => {
       const wrapper = shallow(<DayPickerInput />);
       wrapper.instance().showDayPicker();
@@ -111,7 +95,7 @@ describe('DayPickerInput', () => {
       expect(instance.daypicker.props.numberOfMonths).toBe(12);
     });
     it('should open the daypicker to the month of the selected day', () => {
-      const wrapper = mount(<DayPickerInput value="12/15/2017" />);
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
       wrapper.instance().showDayPicker();
       wrapper.update();
       expect(wrapper.find('.DayPicker-Caption div').first()).toHaveText(
@@ -119,7 +103,7 @@ describe('DayPickerInput', () => {
       );
     });
     it('should display the current value as a selected day', () => {
-      const wrapper = mount(<DayPickerInput value="12/15/2017" />);
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
       wrapper.instance().showDayPicker();
       wrapper.update();
       expect(wrapper.find('.DayPicker-Day--selected')).toHaveLength(1);
@@ -140,25 +124,29 @@ describe('DayPickerInput', () => {
       wrapper.instance().showDayPicker();
       wrapper.update();
       wrapper.find('.DayPicker-TodayButton').simulate('click');
-      expect(wrapper.find('input')).toHaveProp('value', moment().format('L'));
+      const today = new Date();
+      expect(wrapper.find('input')).toHaveProp(
+        'value',
+        `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`
+      );
     });
   });
   describe('updating props', () => {
     it('should update the current value when `value` prop is updated', () => {
-      const wrapper = mount(<DayPickerInput value="12/15/2017" />);
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
       wrapper.setProps({ value: '01/10/2018' });
       expect(wrapper.instance().state.value).toBe('01/10/2018');
     });
     it('should not update the current value when other props are updated', () => {
-      const wrapper = mount(<DayPickerInput value="12/15/2017" />);
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
       wrapper.setProps({ dayPickerProps: {} });
-      expect(wrapper.instance().state.value).toBe('12/15/2017');
+      expect(wrapper.instance().state.value).toBe('2017-12-15');
     });
     it("should update the displayed month when `dayPickerProps.month`'s month is updated", () => {
       const wrapper = mount(
         <DayPickerInput
           dayPickerProps={{ month: new Date(2017, 9) }}
-          value="12/15/2017"
+          value="2017-12-15"
         />
       );
       wrapper.instance().showDayPicker();
@@ -167,7 +155,7 @@ describe('DayPickerInput', () => {
         'December 2017'
       );
       wrapper.setProps({ dayPickerProps: { month: new Date(2017, 10) } });
-      expect(wrapper.instance().state.value).toBe('12/15/2017');
+      expect(wrapper.instance().state.value).toBe('2017-12-15');
       expect(wrapper.find('.DayPicker-Caption').first()).toHaveText(
         'November 2017'
       );
@@ -176,7 +164,7 @@ describe('DayPickerInput', () => {
       const wrapper = mount(
         <DayPickerInput
           dayPickerProps={{ month: new Date(2018, 10) }}
-          value="12/15/2017"
+          value="2017-12-15"
         />
       );
       wrapper.instance().showDayPicker();
@@ -185,28 +173,47 @@ describe('DayPickerInput', () => {
         'December 2017'
       );
       wrapper.setProps({ dayPickerProps: { month: new Date(2016, 10) } });
-      expect(wrapper.instance().state.value).toBe('12/15/2017');
+      expect(wrapper.instance().state.value).toBe('2017-12-15');
       expect(wrapper.find('.DayPicker-Caption').first()).toHaveText(
         'November 2016'
       );
     });
     it('should not change state if month did not change', () => {
-      const wrapper = mount(<DayPickerInput value="12/15/2017" />);
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
       wrapper.instance().showDayPicker();
       wrapper.update();
       expect(wrapper.find('.DayPicker-Caption').first()).toHaveText(
         'December 2017'
       );
       wrapper.setProps({ dayPickerProps: { month: new Date(2017, 11) } });
-      expect(wrapper.instance().state.value).toBe('12/15/2017');
+      expect(wrapper.instance().state.value).toBe('2017-12-15');
       expect(wrapper.find('.DayPicker-Caption').first()).toHaveText(
         'December 2017'
       );
     });
     it('should not update the current value when other props are updated', () => {
-      const wrapper = mount(<DayPickerInput value="12/15/2017" />);
-      wrapper.setProps({ dayPickerProps: {}, value: '12/15/2017' });
-      expect(wrapper.instance().state.value).toBe('12/15/2017');
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
+      wrapper.setProps({ dayPickerProps: {}, value: '2017-12-15' });
+      expect(wrapper.instance().state.value).toBe('2017-12-15');
+    });
+    it('should update the value when it is passed as Date', () => {
+      const wrapper = mount(<DayPickerInput value="2017-12-15" />);
+      wrapper.setProps({ dayPickerProps: {}, value: new Date(2017, 11, 16) });
+      expect(wrapper.instance().state.value).toBe('2017-12-16');
+    });
+    it('should update the selected days from prop', () => {
+      const wrapper = mount(
+        <DayPickerInput
+          dayPickerProps={{ selectedDays: new Date(2020, 2, 20) }}
+        />
+      );
+      wrapper.setProps({
+        dayPickerProps: { selectedDays: new Date(2020, 2, 10) },
+      });
+      wrapper.update();
+      expect(wrapper.instance().state.selectedDays).toEqual(
+        new Date(2020, 2, 10)
+      );
     });
   });
 });