Skip to content

Commit

Permalink
Merge pull request #3417 from mbrookes/datepicker-iso8601
Browse files Browse the repository at this point in the history
[DatePicker] Default to ISO-8601 DateTimeFormat & firstDayOfWeek
  • Loading branch information
alitaheri committed Feb 26, 2016
2 parents 2821529 + a295332 commit 100dfa2
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 41 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
- [RaisedButton] Fix:className now set to root element(#3122)
- [LeftNav] Fix:className and `style` now set to root element(#3322)
- [Colors] Removed default export in favor of singular exports (#2825) <br>
**Note** This can be temoporary worked around by changing <br>
**Note** This can be temporarily worked around by changing <br>
`import Colors from 'material-ui/lib/styles/colors';` <br> to <br>
`import * as Colors from 'material-ui/lib/styles/colors';`.
- [DatePicker] Standardize for ISO8601. (#3417)

## 0.14.4
###### _Feb 02, 2016_
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The roadmap is a living document, and it is likely that priorities will change,
- [x] Remove deprecated usage of JSON to generate children across the components.
- [x] [[#3108](https://github.com/callemall/material-ui/pull/3108)] Remove deprecated components, methods & props.
- [ ] [[#2957](https://github.com/callemall/material-ui/issues/2957)] Standardize callback signatures.
- [ ] [[#2980](https://github.com/callemall/material-ui/issues/2980)] [[#1839](https://github.com/callemall/material-ui/issues/1839)] Standardise Datepicker for ISO8601.
- [x] [[#2980](https://github.com/callemall/material-ui/issues/2980)] [[#1839](https://github.com/callemall/material-ui/issues/1839)] Standardise Datepicker for ISO8601.

#### Deprecations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,42 @@ import areIntlLocalesSupported from 'intl-locales-supported';

let DateTimeFormat;

// Use the native Intl if available
if (areIntlLocalesSupported('fr')) {
/**
* Use the native Intl.DateTimeFormat if available, or a polyfill if not.
*/
if (areIntlLocalesSupported(['fr', 'en-US'])) {
DateTimeFormat = global.Intl.DateTimeFormat;
} else {
const IntlPolyfill = require('intl');
require('intl/locale-data/jsonp/fr');

DateTimeFormat = IntlPolyfill.DateTimeFormat;
require('intl/locale-data/jsonp/fr');
require('intl/locale-data/jsonp/en-US');
}

const DatePickerExampleInternational = () => (
<DatePicker
hintText="fr version"
DateTimeFormat={DateTimeFormat}
// Intl is supported by most modern browsers, see http://caniuse.com/#search=intl
// for browsers that don't support it use this polyfill https://github.com/andyearnshaw/Intl.js
wordings={{ok: 'OK', cancel: 'Annuler'}}
firstDayOfWeek={1}
locale="fr"
/>
<div>
<DatePicker
hintText="fr locale"
DateTimeFormat={DateTimeFormat}
locale="fr"
wordings={{ok: 'OK', cancel: 'Annuler'}}
/>
<DatePicker
hintText="en-US locale"
DateTimeFormat={DateTimeFormat}
locale="en-US"
firstDayOfWeek={0}
/>
<DatePicker
hintText="Custom date format"
firstDayOfWeek={0}
formatDate={new DateTimeFormat('en-US', {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format}
/>
</div>
);

export default DatePickerExampleInternational;
8 changes: 6 additions & 2 deletions docs/src/app/components/pages/components/DatePicker/Page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ const descriptions = {
controlled: '`DatePicker` can be implemented as a controlled input, where `value` is handled by state in the ' +
'parent component.',
disabledDates: '`DatePicker` can disable specific dates based on the return value of a callback.',
localised: 'Date Picker can be localised using the `locale` property, in this case in French. ' +
'Note that the buttons must be localised using the `wordings` property, and we set the `firstDayOfWeek` to Monday.',
localised: '`DatePicker` can be localised using the `locale` property. The first example is localised in French. ' +
'Note that the buttons must be separately localised using the `cancelLabel` and `okLabel` properties. \n\n' +
'The `firstDayOfWeek` property defaults to `1`, (Monday), so may also need to be set for the target locale. ' +
'The second example shows sets `firstDayOfWeek` to `0`, (Sunday), and `locale` to `en-US` which matches the ' +
'bahavior of the Date Picker prior to 0.15.0.\n\n' +
'The final example displays the resulting date in a custom format using the `formatDate` property.',
};

const DatePickerPage = () => (
Expand Down
52 changes: 32 additions & 20 deletions src/date-picker/date-picker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ const DatePicker = React.createClass({

propTypes: {
/**
* Constructor for time formatting.
* Follow this specification: ECMAScript Internationalization API 1.0 (ECMA-402).
* Constructor for date formatting for the specified `locale`.
* The constructor must follow this specification: ECMAScript Internationalization API 1.0 (ECMA-402).
* `Intl.DateTimeFormat` is supported by most modern browsers, see http://caniuse.com/#search=intl,
* otherwise https://github.com/andyearnshaw/Intl.js is a good polyfill.
*/
DateTimeFormat: React.PropTypes.func,

Expand Down Expand Up @@ -43,23 +45,24 @@ const DatePicker = React.createClass({
disabled: React.PropTypes.bool,

/**
* Used to change the first day of week. It drastically varies from
* Saturday to Monday (could even be Friday) between different locales.
* Used to change the first day of week. It varies from
* Saturday to Monday between different locales.
* The allowed range is 0 (Sunday) to 6 (Saturday).
* The default is `1`, Monday, as per ISO 8601.
*/
firstDayOfWeek: React.PropTypes.number,

/**
* This function is called to format the date to display in the input box.
* By default, date objects are formatted to MM/DD/YYYY.
* This function is called to format the date displayed in the input box, and should return a string.
* By default if no `locale` and `DateTimeFormat` is provided date objects are formatted to ISO 8601 YYYY-MM-DD.
*
* @param {object} date `Date` object to be formatted.
*/
formatDate: React.PropTypes.func,

/**
* Locale used for formatting date. If you are not using the default value, you
* have to provide a DateTimeFormat that supports it. You can use Intl.DateTimeFormat
* if it's supported by your environment.
* https://github.com/andyearnshaw/Intl.js is a good polyfill.
* Locale used for formatting the dialog date strings. If you are not using the default value, you
* have to provide a `DateTimeFormat` that supports it.
*/
locale: React.PropTypes.string,

Expand Down Expand Up @@ -88,17 +91,17 @@ const DatePicker = React.createClass({
onChange: React.PropTypes.func,

/**
* Fired when the datepicker dialog is dismissed.
* Fired when the Date Picker dialog is dismissed.
*/
onDismiss: React.PropTypes.func,

/**
* Callback function that is fired when the datepicker field gains focus.
* Fired when the Date Picker field gains focus.
*/
onFocus: React.PropTypes.func,

/**
* Fired when the datepicker dialog is shown.
* Fired when the Date Picker dialog is shown.
*/
onShow: React.PropTypes.func,

Expand All @@ -109,7 +112,7 @@ const DatePicker = React.createClass({

/**
* Called during render time of a given day. If this method returns
* false the day is disabled otherwise it is displayed normally.
* false the day is disabled, otherwise it is displayed normally.
*/
shouldDisableDate: React.PropTypes.func,

Expand Down Expand Up @@ -149,11 +152,10 @@ const DatePicker = React.createClass({

getDefaultProps() {
return {
formatDate: DateTime.format,
autoOk: false,
disableYearSelection: false,
style: {},
firstDayOfWeek: 0,
firstDayOfWeek: 1,
disabled: false,
};
},
Expand Down Expand Up @@ -244,6 +246,18 @@ const DatePicker = React.createClass({
}
},

_formatDate(date) {
if (this.props.locale && this.props.DateTimeFormat) {
return new this.props.DateTimeFormat(this.props.locale, {
day: 'numeric',
month: 'numeric',
year: 'numeric',
}).format(date);
} else {
return DateTime.format(date);
}
},

render() {
const {
container,
Expand All @@ -252,7 +266,6 @@ const DatePicker = React.createClass({
wordings,
autoOk,
defaultDate,
formatDate,
maxDate,
minDate,
mode,
Expand All @@ -268,9 +281,8 @@ const DatePicker = React.createClass({
...other,
} = this.props;

const {
prepareStyles,
} = this.state.muiTheme;
const formatDate = this.props.formatDate || this._formatDate;
const {prepareStyles} = this.state.muiTheme;

return (
<div style={prepareStyles(Object.assign({}, style))}>
Expand Down
6 changes: 2 additions & 4 deletions src/utils/date-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,9 @@ export default {
return weekdayFormatter.format(this.addDays(firstDayDate, day + firstDayOfWeek));
},

// Convert date to ISO8601 (YYYY-MM-DD) date string, accounting for current timezone
format(date) {
const m = date.getMonth() + 1;
const d = date.getDate();
const y = date.getFullYear();
return `${m}/${d}/${y}`;
return (new Date(`${date.toDateString()} 12:00:00 +0000`)).toISOString().substring(0, 10);
},

/**
Expand Down

0 comments on commit 100dfa2

Please sign in to comment.