diff --git a/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md b/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
index 40d761fb0..5f2f188a1 100644
--- a/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
+++ b/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
@@ -4,7 +4,11 @@ summary: How to format and use the DateField class.
# DateField
This `FormField` subclass lets you display an editable date, in a single text input field.
-It also provides a calendar date picker.
+It implements the [HTML5 input date type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
+(with `type=date`). In supported browsers, this will cause a localised date picker to appear for users.
+HTML5 date fields present and save ISO 8601 date formats (`y-MM-dd`),
+since the browser takes care of converting to/from a localised presentation.
+Browsers without support receive an `` based polyfill.
The following example will add a simple DateField to your Page, allowing you to enter a date manually.
@@ -34,65 +38,28 @@ The following example will add a simple DateField to your Page, allowing you to
## Custom Date Format
A custom date format for a [api:DateField] can be provided through `setDateFormat`.
+This is only necessary if you want to opt-out of the built-in browser localisation via `type=date`.
:::php
- // will display a date in the following format: 31-06-2012
- DateField::create('MyDate')->setDateFormat('dd-MM-yyyy');
+ // will display a date in the following format: 31/06/2012
+ DateField::create('MyDate')
+ ->setHTML5(false)
+ ->setDateFormat('dd/MM/yyyy');
-The formats are based on [CLDR format](http://userguide.icu-project.org/formatparse/datetime).
+The formats are based on [ICU format](http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details).
## Min and Max Dates
Sets the minimum and maximum allowed date values using the `min` and `max` configuration settings (in ISO format or
-strtotime()).
+`strtotime()`).
:::php
DateField::create('MyDate')
->setMinDate('-7 days')
- ->setMaxDate'2012-12-31')
-
-## Separate Day / Month / Year Fields
-
-To display separate input fields for day, month and year separately you can use the `SeparatedDateField` subclass`.
-HTML5 placeholders 'day', 'month' and 'year' are enabled by default.
-
- :::php
- SeparatedDateField::create('MyDate');
-
-
-Any custom date format settings will be ignored.
-
-
-## Calendar Picker
-
-The following setting will add a Calendar to a single DateField, using the jQuery UI DatePicker widget.
-
- :::php
- DateField::create('MyDate')
- ->setShowCalendar(true);
-
-The jQuery date picker will support most custom locale formats (if left as default).
-If setting an explicit date format via setDateFormat() then the below table of supported
-characters should be used.
-
-It is recommended to use numeric format, as `MMM` or `MMMM` month names may not always pass validation.
-
-Constant | xxxxx
--------- | -----
-d | numeric day of the month (without leading zero)
-dd | numeric day of the month (with leading zero)
-EEE | dayname, abbreviated
-EEEE | dayname
-M | numeric month of the year (without leading zero)
-MM | numeric month of the year (with leading zero)
-MMM | monthname, abbreviated
-MMMM | monthname
-y | year (4 digits)
-yy | year (2 digits)
-yyyy | year (4 digits)
+ ->setMaxDate('2012-12-31')
## Formatting Hints
diff --git a/docs/en/02_Developer_Guides/13_i18n/index.md b/docs/en/02_Developer_Guides/13_i18n/index.md
index 46023817f..d7efc7ef9 100644
--- a/docs/en/02_Developer_Guides/13_i18n/index.md
+++ b/docs/en/02_Developer_Guides/13_i18n/index.md
@@ -71,18 +71,24 @@ and default alignment of paragraphs and tables to browsers.
### Date and time formats
-Formats can be set globally in the i18n class. These settings are currently only picked up by the CMS, you'll need
-to write your own logic for any frontend output.
+Formats can be set globally in the i18n class.
+You can use these settings for your own view logic.
:::php
Config::inst()->update('i18n', 'date_format', 'dd.MM.YYYY');
Config::inst()->update('i18n', 'time_format', 'HH:mm');
-Most localization routines in SilverStripe use the [Zend_Date API](http://framework.zend.com/manual/1.12/en/zend.date.overview.html).
-This means all formats are defined in
-[ISO date format](http://framework.zend.com/manual/1.12/en/zend.date.constants.html),
+Localization in SilverStripe uses PHP's [intl extension](http://php.net/intl).
+Formats for it's [IntlDateFormatter](http://php.net/manual/en/class.intldateformatter.php)
+are defined in [ICU format](http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details),
not PHP's built-in [date()](http://nz.php.net/manual/en/function.date.php).
+These settings are not used for CMS presentation.
+Users can choose their own locale, which determines the date format
+that gets presented to them. Currently this is a mix of PHP defaults (for readonly `DateField` and `TimeField`),
+browser defaults (for `DateField` on browsers supporting HTML5), and [Moment.JS](http://momentjs.com/)
+client-side logic (for `DateField` polyfills and other readonly dates and times).
+
### Language Names
SilverStripe comes with a built-in list of common languages, listed by locale and region.
@@ -126,32 +132,17 @@ Please refer to [W3C: Introduction to IDN and IRI](http://www.w3.org/Internation
### i18n in Form Fields
-Date- and time related form fields support i18n ([api:DateField], [api:TimeField], [api:DatetimeField]).
+Date and time related form fields are automatically localised ([api:DateField], [api:TimeField], [api:DatetimeField]).
+Since they use HTML5 `type=date` and `type=time` fields by default, these fields will present dates
+in a localised format chosen by the browser and operating system.
- :::php
- i18n::set_locale('ca_AD');
- $field = new DateField(); // will automatically set date format defaults for 'ca_AD'
- $field->setLocale('de_DE'); // will not update the date formats
- $field->setConfig('dateformat', 'dd. MMMM YYYY'); // sets typical 'de_DE' date format, shows as "23. Juni 1982"
-
-Defaults can be applied globally for all field instances through the `DateField.default_config`
-and `TimeField.default_config` [configuration arrays](/developer_guides/configuration).
-If no 'locale' default is set on the field, [api:i18n::get_locale()] will be used.
-
-**Important:** Form fields in the CMS are automatically configured according to the profile settings for the logged-in user (`Member->Locale`, `Member->DateFormat` and `Member->TimeFormat`). This means that in most cases,
-fields created through [api:DataObject::getCMSFields()] will get their i18n settings from a specific member
-
-The [api:DateField] API can be enhanced by JavaScript, and comes with
-[jQuery UI datepicker](http://jqueryui.com/demos/datepicker/) capabilities built-in.
-The field tries to translate the date formats and locales into a format compatible with jQuery UI
-(see [api:DateField_View_JQuery::$locale_map_] and [api:DateField_View_JQuery::convert_iso_to_jquery_format()]).
+Fields can be forced to use a certain locale and date/time format by calling `setHTML5(false)`,
+followed by `setLocale()` or `setDateFormat()`/`setTimeFormat()`.
:::php
$field = new DateField();
- $field->setLocale('de_AT'); // set Austrian/German locale
- $field->setConfig('showcalendar', true);
- $field->setConfig('jslocale', 'de'); // jQuery UI only has a generic German localization
- $field->setConfig('dateformat', 'dd. MMMM YYYY'); // will be transformed to 'dd. MM yy' for jQuery
+ $field->setLocale('de_AT'); // set Austrian/German locale, defaulting format to dd.MM.y
+ $field->setDateFormat('d.M.y'); // set a more specific date format (single digit day/month)
## Translating text
diff --git a/docs/en/04_Changelogs/4.0.0.md b/docs/en/04_Changelogs/4.0.0.md
index 5db6936df..09e3343ae 100644
--- a/docs/en/04_Changelogs/4.0.0.md
+++ b/docs/en/04_Changelogs/4.0.0.md
@@ -398,6 +398,19 @@ In templates this can also be invoked as below:
<%t MyObject.PLURALS 'An item|{count} items' count=$Count %>
+#### Removed Member.DateFormat and Member.TimeFormat database settings
+
+We're using [native HTML5 date and time pickers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
+in `DateField` and `TimeField` now ([discussion](https://github.com/silverstripe/silverstripe-framework/issues/6626)),
+where the browser localises the output based on the browser/system preferences.
+In this context it no longer makes sense to give users control over their own
+date and time formats in their CMS profile.
+Consequently, we've also removed `MemberDatetimeOptionsetField`.
+
+`Member->getDateFormat()` and `Member->getTimeFormat()` still exist, and default to
+the [IntlDateFormatter defaults](http://php.net/manual/en/class.intldateformatter.php) for the selected locale.
+
+
#### New asset storage mechanism
File system has been abstracted into an abstract interface. By default, the out of the box filesystem
@@ -1495,19 +1508,25 @@ New `DatetimeField` methods replace `getConfig()` / `setConfig()`:
New `DateField` methods replace `getConfig()` / `setConfig()`:
-* `getShowCalendar()` / `setShowCalendar()`
-* `getDateFormat()` / `setShowCalendar()`
+* `getDateFormat()` / `setDateFormat()`
* `getMinDate()` / `setMinDate()`
* `getMaxDate()` / `setMaxDate()`
-* `getPlaceholders()` / `setPlaceholders()`
-* `getClientLocale` / `setClientLocale`
* `getLocale()` / `setLocale()`
-* option `dmyfields` is now superceded with an `SeparatedDateField` class
+
+The `DateField` has changed behavior:
+
+* `DateField` no longer provides a jQuery UI date picker (`showcalendar` option),
+ and uses [HTML5 date pickers](https://www.wufoo.com/html5/types/4-date.html) by default instead.
+* `DateField` provides an optional polyfill for
+ [browsers without HTML5 date picker support](http://caniuse.com/#feat=input-datetime)
+* The `dmyfields` option has been replced with native HTML5 behaviour (as one single ``).
+* `getClientLocale` / `setClientLocale` have been removed (handled by `DateField->locale` and browser settings)
New `TimeField` methods replace `getConfig()` / `setConfig()`
* `getTimeFormat()` / `setTimeFormat()`
* `getLocale()` / `setLocale()`
+* `getClientConfig()` has been removed (in favour of `setHTML5()`)
#### Template and Form Removed API
@@ -1549,7 +1568,9 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
* `set_source_file_comments()`
* `get_source_file_comments()`
* `getOption`
- * `setOption`
+ * `setOption`
+* Removed `MemberDatetimeOptionsetField` (no replacement)
+* Removed `DateField_View_JQuery` (replaced with native HTML5 support in `DateField`)
### i18n API
diff --git a/src/Forms/DateField.php b/src/Forms/DateField.php
index ea3e3a7dc..b3da3be06 100644
--- a/src/Forms/DateField.php
+++ b/src/Forms/DateField.php
@@ -5,6 +5,7 @@ namespace SilverStripe\Forms;
use IntlDateFormatter;
use SilverStripe\i18n\i18n;
use InvalidArgumentException;
+use SilverStripe\ORM\FieldType\DBDate;
use SilverStripe\ORM\FieldType\DBDatetime;
/**
@@ -85,13 +86,6 @@ class DateField extends TextField
*/
protected $dateLength = null;
- /**
- * Set whether to show placeholders
- *
- * @var bool
- */
- protected $placeholders = true;
-
/**
* Override locale for client side.
*
@@ -122,25 +116,27 @@ class DateField extends TextField
protected $rawValue = null;
/**
- * Check if calendar should be shown on the frontend
+ * Use HTML5-based input fields (and force ISO 8601 date formats).
*
+ * @var bool
+ */
+ protected $html5 = true;
+
+ /**
* @return bool
*/
- public function getShowCalendar()
+ public function getHTML5()
{
- return $this->showCalendar;
+ return $this->html5;
}
/**
- * Set if calendar should be shown on the frontend.
- * @internal WARNING: Experimental and volatile API.
- *
- * @param bool $show
+ * @param boolean $bool
* @return $this
*/
- public function setShowCalendar($show)
+ public function setHTML5($bool)
{
- $this->showCalendar = $show;
+ $this->html5 = $bool;
return $this;
}
@@ -164,12 +160,8 @@ class DateField extends TextField
}
/**
- * Get length of the date format to use. One of:
- *
- * - IntlDateFormatter::SHORT
- * - IntlDateFormatter::MEDIUM
- * - IntlDateFormatter::LONG
- * - IntlDateFormatter::FULL
+ * Get length of the date format to use.
+ * Only applicable with {@link setHTML5(false)}.
*
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
*
@@ -192,6 +184,11 @@ class DateField extends TextField
*/
public function getDateFormat()
{
+ if ($this->getHTML5()) {
+ // Browsers expect ISO 8601 dates, localisation is handled on the client
+ $this->setDateFormat(DBDate::ISO_DATE);
+ }
+
if ($this->dateFormat) {
return $this->dateFormat;
}
@@ -202,6 +199,7 @@ class DateField extends TextField
/**
* Set date format in CLDR standard format.
+ * Only applicable with {@link setHTML5(false)}.
*
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
* @param string $format
@@ -216,18 +214,40 @@ class DateField extends TextField
/**
* Get date formatter with the standard locale / date format
*
+ * @throws \LogicException
* @return IntlDateFormatter
*/
protected function getFormatter()
{
+ if ($this->getHTML5() && $this->dateFormat && $this->dateFormat !== DBDate::ISO_DATE) {
+ throw new \LogicException(
+ 'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setDateFormat()'
+ );
+ }
+
+ if ($this->getHTML5() && $this->dateLength) {
+ throw new \LogicException(
+ 'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setDateLength()'
+ );
+ }
+
+ if ($this->getHTML5() && $this->locale) {
+ throw new \LogicException(
+ 'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setLocale()'
+ );
+ }
+
$formatter = IntlDateFormatter::create(
$this->getLocale(),
$this->getDateLength(),
IntlDateFormatter::NONE
);
- // Don't invoke getDateFormat() directly to avoid infinite loop
- if ($this->dateFormat) {
+ if ($this->getHTML5()) {
+ // Browsers expect ISO 8601 dates, localisation is handled on the client
+ $formatter->setPattern(DBDate::ISO_DATE);
+ } elseif ($this->dateFormat) {
+ // Don't invoke getDateFormat() directly to avoid infinite loop
$ok = $formatter->setPattern($this->dateFormat);
if (!$ok) {
throw new InvalidArgumentException("Invalid date format {$this->dateFormat}");
@@ -243,59 +263,28 @@ class DateField extends TextField
*/
protected function getISO8601Formatter()
{
+ $locale = i18n::config()->uninherited('default_locale');
$formatter = IntlDateFormatter::create(
i18n::config()->uninherited('default_locale'),
IntlDateFormatter::MEDIUM,
IntlDateFormatter::NONE
);
$formatter->setLenient(false);
- // CLDR iso8601 date.
- $formatter->setPattern('y-MM-dd');
+ // CLDR ISO 8601 date.
+ $formatter->setPattern(DBDate::ISO_DATE);
return $formatter;
}
- public function FieldHolder($properties = array())
- {
- return $this->renderWithClientView(function () use ($properties) {
- return parent::FieldHolder($properties);
- });
- }
-
- public function SmallFieldHolder($properties = array())
- {
- return $this->renderWithClientView(function () use ($properties) {
- return parent::SmallFieldHolder($properties);
- });
- }
-
- /**
- * Generate field with client view enabled
- *
- * @param callable $callback
- * @return string
- */
- protected function renderWithClientView($callback)
- {
- $clientView = null;
- if ($this->getShowCalendar()) {
- $clientView = $this->getClientView();
- $clientView->onBeforeRender();
- }
- $html = $callback();
- if ($clientView) {
- $html = $clientView->onAfterRender($html);
- }
- return $html;
- }
-
public function getAttributes()
{
$attributes = parent::getAttributes();
- // Merge with client config
- $config = $this->getClientConfig();
- foreach ($config as $key => $value) {
- $attributes["data-{$key}"] = $value;
+ $attributes['lang'] = i18n::convert_rfc1766($this->getLocale());
+
+ if ($this->getHTML5()) {
+ $attributes['type'] = 'date';
+ $attributes['min'] = $this->getMinDate();
+ $attributes['max'] = $this->getMaxDate();
}
return $attributes;
@@ -434,7 +423,9 @@ class DateField extends TextField
}
/**
- * Caution: Will not update the 'dateformat' config value.
+ * Determines the presented/processed format based on locale defaults,
+ * instead of explicitly setting {@link setDateFormat()}.
+ * Only applicable with {@link setHTML5(false)}.
*
* @param string $locale
* @return $this
@@ -445,29 +436,6 @@ class DateField extends TextField
return $this;
}
- /**
- * Get locale code for client-side. Will default to getLocale() if omitted.
- *
- * @return string
- */
- public function getClientLocale()
- {
- if ($this->clientLocale) {
- return $this->clientLocale;
- }
- return $this->getLocale();
- }
-
- /**
- * @param string $clientLocale
- * @return DateField
- */
- public function setClientLocale($clientLocale)
- {
- $this->clientLocale = $clientLocale;
- return $this;
- }
-
public function getSchemaValidation()
{
$rules = parent::getSchemaValidation();
@@ -475,28 +443,6 @@ class DateField extends TextField
return $rules;
}
- /**
- * If placeholders are shown
- *
- * @return bool
- */
- public function getPlaceholders()
- {
- return $this->placeholders;
- }
-
- /**
- * Set if placeholders are shown
- *
- * @param bool $placeholders
- * @return $this
- */
- public function setPlaceholders($placeholders)
- {
- $this->placeholders = $placeholders;
- return $this;
- }
-
/**
* @return string
*/
@@ -533,35 +479,6 @@ class DateField extends TextField
return $this;
}
- /**
- * Get client data properties for this field
- *
- * @return array
- */
- public function getClientConfig()
- {
- $view = $this->getClientView();
- $config = [
- 'showcalendar' => $this->getShowCalendar() ? 'true' : null,
- 'date-format' => $view->getDateFormat(), // https://api.jqueryui.com/datepicker/#option-dateFormat
- 'locale' => $view->getLocale(),
- ];
-
- // Format min/maxDate in format expected by jquery datepicker
- $min = $this->getMinDate();
- if ($min) {
- // https://api.jqueryui.com/datepicker/#option-minDate
- $config['min-date'] = $this->iso8601ToLocalised($min);
- }
- $max = $this->getMaxDate();
- if ($max) {
- // https://api.jqueryui.com/datepicker/#option-maxDate
- $config['max-date'] = $this->iso8601ToLocalised($max);
- }
-
- return $config;
- }
-
/**
* Convert date localised in the current locale to ISO 8601 date
*
@@ -627,12 +544,4 @@ class DateField extends TextField
}
return $formatter->format($timestamp);
}
-
- /**
- * @return DateField_View_JQuery
- */
- protected function getClientView()
- {
- return DateField_View_JQuery::create($this);
- }
}
diff --git a/src/Forms/DateField_View_JQuery.php b/src/Forms/DateField_View_JQuery.php
deleted file mode 100644
index b00539b80..000000000
--- a/src/Forms/DateField_View_JQuery.php
+++ /dev/null
@@ -1,197 +0,0 @@
- 'en-GB',
- 'en_US' => 'en',
- 'en_NZ' => 'en-GB',
- 'fr_CH' => 'fr',
- 'pt_BR' => 'pt-BR',
- 'sr_SR' => 'sr-SR',
- 'zh_CN' => 'zh-CN',
- 'zh_HK' => 'zh-HK',
- 'zh_TW' => 'zh-TW',
- );
-
- /**
- * @param DateField $field
- */
- public function __construct($field)
- {
- $this->field = $field;
-
- // Health check
- if (!$this->localePath('en')) {
- throw new InvalidArgumentException("Missing jquery config");
- }
- }
-
- /**
- * @return DateField
- */
- public function getField()
- {
- return $this->field;
- }
-
- /**
- * Get path to localisation file for a given locale, if it exists
- *
- * @param string $lang
- * @return string Relative path to file, or null if it isn't available
- */
- protected function localePath($lang)
- {
- $path = ADMIN_THIRDPARTY_DIR . "/jquery-ui/datepicker/i18n/jquery.ui.datepicker-{$lang}.js";
- if (file_exists(BASE_PATH . '/' . $path)) {
- return $path;
- }
- return null;
- }
-
- public function onBeforeRender()
- {
- }
-
- /**
- * @param String $html
- * @return string
- */
- public function onAfterRender($html)
- {
- if ($this->getField()->getShowCalendar()) {
- // Load config for this locale if available
- $locale = $this->getLocale();
- $localeFile = $this->localePath($locale);
- if ($localeFile) {
- Requirements::javascript($localeFile);
- }
- }
-
- return $html;
- }
-
- /**
- * Determines which language to use for jQuery UI, which
- * can be different from the value set in i18n.
- *
- * @return string
- */
- public function getLocale()
- {
- $locale = $this->getField()->getClientLocale();
-
- // Check standard mappings
- $map = Config::inst()->get(__CLASS__, 'locale_map');
- if (array_key_exists($locale, $map)) {
- return $map[$locale];
- }
-
- // Fall back to default lang (meaning "en_US" turns into "en")
- return i18n::getData()->langFromLocale($locale);
- }
-
- /**
- * Convert iso to jquery UI date format.
- * Needs to be consistent with Zend formatting, otherwise validation will fail.
- * Removes all time settings like hour/minute/second from the format.
- * See http://docs.jquery.com/UI/Datepicker/formatDate
- * From http://userguide.icu-project.org/formatparse/datetime
- *
- * @param string $format
- * @return string
- */
- public static function convert_iso_to_jquery_format($format)
- {
- $convert = array(
- '/([^d])d([^d])/' => '$1d$2',
- '/^d([^d])/' => 'd$1',
- '/([^d])d$/' => '$1d',
- '/dd/' => 'dd',
- '/SS/' => '',
- '/eee/' => 'd',
- '/e/' => 'N',
- '/D/' => '',
- '/EEEE/' => 'DD',
- '/EEE/' => 'D',
- '/w/' => '',
- // make single "M" lowercase
- '/([^M])M([^M])/' => '$1m$2',
- // make single "M" at start of line lowercase
- '/^M([^M])/' => 'm$1',
- // make single "M" at end of line lowercase
- '/([^M])M$/' => '$1m',
- // match exactly three capital Ms not preceeded or followed by an M
- '/(? 'M',
- // match exactly two capital Ms not preceeded or followed by an M
- '/(? 'mm',
- // match four capital Ms (maximum allowed)
- '/MMMM/' => 'MM',
- '/l/' => '',
- '/YYYY/' => 'yy',
- '/yyyy/' => 'yy',
- // See http://open.silverstripe.org/ticket/7669
- '/y{1,3}/' => 'yy',
- '/a/' => '',
- '/B/' => '',
- '/hh/' => '',
- '/h/' => '',
- '/([^H])H([^H])/' => '',
- '/^H([^H])/' => '',
- '/([^H])H$/' => '',
- '/HH/' => '',
- // '/mm/' => '',
- '/ss/' => '',
- '/zzzz/' => '',
- '/I/' => '',
- '/ZZZZ/' => '',
- '/Z/' => '',
- '/z/' => '',
- '/X/' => '',
- '/r/' => '',
- '/U/' => '',
- );
- $patterns = array_keys($convert);
- $replacements = array_values($convert);
-
- return preg_replace($patterns, $replacements, $format);
- }
-
- /**
- * Get client date format
- *
- * @return string
- */
- public function getDateFormat()
- {
- return static::convert_iso_to_jquery_format($this->getField()->getDateFormat());
- }
-}
diff --git a/src/Forms/DatetimeField.php b/src/Forms/DatetimeField.php
index 4190e2d3e..b47933faa 100644
--- a/src/Forms/DatetimeField.php
+++ b/src/Forms/DatetimeField.php
@@ -13,6 +13,10 @@ use SilverStripe\i18n\i18n;
* If you want to save into {@link Date} or {@link Time} columns,
* please instanciate the fields separately.
*
+ * This field does not implement the HTML5 field,
+ * but can use date and time HTML5 inputs separately (through {@link DateField->setHTML5()}
+ * and {@link TimeField->setHTML5()}.
+ *
* # Configuration
*
* Individual options are configured either on the DatetimeField, or on individual
diff --git a/src/Forms/SeparatedDateField.php b/src/Forms/SeparatedDateField.php
deleted file mode 100644
index 8580a1e48..000000000
--- a/src/Forms/SeparatedDateField.php
+++ /dev/null
@@ -1,177 +0,0 @@
-iso8601ToArray($this->dataValue());
- $fieldDay = NumericField::create($this->name . '[day]', false, $valArr ? $valArr['day'] : null)
- ->addExtraClass('day')
- ->setHTML5(true)
- ->setMaxLength(2);
- $fieldMonth = NumericField::create($this->name . '[month]', false, $valArr ? $valArr['month'] : null)
- ->addExtraClass('month')
- ->setHTML5(true)
- ->setMaxLength(2);
- $fieldYear = NumericField::create($this->name . '[year]', false, $valArr ? $valArr['year'] : null)
- ->addExtraClass('year')
- ->setHTML5(true)
- ->setMaxLength(4);
-
- // Set placeholders
- if ($this->getPlaceholders()) {
- $fieldDay->setAttribute('placeholder', _t(__CLASS__ . '.DAY', 'Day'));
- $fieldMonth->setAttribute('placeholder', _t(__CLASS__ . '.MONTH', 'Month'));
- $fieldYear->setAttribute('placeholder', _t(__CLASS__ . '.YEAR', 'Year'));
- }
-
- $format = $this->getDateFormat();
- $validFormat = (
- stripos($format, 'd') !== false
- && stripos($format, 'm') !== false
- && stripos($format, 'y') !== false
- );
- if (!$validFormat) {
- throw new \InvalidArgumentException(
- 'Invalid date format for field ordering: ' . $format
- . '. Requires "d", "m", and "y" values to determine order'
- );
- }
-
- $fields = array();
- $fields[stripos($format, 'd')] = $fieldDay->Field();
- $fields[stripos($format, 'm')] = $fieldMonth->Field();
- $fields[stripos($format, 'y')] = $fieldYear->Field();
- ksort($fields);
-
-
- // Join all fields
- $sep = ' ' . $this->getSeparator() . ' ';
- return implode($sep, $fields);
- }
-
- /**
- * @param $string
- * @return self
- */
- public function setSeparator($separator)
- {
- $this->separator = $separator;
- return $this;
- }
-
- /**
- * @return string
- */
- public function getSeparator()
- {
- return $this->separator;
- }
-
- /**
- * Convert array to timestamp
- *
- * @param array $value
- * @return string
- */
- public function arrayToISO8601($value)
- {
- if ($this->isEmptyArray($value)) {
- return null;
- }
-
- // ensure all keys are specified
- if (!isset($value['month']) || !isset($value['day']) || !isset($value['year'])) {
- return null;
- }
-
- // Ensure valid range
- if (!checkdate($value['month'], $value['day'], $value['year'])) {
- return null;
- }
-
- // Note: Set formatter to strict for array input
- $formatter = $this->getISO8601Formatter();
- $timestamp = mktime(0, 0, 0, $value['month'], $value['day'], $value['year']);
- if ($timestamp === false) {
- return null;
- }
- return $formatter->format($timestamp);
- }
-
- /**
- * Convert iso 8601 date to array (day / month / year)
- *
- * @param string $date
- * @return array|null Array form, or null if not valid
- */
- public function iso8601ToArray($date)
- {
- if (!$date) {
- return null;
- }
- $formatter = $this->getISO8601Formatter();
- $timestamp = $formatter->parse($date);
- if ($timestamp === false) {
- return null;
- }
-
- // Format time manually into an array
- return [
- 'day' => date('j', $timestamp),
- 'month' => date('n', $timestamp),
- 'year' => date('Y', $timestamp),
- ];
- }
-
- /**
- * Assign value posted from form submission
- *
- * @param mixed $value
- * @param mixed $data
- * @return $this
- */
- public function setSubmittedValue($value, $data = null)
- {
- // Filter out empty arrays
- if ($this->isEmptyArray($value)) {
- $value = null;
- }
- $this->rawValue = $value;
-
- // Null case
- if (!$value || !is_array($value)) {
- $this->value = null;
- return $this;
- }
-
- // Parse
- $this->value = $this->arrayToISO8601($value);
- return $this;
- }
-
- /**
- * Check if this array is empty
- *
- * @param $value
- * @return bool
- */
- public function isEmptyArray($value)
- {
- return is_array($value) && !array_filter($value);
- }
-}
diff --git a/src/Forms/TimeField.php b/src/Forms/TimeField.php
index ee5427510..94d480236 100644
--- a/src/Forms/TimeField.php
+++ b/src/Forms/TimeField.php
@@ -6,6 +6,7 @@ use IntlDateFormatter;
use InvalidArgumentException;
use SilverStripe\i18n\i18n;
use SilverStripe\ORM\FieldType\DBDatetime;
+use SilverStripe\ORM\FieldType\DBTime;
/**
* Form field to display editable time values in an field.
@@ -57,6 +58,31 @@ class TimeField extends TextField
*/
protected $timezone = null;
+ /**
+ * Use HTML5-based input fields (and force ISO 8601 time formats).
+ *
+ * @var bool
+ */
+ protected $html5 = true;
+
+ /**
+ * @return bool
+ */
+ public function getHTML5()
+ {
+ return $this->html5;
+ }
+
+ /**
+ * @param boolean $bool
+ * @return $this
+ */
+ public function setHTML5($bool)
+ {
+ $this->html5 = $bool;
+ return $this;
+ }
+
/**
* Get time format in CLDR standard format
*
@@ -67,6 +93,11 @@ class TimeField extends TextField
*/
public function getTimeFormat()
{
+ if ($this->getHTML5()) {
+ // Browsers expect ISO 8601 times, localisation is handled on the client
+ $this->setTimeFormat(DBTime::ISO_TIME);
+ }
+
if ($this->timeFormat) {
return $this->timeFormat;
}
@@ -77,6 +108,7 @@ class TimeField extends TextField
/**
* Set time format in CLDR standard format.
+ * Only applicable with {@link setHTML5(false)}.
*
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
* @param string $format
@@ -108,12 +140,8 @@ class TimeField extends TextField
}
/**
- * Get length of the time format to use. One of:
- *
- * - IntlDateFormatter::SHORT E.g. '6:31 PM'
- * - IntlDateFormatter::MEDIUM E.g. '6:30:48 PM'
- * - IntlDateFormatter::LONG E.g. '6:32:09 PM NZDT'
- * - IntlDateFormatter::FULL E.g. '6:32:24 PM New Zealand Daylight Time'
+ * Get length of the time format to use.
+ * Only applicable with {@link setHTML5(false)}.
*
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
*
@@ -133,6 +161,24 @@ class TimeField extends TextField
*/
protected function getFormatter()
{
+ if ($this->getHTML5() && $this->timeFormat && $this->timeFormat !== DBTime::ISO_TIME) {
+ throw new \LogicException(
+ 'Please opt-out of HTML5 processing of ISO 8601 times via setHTML5(false) if using setTimeFormat()'
+ );
+ }
+
+ if ($this->getHTML5() && $this->timeLength) {
+ throw new \LogicException(
+ 'Please opt-out of HTML5 processing of ISO 8601 times via setHTML5(false) if using setTimeLength()'
+ );
+ }
+
+ if ($this->getHTML5() && $this->locale) {
+ throw new \LogicException(
+ 'Please opt-out of HTML5 processing of ISO 8601 times via setHTML5(false) if using setLocale()'
+ );
+ }
+
$formatter = IntlDateFormatter::create(
$this->getLocale(),
IntlDateFormatter::NONE,
@@ -140,8 +186,11 @@ class TimeField extends TextField
$this->getTimezone()
);
- // Don't invoke getDateFormat() directly to avoid infinite loop
- if ($this->timeFormat) {
+ if ($this->getHTML5()) {
+ // Browsers expect ISO 8601 times, localisation is handled on the client
+ $formatter->setPattern(DBTime::ISO_TIME);
+ // Don't invoke getTimeFormat() directly to avoid infinite loop
+ } elseif ($this->timeFormat) {
$ok = $formatter->setPattern($this->timeFormat);
if (!$ok) {
throw new InvalidArgumentException("Invalid time format {$this->timeFormat}");
@@ -164,35 +213,22 @@ class TimeField extends TextField
date_default_timezone_get() // Default to server timezone
);
$formatter->setLenient(false);
- // CLDR iso8601 time
+
// Note we omit timezone from this format, and we assume server TZ always.
- $formatter->setPattern('HH:mm:ss');
+ $formatter->setPattern(DBTime::ISO_TIME);
+
return $formatter;
}
- public function getAttribute($name)
+ public function getAttributes()
{
$attributes = parent::getAttributes();
- // Merge with client config
- $config = $this->getClientConfig();
- foreach ($config as $key => $value) {
- $attributes["data-{$key}"] = $value;
+ if ($this->getHTML5()) {
+ $attributes['type'] = 'time';
}
- return $attributes;
- }
- /**
- * Get client config options for this field
- *
- * @return array
- */
- public function getClientConfig()
- {
- return [
- // @todo - Support javascript time picker
- 'timeformat' => $this->getTimeFormat(),
- ];
+ return $attributes;
}
public function Type()
@@ -302,6 +338,10 @@ class TimeField extends TextField
}
/**
+ * Determines the presented/processed format based on locale defaults,
+ * instead of explicitly setting {@link setTimeFormat()}.
+ * Only applicable with {@link setHTML5(false)}.
+ *
* @param string $locale
* @return $this
*/
@@ -337,9 +377,19 @@ class TimeField extends TextField
$fromFormatter = $this->getFormatter();
$toFormatter = $this->getISO8601Formatter();
$timestamp = $fromFormatter->parse($time);
+
+ // Try to parse time without seconds, since that's a valid HTML5 submission format
+ // See https://html.spec.whatwg.org/multipage/infrastructure.html#times
+ if ($timestamp === false && $this->getHTML5()) {
+ $fromFormatter->setPattern('HH:mm');
+ $timestamp = $fromFormatter->parse($time);
+ }
+
+ // If timestamp still can't be detected, we've got an invalid time
if ($timestamp === false) {
return null;
}
+
return $toFormatter->format($timestamp);
}
diff --git a/src/ORM/FieldType/DBDate.php b/src/ORM/FieldType/DBDate.php
index 1e1fd26e8..4eeb6a0a7 100644
--- a/src/ORM/FieldType/DBDate.php
+++ b/src/ORM/FieldType/DBDate.php
@@ -512,17 +512,7 @@ class DBDate extends DBField
public function scaffoldFormField($title = null, $params = null)
{
$field = DateField::create($this->name, $title);
- $format = $field->getDateFormat();
-
- // Show formatting hints for better usability
- $now = DBDatetime::now()->Format($format);
- $field->setDescription(_t(
- 'FormField.EXAMPLE',
- 'e.g. {format}',
- 'Example format',
- [ 'format' => $now ]
- ));
- $field->setAttribute('placeholder', $format);
+ $field->setHTML5(true);
return $field;
}
diff --git a/src/ORM/FieldType/DBTime.php b/src/ORM/FieldType/DBTime.php
index d6eac7f06..b0e596956 100644
--- a/src/ORM/FieldType/DBTime.php
+++ b/src/ORM/FieldType/DBTime.php
@@ -141,19 +141,7 @@ class DBTime extends DBField
public function scaffoldFormField($title = null, $params = null)
{
- $field = TimeField::create($this->name, $title);
- $format = $field->getTimeFormat();
-
- // Show formatting hints for better usability
- $now = DBDatetime::now()->Format($format);
- $field->setDescription(_t(
- 'FormField.Example',
- 'e.g. {format}',
- 'Example format',
- [ 'format' => $now ]
- ));
- $field->setAttribute('placeholder', $format);
- return $field;
+ return TimeField::create($this->name, $title);
}
/**
diff --git a/src/Security/Member.php b/src/Security/Member.php
index e7090a706..22174dcc2 100644
--- a/src/Security/Member.php
+++ b/src/Security/Member.php
@@ -19,7 +19,6 @@ use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HTMLEditor\HTMLEditorConfig;
use SilverStripe\Forms\ListboxField;
-use SilverStripe\Forms\MemberDatetimeOptionsetField;
use SilverStripe\i18n\i18n;
use SilverStripe\MSSQL\MSSQLDatabase;
use SilverStripe\ORM\ArrayList;
@@ -81,9 +80,6 @@ class Member extends DataObject implements TemplateGlobalProvider
'Locale' => 'Varchar(6)',
// handled in registerFailedLogin(), only used if $lock_out_after_incorrect_logins is set
'FailedLoginCount' => 'Int',
- // In ISO format
- 'DateFormat' => 'Varchar(30)',
- 'TimeFormat' => 'Varchar(30)',
);
private static $belongs_many_many = array(
@@ -1315,19 +1311,23 @@ class Member extends DataObject implements TemplateGlobalProvider
}
/**
- * Override the default getter for DateFormat so the
- * default format for the user's locale is used
- * if the user has not defined their own.
+ * Return the date format based on the user's chosen locale,
+ * falling back to the default format defined by the {@link i18n.get_locale()} setting.
*
* @return string ISO date format
*/
public function getDateFormat()
{
- $format = $this->getField('DateFormat');
- if ($format) {
- return $format;
- }
- return $this->getDefaultDateFormat();
+ $formatter = new IntlDateFormatter(
+ $this->getLocale(),
+ IntlDateFormatter::MEDIUM,
+ IntlDateFormatter::NONE
+ );
+ $format = $formatter->getPattern();
+
+ $this->extend('updateDateFormat', $format);
+
+ return $format;
}
/**
@@ -1343,19 +1343,23 @@ class Member extends DataObject implements TemplateGlobalProvider
}
/**
- * Override the default getter for TimeFormat so the
- * default format for the user's locale is used
- * if the user has not defined their own.
+ * Return the time format based on the user's chosen locale,
+ * falling back to the default format defined by the {@link i18n.get_locale()} setting.
*
* @return string ISO date format
*/
public function getTimeFormat()
{
- $timeFormat = $this->getField('TimeFormat');
- if ($timeFormat) {
- return $timeFormat;
- }
- return $this->getDefaultTimeFormat();
+ $formatter = new IntlDateFormatter(
+ $this->getLocale(),
+ IntlDateFormatter::NONE,
+ IntlDateFormatter::MEDIUM
+ );
+ $format = $formatter->getPattern();
+
+ $this->extend('updateTimeFormat', $format);
+
+ return $format;
}
//---------------------------------------------------------------------//
@@ -1592,112 +1596,11 @@ class Member extends DataObject implements TemplateGlobalProvider
if ($permissionsTab) {
$permissionsTab->addExtraClass('readonly');
}
-
- // Date format selecter
- $mainFields->push(
- $dateFormatField = new MemberDatetimeOptionsetField(
- 'DateFormat',
- $this->fieldLabel('DateFormat'),
- $this->getDateFormats()
- )
- );
- $formatClass = get_class($dateFormatField);
- $dateFormatField->setValue($this->DateFormat);
- $dateTemplate = SSViewer::get_templates_by_class($formatClass, '_description_date', $formatClass);
- $dateFormatField->setDescriptionTemplate($dateTemplate);
-
- // Time format selector
- $mainFields->push(
- $timeFormatField = new MemberDatetimeOptionsetField(
- 'TimeFormat',
- $this->fieldLabel('TimeFormat'),
- $this->getTimeFormats()
- )
- );
- $timeFormatField->setValue($this->TimeFormat);
- $timeTemplate = SSViewer::get_templates_by_class($formatClass, '_description_time', $formatClass);
- $timeFormatField->setDescriptionTemplate($timeTemplate);
});
return parent::getCMSFields();
}
- /**
- * Get list of date formats with example values
- *
- * @return array
- */
- protected function getDateFormats()
- {
- $defaultDateFormat = $this->getDefaultDateFormat();
- $formats = [
- 'MMM d, y' => null,
- 'yyyy/MM/dd' => null,
- 'MM/dd/y' => null,
- 'dd/MM/y' => null,
- ];
- unset($formats[$defaultDateFormat]);
- $formats[$defaultDateFormat] = null;
- // Fill in each format with example
- foreach (array_keys($formats) as $format) {
- $formats[$format] = DBDatetime::now()->Format($format);
- }
- // Mark default format
- $formats[$defaultDateFormat] .= sprintf(' (%s)', _t('Member.DefaultDateTime', 'default'));
- return $formats;
- }
-
- /**
- * @return string
- */
- public function getDefaultDateFormat()
- {
- $formatter = new IntlDateFormatter(
- $this->getLocale(),
- IntlDateFormatter::MEDIUM,
- IntlDateFormatter::NONE
- );
- return $formatter->getPattern();
- }
-
- /**
- * @return string
- */
- public function getDefaultTimeFormat()
- {
- $formatter = new IntlDateFormatter(
- $this->getLocale(),
- IntlDateFormatter::NONE,
- IntlDateFormatter::MEDIUM
- );
- $defaultTimeFormat = $formatter->getPattern();
- return $defaultTimeFormat;
- }
-
-
- /**
- * Get list of date formats with example values
- *
- * @return array
- */
- protected function getTimeFormats()
- {
- $defaultTimeFormat = $this->getDefaultTimeFormat();
- $formats = [
- 'h:mm a' => null,
- 'H:mm' => null,
- ];
- unset($formats[$defaultTimeFormat]);
- $formats[$defaultTimeFormat] = null;
- // Fill in each format with example
- foreach (array_keys($formats) as $format) {
- $formats[$format] = DBDatetime::now()->Format($format);
- }
- // Mark default format
- $formats[$defaultTimeFormat] .= sprintf(' (%s)', _t('Member.DefaultDateTime', 'default'));
- return $formats;
- }
-
/**
* @param bool $includerelations Indicate if the labels returned include relation fields
* @return array
@@ -1714,8 +1617,6 @@ class Member extends DataObject implements TemplateGlobalProvider
$labels['PasswordExpiry'] = _t('Member.db_PasswordExpiry', 'Password Expiry Date', 'Password expiry date');
$labels['LockedOutUntil'] = _t('Member.db_LockedOutUntil', 'Locked out until', 'Security related date');
$labels['Locale'] = _t('Member.db_Locale', 'Interface Locale');
- $labels['DateFormat'] = _t('Member.DATEFORMAT', 'Date format');
- $labels['TimeFormat'] = _t('Member.TIMEFORMAT', 'Time format');
if ($includerelations) {
$labels['Groups'] = _t(
'Member.belongs_many_many_Groups',
diff --git a/src/i18n/i18n.php b/src/i18n/i18n.php
index ee7c5fcea..732eb3922 100644
--- a/src/i18n/i18n.php
+++ b/src/i18n/i18n.php
@@ -85,12 +85,20 @@ class i18n implements TemplateGlobalProvider
private static $default_locale = 'en_US';
/**
+ * System-wide date format. Will be overruled for CMS UI display
+ * by the format defaults inferred from the browser as well as
+ * any user-specific locale preferences.
+ *
* @config
* @var string
*/
private static $date_format = 'yyyy-MM-dd';
/**
+ * System-wide time format. Will be overruled for CMS UI display
+ * by the format defaults inferred from the browser as well as
+ * any user-specific locale preferences.
+ *
* @config
* @var string
*/
diff --git a/tests/php/Forms/DateFieldTest.php b/tests/php/Forms/DateFieldTest.php
index fbfe18e89..676ae58eb 100644
--- a/tests/php/Forms/DateFieldTest.php
+++ b/tests/php/Forms/DateFieldTest.php
@@ -2,9 +2,9 @@
namespace SilverStripe\Forms\Tests;
+use IntlDateFormatter;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\DateField;
-use SilverStripe\Forms\SeparatedDateField;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\i18n\i18n;
use SilverStripe\ORM\FieldType\DBDatetime;
@@ -105,21 +105,11 @@ class DateFieldTest extends SapphireTest
public function testSetValueWithDateString()
{
$f = new DateField('Date', 'Date');
+ $f->setHTML5(false);
$f->setSubmittedValue('29/03/2003');
$this->assertEquals($f->dataValue(), '2003-03-29');
}
- public function testSetValueWithDateArray()
- {
- $f = new SeparatedDateField('Date', 'Date');
- $f->setSubmittedValue([
- 'day' => 29,
- 'month' => 03,
- 'year' => 2003
- ]);
- $this->assertEquals($f->dataValue(), '2003-03-29');
- }
-
public function testConstructorWithIsoDate()
{
// used by Form->loadDataFrom()
@@ -145,84 +135,11 @@ class DateFieldTest extends SapphireTest
$this->assertFalse($f->validate(new RequiredFields()));
}
- public function testEmptyValueValidation()
- {
- $validator = new RequiredFields();
- $field = new SeparatedDateField('Date');
- $this->assertTrue($field->validate($validator));
- $field->setSubmittedValue([
- 'day' => '',
- 'month' => '',
- 'year' => '',
- ]);
- $this->assertTrue($field->validate($validator));
- }
-
- public function testValidateArray()
- {
- $f = new SeparatedDateField('Date', 'Date');
- $f->setSubmittedValue([
- 'day' => 29,
- 'month' => 03,
- 'year' => 2003
- ]);
- $this->assertTrue($f->validate(new RequiredFields()));
-
- $f->setValue(null);
- $this->assertTrue($f->validate(new RequiredFields()), 'NULL values are validating TRUE');
-
- $f->setSubmittedValue(array());
- $this->assertTrue($f->validate(new RequiredFields()), 'Empty array values are validating TRUE');
-
- $f->setSubmittedValue([
- 'day' => null,
- 'month' => null,
- 'year' => null
- ]);
- $this->assertTrue($f->validate(new RequiredFields()), 'Empty array values with keys are validating TRUE');
- $f->setSubmittedValue([
- 'day' => 9999,
- 'month' => 9999,
- 'year' => 9999
- ]);
- $this->assertFalse($f->validate(new RequiredFields()));
- }
-
- public function testValidateEmptyArrayValuesSetsNullForValueObject()
- {
- $f = new SeparatedDateField('Date', 'Date');
- $f->setSubmittedValue([
- 'day' => '',
- 'month' => '',
- 'year' => ''
- ]);
- $this->assertNull($f->dataValue());
-
- $f->setSubmittedValue([
- 'day' => null,
- 'month' => null,
- 'year' => null
- ]);
- $this->assertNull($f->dataValue());
- }
-
- public function testValidateArrayValue()
- {
- $f = new SeparatedDateField('Date', 'Date');
- $f->setSubmittedValue(['day' => 29, 'month' => 03, 'year' => 2003]);
- $this->assertTrue($f->validate(new RequiredFields()));
-
- $f->setSubmittedValue(['month' => 03, 'year' => 2003]);
- $this->assertFalse($f->validate(new RequiredFields()));
-
- $f->setSubmittedValue(array('day' => 99, 'month' => 99, 'year' => 2003));
- $this->assertFalse($f->validate(new RequiredFields()));
- }
-
public function testFormatEnNz()
{
/* We get YYYY-MM-DD format as the data value for DD/MM/YYYY input value */
$f = new DateField('Date', 'Date');
+ $f->setHTML5(false);
$f->setSubmittedValue('29/03/2003');
$this->assertEquals($f->dataValue(), '2003-03-29');
}
@@ -232,6 +149,7 @@ class DateFieldTest extends SapphireTest
// should get en_NZ by default through setUp()
i18n::set_locale('de_DE');
$f = new DateField('Date', 'Date', '29/03/2003');
+ $f->setHTML5(false);
$f->setValue('29.06.2006');
$this->assertEquals($f->dataValue(), '2006-06-29');
}
@@ -242,6 +160,7 @@ class DateFieldTest extends SapphireTest
public function testMDYFormat()
{
$dateField = new DateField('Date', 'Date');
+ $dateField->setHTML5(false);
$dateField->setDateFormat('d/M/y');
$dateField->setSubmittedValue('31/03/2003');
$this->assertEquals(
@@ -251,6 +170,7 @@ class DateFieldTest extends SapphireTest
);
$dateField2 = new DateField('Date', 'Date');
+ $dateField2->setHTML5(false);
$dateField2->setDateFormat('d/M/y');
$dateField2->setSubmittedValue('04/3/03');
$this->assertEquals(
@@ -259,4 +179,40 @@ class DateFieldTest extends SapphireTest
"Even if input value hasn't got leading 0's in it we still get the correct data value"
);
}
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessageRegExp /Please opt-out .* if using setDateFormat/
+ */
+ public function testHtml5WithCustomFormatThrowsException()
+ {
+ $dateField = new DateField('Date', 'Date');
+ $dateField->setValue('2010-03-31');
+ $dateField->setDateFormat('d/M/y');
+ $dateField->Value();
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessageRegExp /Please opt-out .* if using setDateLength/
+ */
+ public function testHtml5WithCustomDateLengthThrowsException()
+ {
+ $dateField = new DateField('Date', 'Date');
+ $dateField->setValue('2010-03-31');
+ $dateField->setDateLength(IntlDateFormatter::MEDIUM);
+ $dateField->Value();
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessageRegExp /Please opt-out .* if using setLocale/
+ */
+ public function testHtml5WithCustomLocaleThrowsException()
+ {
+ $dateField = new DateField('Date', 'Date');
+ $dateField->setValue('2010-03-31');
+ $dateField->setLocale('de_DE');
+ $dateField->Value();
+ }
}
diff --git a/tests/php/Forms/DatefieldViewJQueryTest.php b/tests/php/Forms/DatefieldViewJQueryTest.php
deleted file mode 100644
index 83b7a931a..000000000
--- a/tests/php/Forms/DatefieldViewJQueryTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-assertEquals(
- 'M d, yy',
- DateField_View_JQuery::convert_iso_to_jquery_format('MMM d, yyyy')
- );
-
- $this->assertEquals(
- 'd/mm/yy',
- DateField_View_JQuery::convert_iso_to_jquery_format('d/MM/yyyy')
- );
-
- $this->assertEquals(
- 'dd.m.yy',
- DateField_View_JQuery::convert_iso_to_jquery_format('dd.M.yyyy'),
- 'Month, no leading zero'
- );
-
- $this->assertEquals(
- 'dd.mm.yy',
- DateField_View_JQuery::convert_iso_to_jquery_format('dd.MM.yyyy'),
- 'Month, two digit'
- );
-
- $this->assertEquals(
- 'dd.M.yy',
- DateField_View_JQuery::convert_iso_to_jquery_format('dd.MMM.yyyy'),
- 'Abbreviated month name'
- );
-
- $this->assertEquals(
- 'dd.MM.yy',
- DateField_View_JQuery::convert_iso_to_jquery_format('dd.MMMM.yyyy'),
- 'Full month name'
- );
- }
-}
diff --git a/tests/php/Forms/DatetimeFieldTest.php b/tests/php/Forms/DatetimeFieldTest.php
index 9969bb24f..f0736f44a 100644
--- a/tests/php/Forms/DatetimeFieldTest.php
+++ b/tests/php/Forms/DatetimeFieldTest.php
@@ -7,7 +7,6 @@ use SilverStripe\Control\Controller;
use SilverStripe\Forms\DatetimeField;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\DateField;
-use SilverStripe\Forms\SeparatedDateField;
use SilverStripe\Forms\Tests\DatetimeFieldTest\Model;
use SilverStripe\Forms\TimeField;
use SilverStripe\Forms\FieldList;
@@ -38,6 +37,32 @@ class DatetimeFieldTest extends SapphireTest
$form = $this->getMockForm();
$form->Fields()->push($dateTimeField);
+ $dateTimeField->setSubmittedValue([
+ 'date' => '2003-03-29',
+ 'time' => '23:59:38'
+ ]);
+ $validator = new RequiredFields();
+ $this->assertTrue($dateTimeField->validate($validator));
+ $m = new Model();
+ $form->saveInto($m);
+ $this->assertEquals('2003-03-29 23:59:38', $m->MyDatetime);
+ }
+
+ public function testFormSaveIntoLocalised()
+ {
+ $dateTimeField = new DatetimeField('MyDatetime');
+
+ $dateTimeField->getDateField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
+ $dateTimeField->getTimeField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
+ $form = $this->getMockForm();
+ $form->Fields()->push($dateTimeField);
+
// en_NZ standard format
$dateTimeField->setSubmittedValue([
'date' => '29/03/2003',
@@ -97,6 +122,25 @@ class DatetimeFieldTest extends SapphireTest
public function testSetValueWithArray()
{
$datetimeField = new DatetimeField('Datetime', 'Datetime');
+ $datetimeField->setSubmittedValue([
+ 'date' => '2003-03-29',
+ 'time' => '23:00:00'
+ ]);
+ $this->assertEquals($datetimeField->dataValue(), '2003-03-29 23:00:00');
+ }
+
+ public function testSetValueWithArrayLocalised()
+ {
+ $datetimeField = new DatetimeField('Datetime', 'Datetime');
+
+ $datetimeField->getDateField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
+ $datetimeField->getTimeField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
// Values can only be localized (= non-ISO) in array notation
$datetimeField->setSubmittedValue([
'date' => '29/03/2003',
@@ -105,17 +149,6 @@ class DatetimeFieldTest extends SapphireTest
$this->assertEquals($datetimeField->dataValue(), '2003-03-29 23:00:00');
}
- public function testSetValueWithDmyArray()
- {
- $f = new DatetimeField('Datetime', 'Datetime');
- $f->setDateField(new SeparatedDateField('Datetime[date]'));
- $f->setSubmittedValue([
- 'date' => ['day' => 29, 'month' => 03, 'year' => 2003],
- 'time' => '11:00:00 pm'
- ]);
- $this->assertEquals($f->dataValue(), '2003-03-29 23:00:00');
- }
-
public function testValidate()
{
$f = new DatetimeField('Datetime', 'Datetime', '2003-03-29 23:59:38');
@@ -128,11 +161,20 @@ class DatetimeFieldTest extends SapphireTest
$this->assertFalse($f->validate(new RequiredFields()));
}
- public function testTimezoneSet()
+ public function testTimezoneSetLocalised()
{
date_default_timezone_set('Europe/Berlin');
// Berlin and Auckland have 12h time difference in northern hemisphere winter
$datetimeField = new DatetimeField('Datetime', 'Datetime');
+
+ $datetimeField->getDateField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
+ $datetimeField->getTimeField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
$datetimeField->setTimezone('Pacific/Auckland');
$datetimeField->setValue('2003-12-24 23:59:59');
$this->assertEquals(
@@ -149,11 +191,20 @@ class DatetimeFieldTest extends SapphireTest
);
}
- public function testTimezoneFromConfig()
+ public function testTimezoneFromConfigLocalised()
{
date_default_timezone_set('Europe/Berlin');
// Berlin and Auckland have 12h time difference in northern hemisphere summer, but Berlin and Moscow only 2h.
$datetimeField = new DatetimeField('Datetime', 'Datetime');
+
+ $datetimeField->getDateField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
+ $datetimeField->getTimeField()
+ ->setHTML5(false)
+ ->setLocale('en_NZ');
+
$datetimeField->setTimezone('Europe/Moscow');
$datetimeField->setSubmittedValue([
// pass in default format, at user time (Moscow)
@@ -170,7 +221,7 @@ class DatetimeFieldTest extends SapphireTest
$field = new DatetimeField('Datetime', 'Datetime');
$field->setForm($form);
$field->setSubmittedValue([
- 'date' => '24/06/2003',
+ 'date' => '2003-06-24',
'time' => '23:59:59',
]);
$dateField = new DateField('Datetime[date]');
@@ -195,8 +246,8 @@ class DatetimeFieldTest extends SapphireTest
$field = new DatetimeField('Datetime', 'Datetime');
$field->setForm($form);
$field->setSubmittedValue([
- 'date' => '24/06/2003',
- 'time' => '11:59:59 pm',
+ 'date' => '2003-06-24',
+ 'time' => '23:59:59',
]);
$timeField = new TimeField('Datetime[time]');
$field->setTimeField($timeField);
diff --git a/tests/php/Forms/MemberDatetimeOptionsetFieldTest.php b/tests/php/Forms/MemberDatetimeOptionsetFieldTest.php
deleted file mode 100644
index 5755b4fa8..000000000
--- a/tests/php/Forms/MemberDatetimeOptionsetFieldTest.php
+++ /dev/null
@@ -1,177 +0,0 @@
-getDefaultDateFormat();
- $dateFormatMap = array(
- 'yyyy-MM-dd' => DBDatetime::now()->Format('yyyy-MM-dd'),
- 'yyyy/MM/dd' => DBDatetime::now()->Format('yyyy/MM/dd'),
- 'MM/dd/yyyy' => DBDatetime::now()->Format('MM/dd/yyyy'),
- 'dd/MM/yyyy' => DBDatetime::now()->Format('dd/MM/yyyy'),
- );
- $dateFormatMap[$defaultDateFormat] = DBDatetime::now()->Format($defaultDateFormat) . ' (default)';
- $field = new MemberDatetimeOptionsetField(
- 'DateFormat',
- 'Date format',
- $dateFormatMap
- );
- $field->setValue($member->getDateFormat());
- return $field;
- }
-
- /**
- * @param Member $member
- * @return MemberDatetimeOptionsetField
- */
- protected function createTimeFormatFieldForMember($member)
- {
- $defaultTimeFormat = $member->getDefaultTimeFormat();
- $timeFormatMap = array(
- 'h:mm a' => DBDatetime::now()->Format('h:mm a'),
- 'H:mm' => DBDatetime::now()->Format('H:mm'),
- );
- $timeFormatMap[$defaultTimeFormat] = DBDatetime::now()->Format($defaultTimeFormat) . ' (default)';
- $field = new MemberDatetimeOptionsetField(
- 'TimeFormat',
- 'Time format',
- $timeFormatMap
- );
- $field->setValue($member->getTimeFormat());
- return $field;
- }
-
- public function testDateFormatDefaultCheckedInFormField()
- {
- /** @var Member $member */
- $member = $this->objFromFixture(Member::class, 'noformatmember');
- $field = $this->createDateFormatFieldForMember($member);
- /** @skipUpgrade */
- $field->setForm(
- new Form(
- new Controller(),
- 'Form',
- new FieldList(),
- new FieldList()
- )
- ); // fake form
- // `MMM d, y` is default format for default locale (en_US)
- $parser = new CSSContentParser($field->Field());
- $xmlArr = $parser->getBySelector('#Form_Form_DateFormat_MMM_d_y');
- $this->assertEquals('checked', (string) $xmlArr[0]['checked']);
- }
-
- public function testTimeFormatDefaultCheckedInFormField()
- {
- /** @var Member $member */
- $member = $this->objFromFixture(Member::class, 'noformatmember');
- $field = $this->createTimeFormatFieldForMember($member);
- /** @skipUpgrade */
- $field->setForm(
- new Form(
- new Controller(),
- 'Form',
- new FieldList(),
- new FieldList()
- )
- ); // fake form
- // `h:mm:ss a` is the default for en_US locale
- $parser = new CSSContentParser($field->Field());
- $xmlArr = $parser->getBySelector('#Form_Form_TimeFormat_h:mm:ss_a');
- $this->assertEquals('checked', (string) $xmlArr[0]['checked']);
- }
-
- public function testDateFormatChosenIsCheckedInFormField()
- {
- /** @var Member $member */
- $member = $this->objFromFixture(Member::class, 'noformatmember');
- $member->setField('DateFormat', 'MM/dd/yyyy');
- $field = $this->createDateFormatFieldForMember($member);
- /** @skipUpgrade */
- $field->setForm(
- new Form(
- new Controller(),
- 'Form',
- new FieldList(),
- new FieldList()
- )
- ); // fake form
- $parser = new CSSContentParser($field->Field());
- $xmlArr = $parser->getBySelector('#Form_Form_DateFormat_MM_dd_yyyy');
- $this->assertEquals('checked', (string) $xmlArr[0]['checked']);
- }
-
- public function testDateFormatCustomFormatAppearsInCustomInputInField()
- {
- /** @var Member $member */
- $member = $this->objFromFixture(Member::class, 'noformatmember');
- $member->setField('DateFormat', 'dd MM yy');
- $field = $this->createDateFormatFieldForMember($member);
- /** @skipUpgrade */
- $field->setForm(
- new Form(
- new Controller(),
- 'Form',
- new FieldList(),
- new FieldList()
- )
- ); // fake form
- $parser = new CSSContentParser($field->Field());
- $xmlInputArr = $parser->getBySelector('.valcustom input');
- $this->assertEquals('checked', (string) $xmlInputArr[0]['checked']);
- $this->assertEquals('dd MM yy', (string) $xmlInputArr[1]['value']);
- }
-
- public function testDateFormValid()
- {
- $field = new MemberDatetimeOptionsetField('DateFormat', 'DateFormat');
- $validator = new RequiredFields();
- $this->assertTrue($field->validate($validator));
- $field->setSubmittedValue([
- 'Options' => '__custom__',
- 'Custom' => 'dd MM yyyy'
- ]);
- $this->assertTrue($field->validate($validator));
- $field->setSubmittedValue([
- 'Options' => '__custom__',
- 'Custom' => 'sdfdsfdfd1244'
- ]);
- // @todo - Be less forgiving of invalid CLDR date format strings
- $this->assertTrue($field->validate($validator));
- }
-
- public function testDescriptionTemplate()
- {
- $field = new MemberDatetimeOptionsetField('DateFormat', 'DateFormat');
-
- $this->assertEmpty($field->getDescription());
-
- $field->setDescription('Test description');
- $this->assertEquals('Test description', $field->getDescription());
-
- $field->setDescriptionTemplate(get_class($field).'_description_time');
- $this->assertNotEmpty($field->getDescription());
- $this->assertNotEquals('Test description', $field->getDescription());
- }
-}
diff --git a/tests/php/Forms/MemberDatetimeOptionsetFieldTest.yml b/tests/php/Forms/MemberDatetimeOptionsetFieldTest.yml
deleted file mode 100644
index 655d400df..000000000
--- a/tests/php/Forms/MemberDatetimeOptionsetFieldTest.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-SilverStripe\Security\Member:
- noformatmember:
- Email: noformat@test.com
- delocalemember:
- Email: delocalemember@test.com
- Locale: de_DE
diff --git a/tests/php/Forms/SeparatedDateFieldTest.php b/tests/php/Forms/SeparatedDateFieldTest.php
deleted file mode 100644
index 096503f8e..000000000
--- a/tests/php/Forms/SeparatedDateFieldTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-setLocale('en_NZ');
- $this->assertRegExp('/.*[day].*[month].*[year]/', $dateField->Field());
- }
-
- public function testFieldOrderingBasedOnDateFormat()
- {
- $dateField = new SeparatedDateField('Date');
- $dateField->setDateFormat('y/MM/dd');
- $this->assertRegExp('/.*[year].*[month].*[day]/', $dateField->Field());
- }
-
- public function testCustomSeparator()
- {
- $dateField = new SeparatedDateField('Date');
- $dateField->setDateFormat('dd/MM/y');
- $dateField->setSeparator('###');
- $this->assertRegExp('/.*[day].*###.*[month].*###.*[day]/', $dateField->Field());
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @expectedExceptionMessage Invalid date format
- */
- public function testInvalidDateFormat()
- {
- $dateField = new SeparatedDateField('Date');
- $dateField->setDateFormat('y/MM');
- $dateField->Field();
- }
-}
diff --git a/tests/php/Forms/TimeFieldTest.php b/tests/php/Forms/TimeFieldTest.php
index 58d2e31dc..65e40fb22 100644
--- a/tests/php/Forms/TimeFieldTest.php
+++ b/tests/php/Forms/TimeFieldTest.php
@@ -2,6 +2,7 @@
namespace SilverStripe\Forms\Tests;
+use IntlDateFormatter;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\TimeField;
@@ -40,11 +41,23 @@ class TimeFieldTest extends SapphireTest
$this->assertFalse($f->validate(new RequiredFields()));
}
+ public function testValidateLenientWithHtml5()
+ {
+ $f = new TimeField('Time', 'Time', '23:59:59');
+ $f->setHTML5(true);
+ $this->assertTrue($f->validate(new RequiredFields()));
+
+ $f = new TimeField('Time', 'Time', '23:59'); // leave out seconds
+ $f->setHTML5(true);
+ $this->assertTrue($f->validate(new RequiredFields()));
+ }
+
public function testSetLocale()
{
// should get en_NZ by default through setUp()
$f = new TimeField('Time', 'Time');
- $f->setLocale('de_DE');
+ $f->setHTML5(false);
+ $f->setLocale('fr_FR');
// TODO Find a hour format thats actually different
$f->setValue('23:59');
$this->assertEquals($f->dataValue(), '23:59:00');
@@ -85,8 +98,7 @@ class TimeFieldTest extends SapphireTest
public function testOverrideWithNull()
{
$field = new TimeField('Time', 'Time');
-
- $field->setValue('11:00pm');
+ $field->setValue('11:00:00');
$field->setValue('');
$this->assertEquals($field->dataValue(), '');
}
@@ -94,33 +106,80 @@ class TimeFieldTest extends SapphireTest
/**
* Test that AM/PM is preserved correctly in various situations
*/
- public function testPreserveAMPM()
+ public function testSetTimeFormat()
{
// Test with timeformat that includes hour
// Check pm
$f = new TimeField('Time', 'Time');
+ $f->setHTML5(false);
$f->setTimeFormat('h:mm:ss a');
$f->setValue('3:59 pm');
$this->assertEquals($f->dataValue(), '15:59:00');
// Check am
$f = new TimeField('Time', 'Time');
+ $f->setHTML5(false);
$f->setTimeFormat('h:mm:ss a');
$f->setValue('3:59 am');
$this->assertEquals($f->dataValue(), '03:59:00');
// Check with ISO date/time
$f = new TimeField('Time', 'Time');
+ $f->setHTML5(false);
$f->setTimeFormat('h:mm:ss a');
$f->setValue('15:59:00');
$this->assertEquals($f->dataValue(), '15:59:00');
// ISO am
$f = new TimeField('Time', 'Time');
+ $f->setHTML5(false);
$f->setTimeFormat('h:mm:ss a');
$f->setValue('03:59:00');
$this->assertEquals($f->dataValue(), '03:59:00');
}
+
+ public function testLenientSubmissionParseWithoutSecondsOnHtml5()
+ {
+ $f = new TimeField('Time', 'Time');
+ $f->setSubmittedValue('23:59');
+ $this->assertEquals($f->Value(), '23:59:00');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessageRegExp /Please opt-out .* if using setTimeFormat/
+ */
+ public function testHtml5WithCustomFormatThrowsException()
+ {
+ $f = new TimeField('Time', 'Time');
+ $f->setValue('15:59:00');
+ $f->setTimeFormat('mm:HH');
+ $f->Value();
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessageRegExp /Please opt-out .* if using setTimeLength/
+ */
+ public function testHtml5WithCustomDateLengthThrowsException()
+ {
+ $f = new TimeField('Time', 'Time');
+ $f->setValue('15:59:00');
+ $f->setTimeLength(IntlDateFormatter::MEDIUM);
+ $f->Value();
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessageRegExp /Please opt-out .* if using setLocale/
+ */
+ public function testHtml5WithCustomLocaleThrowsException()
+ {
+ $f = new TimeField('Time', 'Time');
+ $f->setValue('15:59:00');
+ $f->setLocale('de_DE');
+ $f->Value();
+ }
}
diff --git a/tests/php/ORM/DBDateTest.php b/tests/php/ORM/DBDateTest.php
index cb550e765..30040a159 100644
--- a/tests/php/ORM/DBDateTest.php
+++ b/tests/php/ORM/DBDateTest.php
@@ -324,41 +324,4 @@ class DBDateTest extends SapphireTest
DBDatetime::clear_mock_now();
}
-
- /**
- * @see testFormatFromSettings
- * @return array
- */
- public function dataTestFormatFromSettings()
- {
- return [
- ['2000-12-31', '31/12/2000'],
- ['31-12-2000', '31/12/2000'],
- ['2014-04-01', '01/04/2014'],
- ];
- }
-
- /**
- * @dataProvider dataTestFormatFromSettings
- * @param string $from
- * @param string $to
- */
- public function testFormatFromSettings($from, $to)
- {
- $this->suppressNotices();
- $member = new Member();
- $member->DateFormat = 'dd/MM/y';
-
- $date = DBField::create_field('Date', $from);
- $this->assertEquals($to, $date->FormatFromSettings($member));
- }
-
- /**
- * Test that FormatFromSettings without a member defaults to Nice()
- */
- public function testFormatFromSettingsEmpty()
- {
- $date = DBfield::create_field('Date', '2000-12-31');
- $this->assertEquals('31/12/2000', $date->FormatFromSettings());
- }
}
diff --git a/tests/php/ORM/DBDatetimeTest.php b/tests/php/ORM/DBDatetimeTest.php
index 9f3cb8e02..428e56b03 100644
--- a/tests/php/ORM/DBDatetimeTest.php
+++ b/tests/php/ORM/DBDatetimeTest.php
@@ -204,41 +204,4 @@ class DBDatetimeTest extends SapphireTest
DBDatetime::clear_mock_now();
}
-
- public function dataTestFormatFromSettings()
- {
- return [
- ['2000-12-31 10:11:01', '31/12/2000 10:11:01'],
- ['2000-12-31 1:11:01', '31/12/2000 01:11:01'],
- ['2000-12-12 1:11:01', '12/12/2000 01:11:01'],
- ['2000-12-31', '31/12/2000 00:00:00'],
- ['2014-04-01 10:11:01', '01/04/2014 10:11:01']
- ];
- }
-
- /**
- * @dataProvider dataTestFormatFromSettings
- * @param string $from
- * @param string $to
- */
- public function testFormatFromSettings($from, $to)
- {
- $member = new Member();
- $member->DateFormat = 'dd/MM/y';
- $member->TimeFormat = 'HH:mm:ss';
-
- $date = DBDatetime::create_field('Datetime', $from);
- $this->assertEquals($to, $date->FormatFromSettings($member));
- }
-
- /**
- * Test that FormatFromSettings without a member defaults to Nice()
- */
- public function testFormatFromSettingsEmpty()
- {
- $date = DBDatetime::create_field('Datetime', '2000-12-31 10:11:01');
-
- // note: Some localisation packages exclude the ',' in default medium format
- $this->assertRegExp('#31/12/2000(,)? 10:11:01 AM#', $date->FormatFromSettings());
- }
}
diff --git a/tests/php/ORM/DBTimeTest.php b/tests/php/ORM/DBTimeTest.php
index 64f0640ae..8f68f5017 100644
--- a/tests/php/ORM/DBTimeTest.php
+++ b/tests/php/ORM/DBTimeTest.php
@@ -56,35 +56,4 @@ class DBTimeTest extends SapphireTest
$time = DBTime::create_field('Time', '17:15:55');
$this->assertEquals('5:15 PM', $time->Short());
}
-
- public function dataTestFormatFromSettings()
- {
- return [
- ['10:11:01', '10:11:01 (AM)'],
- ['21:11:01', '9:11:01 (PM)'],
- ];
- }
-
- /**
- * @dataProvider dataTestFormatFromSettings
- * @param string $from
- * @param string $to
- */
- public function testFormatFromSettings($from, $to)
- {
- $member = new Member();
- $member->TimeFormat = 'h:mm:ss (a)';
-
- $date = DBTime::create_field('Time', $from);
- $this->assertEquals($to, $date->FormatFromSettings($member));
- }
-
- /**
- * Test that FormatFromSettings without a member defaults to Nice()
- */
- public function testFormatFromSettingsEmpty()
- {
- $date = DBTime::create_field('Time', '10:11:01');
- $this->assertEquals('10:11:01 AM', $date->FormatFromSettings());
- }
}
diff --git a/tests/php/Security/MemberTest.php b/tests/php/Security/MemberTest.php
index 153eab2dc..80c2ea1df 100644
--- a/tests/php/Security/MemberTest.php
+++ b/tests/php/Security/MemberTest.php
@@ -395,15 +395,6 @@ class MemberTest extends FunctionalTest
$member->PasswordExpiry = date('Y-m-d', time() + 86400);
$this->assertFalse($member->isPasswordExpired());
}
-
- public function testMemberWithNoDateFormatFallsbackToGlobalLocaleDefaultFormat()
- {
- // Note: All default strings are based on locale defaults for en_US
- $member = $this->objFromFixture(Member::class, 'noformatmember');
- $this->assertEquals('MMM d, y', $member->DateFormat);
- $this->assertEquals('h:mm:ss a', $member->TimeFormat);
- }
-
public function testInGroups()
{
$staffmember = $this->objFromFixture(Member::class, 'staffmember');