FEATURE New DatetimeField class (form field wrapper composed of DateField andTimeField)
FEATURE New DateField and TimeField form classes with more consistent API and easier localization
API CHANGE Date/time parsing in DateField, TimeField and DatetimeField defaults to i18n::get_locale() ('en_US') instead of using en_NZ/en_GB specific parsing. Use i18n::set_locale('en_NZ') in mysite/_config.php to revert to old behaviour.
API CHANGE constructor parameter in TimeField needs to be in ISO date notation (not PHP's date())
API CHANGE TimeField, DateField and related subclasses use Zend_Date for date parsing, meaning they're stricer than the previously used strtotime()
API CHANGE Removed DMYCalendarDateField and CalendarDateField, use DateField with setConfig('showcalendar')
API CHANGE Removed CompositeDateField, DMYDateField, use DateField with setConfig('dmyfields')
API CHANGE Removed DropdownTimeField, use TimeField with setConfig('showdropdown')
API CHANGE Removed PopupDateTimeField, use DatetimeField
API CHANGE Changed 'date', 'month' and 'year' HTML field names to lowercase in DMYDateField
API CHANGE Removed support for ambiguous date formats in DateField, e.g. '06/03/03'. Use DateField->setConfig('dateformat', '<format>') to revert to this behaviour.
API CHANGE Removed flag from DateField, CalendarDateField etc., use DateField->setConfig('min') and DateField->setConfig('max')
ENHANCEMENT Using Zend_Date for DateField and TimeField, with more robust date handling, starting localization support. Set globally via i18n::set_locale(), or for a field instance through setLocale(). Note: Javascript validation is not localized yet. (from r99360)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102859 467b73ca-7a2a-4603-9d3b-597d59a354a9
2010-04-14 06:38:40 +02:00
|
|
|
<?php
|
2016-06-15 06:03:16 +02:00
|
|
|
|
2016-10-14 03:30:05 +02:00
|
|
|
namespace SilverStripe\Forms\Tests;
|
|
|
|
|
2022-04-06 01:34:34 +02:00
|
|
|
use IntlDateFormatter;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\Control\Controller;
|
2017-06-22 12:50:45 +02:00
|
|
|
use SilverStripe\Dev\SapphireTest;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\Forms\DatetimeField;
|
|
|
|
use SilverStripe\Forms\FieldList;
|
|
|
|
use SilverStripe\Forms\Form;
|
2017-06-22 12:50:45 +02:00
|
|
|
use SilverStripe\Forms\FormAction;
|
|
|
|
use SilverStripe\Forms\RequiredFields;
|
|
|
|
use SilverStripe\Forms\Tests\DatetimeFieldTest\Model;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\i18n\i18n;
|
2017-04-26 03:49:40 +02:00
|
|
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
2016-08-19 00:51:35 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
class DatetimeFieldTest extends SapphireTest
|
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
protected $timezone = null;
|
2016-12-16 05:34:21 +01:00
|
|
|
|
2021-10-27 04:39:47 +02:00
|
|
|
protected function setUp(): void
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
|
|
|
parent::setUp();
|
2024-09-30 07:32:17 +02:00
|
|
|
// Set to an explicit locale so project-level locale swapping doesn't affect tests
|
|
|
|
i18n::set_locale('en_US');
|
2017-05-25 02:13:04 +02:00
|
|
|
// Fix now to prevent race conditions
|
|
|
|
DBDatetime::set_mock_now('2010-04-04');
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->timezone = date_default_timezone_get();
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
2021-10-27 04:39:47 +02:00
|
|
|
protected function tearDown(): void
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
2017-05-25 02:13:04 +02:00
|
|
|
DBDatetime::clear_mock_now();
|
2022-04-14 03:12:59 +02:00
|
|
|
date_default_timezone_set($this->timezone ?? '');
|
2020-04-06 07:03:11 +02:00
|
|
|
parent::tearDown();
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testFormSaveInto()
|
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$dateTimeField = new DatetimeField('MyDatetime');
|
2016-12-16 05:34:21 +01:00
|
|
|
$form = $this->getMockForm();
|
2017-01-26 05:20:08 +01:00
|
|
|
$form->Fields()->push($dateTimeField);
|
|
|
|
|
2017-04-20 05:08:44 +02:00
|
|
|
$dateTimeField->setSubmittedValue('2003-03-29T23:59:38');
|
2017-04-03 09:35:40 +02:00
|
|
|
$validator = new RequiredFields();
|
|
|
|
$this->assertTrue($dateTimeField->validate($validator));
|
|
|
|
$m = new Model();
|
|
|
|
$form->saveInto($m);
|
2017-04-26 03:49:59 +02:00
|
|
|
$this->assertEquals('2003-03-29 23:59:38', $m->MyDatetime);
|
2017-04-03 09:35:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testFormSaveIntoLocalised()
|
|
|
|
{
|
|
|
|
$dateTimeField = new DatetimeField('MyDatetime');
|
2017-04-20 05:08:44 +02:00
|
|
|
$dateTimeField
|
2017-04-03 09:35:40 +02:00
|
|
|
->setHTML5(false)
|
|
|
|
->setLocale('en_NZ');
|
|
|
|
|
|
|
|
$form = $this->getMockForm();
|
|
|
|
$form->Fields()->push($dateTimeField);
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// en_NZ standard format
|
2017-04-20 05:08:44 +02:00
|
|
|
$dateTimeField->setSubmittedValue('29/03/2003 11:59:38 pm');
|
2017-01-26 05:20:08 +01:00
|
|
|
$validator = new RequiredFields();
|
|
|
|
$this->assertTrue($dateTimeField->validate($validator));
|
2016-12-16 05:34:21 +01:00
|
|
|
$m = new Model();
|
|
|
|
$form->saveInto($m);
|
2017-04-26 03:49:59 +02:00
|
|
|
$this->assertEquals('2003-03-29 23:59:38', $m->MyDatetime);
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testDataValue()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$this->assertEquals(null, $f->dataValue(), 'Empty field');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime', null, '2003-03-29 23:59:38');
|
|
|
|
$this->assertEquals('2003-03-29 23:59:38', $f->dataValue(), 'From date/time string');
|
|
|
|
}
|
|
|
|
|
2017-04-27 04:59:11 +02:00
|
|
|
public function testDataValueWithTimezone()
|
|
|
|
{
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere winter
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setTimezone('Pacific/Auckland');
|
|
|
|
$f->setSubmittedValue('2003-01-30T23:59:38'); // frontend timezone (Auckland)
|
|
|
|
$this->assertEquals('2003-01-30 11:59:38', $f->dataValue()); // server timezone (Berlin)
|
|
|
|
}
|
|
|
|
|
2018-10-20 18:29:07 +02:00
|
|
|
public function testSetSubmittedValueNull()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
$field->setSubmittedValue(false);
|
|
|
|
$this->assertNull($field->Value());
|
|
|
|
}
|
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testConstructorWithoutArgs()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$this->assertEquals($f->dataValue(), null);
|
|
|
|
}
|
|
|
|
|
2017-04-26 23:18:38 +02:00
|
|
|
public function testConstructorWithLocalizedDateSetsNullValue()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime', 'Datetime', '29/03/2003 23:59:38');
|
|
|
|
$this->assertNull($f->Value());
|
|
|
|
}
|
2016-12-16 05:34:21 +01:00
|
|
|
|
|
|
|
public function testConstructorWithIsoDate()
|
|
|
|
{
|
|
|
|
// used by Form->loadDataFrom()
|
|
|
|
$f = new DatetimeField('Datetime', 'Datetime', '2003-03-29 23:59:38');
|
|
|
|
$this->assertEquals($f->dataValue(), '2003-03-29 23:59:38');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetValueWithDateTimeString()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime', 'Datetime');
|
|
|
|
$f->setValue('2003-03-29 23:59:38');
|
2018-06-14 08:14:12 +02:00
|
|
|
$this->assertEquals('2003-03-29 23:59:38', $f->dataValue(), 'Accepts ISO');
|
2017-04-26 03:49:59 +02:00
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime', 'Datetime');
|
|
|
|
$f->setValue('2003-03-29T23:59:38');
|
2018-06-14 08:14:12 +02:00
|
|
|
$this->assertEquals('2003-03-29 23:59:38', $f->dataValue(), 'Accepts normalised ISO');
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
2017-04-26 03:49:59 +02:00
|
|
|
public function testSubmittedValue()
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField = new DatetimeField('Datetime', 'Datetime');
|
2017-04-20 05:08:44 +02:00
|
|
|
$datetimeField->setSubmittedValue('2003-03-29 23:00:00');
|
2017-04-03 09:35:40 +02:00
|
|
|
$this->assertEquals($datetimeField->dataValue(), '2003-03-29 23:00:00');
|
2017-04-26 03:49:59 +02:00
|
|
|
|
|
|
|
$datetimeField = new DatetimeField('Datetime', 'Datetime');
|
|
|
|
$datetimeField->setSubmittedValue('2003-03-29T23:00:00');
|
|
|
|
$this->assertEquals($datetimeField->dataValue(), '2003-03-29 23:00:00', 'Normalised ISO');
|
2017-04-03 09:35:40 +02:00
|
|
|
}
|
|
|
|
|
2017-04-20 05:08:44 +02:00
|
|
|
public function testSetValueWithLocalised()
|
2017-04-03 09:35:40 +02:00
|
|
|
{
|
|
|
|
$datetimeField = new DatetimeField('Datetime', 'Datetime');
|
|
|
|
|
2017-04-20 05:08:44 +02:00
|
|
|
$datetimeField
|
2017-04-03 09:35:40 +02:00
|
|
|
->setHTML5(false)
|
2024-09-30 07:32:17 +02:00
|
|
|
->setLocale('de_DE');
|
2017-04-03 09:35:40 +02:00
|
|
|
|
2024-09-30 07:32:17 +02:00
|
|
|
$datetimeField->setSubmittedValue('29/03/2003 23:00:00');
|
|
|
|
$this->assertEquals('2003-03-29 23:00:00', $datetimeField->dataValue());
|
2017-04-26 23:18:38 +02:00
|
|
|
|
|
|
|
// Some localisation packages exclude the ',' in default medium format
|
2021-10-27 04:39:47 +02:00
|
|
|
$this->assertMatchesRegularExpression(
|
2024-09-30 07:32:17 +02:00
|
|
|
'#29.03.2003(,)? 23:00:00#',
|
2017-04-26 23:18:38 +02:00
|
|
|
$datetimeField->Value(),
|
|
|
|
'User value is formatted, and in user timezone'
|
|
|
|
);
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testValidate()
|
|
|
|
{
|
2018-10-20 18:29:07 +02:00
|
|
|
$field = new DatetimeField('Datetime', 'Datetime', '2003-03-29 23:59:38');
|
|
|
|
$this->assertTrue($field->validate(new RequiredFields()));
|
2016-12-16 05:34:21 +01:00
|
|
|
|
2018-10-20 18:29:07 +02:00
|
|
|
$field = new DatetimeField('Datetime', 'Datetime', '2003-03-29T23:59:38');
|
|
|
|
$this->assertTrue($field->validate(new RequiredFields()), 'Normalised ISO');
|
2017-04-26 03:49:59 +02:00
|
|
|
|
2018-10-20 18:29:07 +02:00
|
|
|
$field = new DatetimeField('Datetime', 'Datetime', '2003-03-29');
|
|
|
|
$this->assertFalse($field->validate(new RequiredFields()), 'Leaving out time');
|
2016-12-16 05:34:21 +01:00
|
|
|
|
2018-10-20 18:29:07 +02:00
|
|
|
$field = (new DatetimeField('Datetime', 'Datetime'))
|
2017-04-27 04:59:11 +02:00
|
|
|
->setSubmittedValue('2003-03-29T00:00');
|
2018-10-20 18:29:07 +02:00
|
|
|
$this->assertTrue($field->validate(new RequiredFields()), 'Leaving out seconds (like many browsers)');
|
|
|
|
|
|
|
|
$field = new DatetimeField('Datetime', 'Datetime', 'wrong');
|
|
|
|
$this->assertFalse($field->validate(new RequiredFields()));
|
2017-04-26 03:49:29 +02:00
|
|
|
|
2018-10-20 18:29:07 +02:00
|
|
|
$field = new DatetimeField('Datetime', 'Datetime', false);
|
|
|
|
$this->assertTrue($field->validate(new RequiredFields()));
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
2017-04-27 01:53:34 +02:00
|
|
|
public function testSetMinDate()
|
|
|
|
{
|
|
|
|
$f = (new DatetimeField('Datetime'))->setMinDatetime('2009-03-31T23:00:00');
|
2017-04-27 04:59:11 +02:00
|
|
|
$this->assertEquals($f->getMinDatetime(), '2009-03-31 23:00:00', 'Retains ISO');
|
2017-04-27 01:53:34 +02:00
|
|
|
|
|
|
|
$f = (new DatetimeField('Datetime'))->setMinDatetime('2009-03-31 23:00:00');
|
2017-04-27 04:59:11 +02:00
|
|
|
$this->assertEquals($f->getMinDatetime(), '2009-03-31 23:00:00', 'Converts normalised ISO to ISO');
|
2017-04-27 01:53:34 +02:00
|
|
|
|
|
|
|
$f = (new DatetimeField('Datetime'))->setMinDatetime('invalid');
|
|
|
|
$this->assertNull($f->getMinDatetime(), 'Ignores invalid values');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetMaxDate()
|
|
|
|
{
|
|
|
|
$f = (new DatetimeField('Datetime'))->setMaxDatetime('2009-03-31T23:00:00');
|
2017-04-27 04:59:11 +02:00
|
|
|
$this->assertEquals($f->getMaxDatetime(), '2009-03-31 23:00:00', 'Retains ISO');
|
2017-04-27 01:53:34 +02:00
|
|
|
|
|
|
|
$f = (new DatetimeField('Datetime'))->setMaxDatetime('2009-03-31 23:00:00');
|
2017-04-27 04:59:11 +02:00
|
|
|
$this->assertEquals($f->getMaxDatetime(), '2009-03-31 23:00:00', 'Converts normalised ISO to ISO');
|
2017-04-27 01:53:34 +02:00
|
|
|
|
|
|
|
$f = (new DatetimeField('Datetime'))->setMaxDatetime('invalid');
|
|
|
|
$this->assertNull($f->getMaxDatetime(), 'Ignores invalid values');
|
|
|
|
}
|
|
|
|
|
2017-04-26 03:49:40 +02:00
|
|
|
public function testValidateMinDate()
|
|
|
|
{
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setMinDatetime('2009-03-31 23:00:00');
|
|
|
|
$dateField->setValue('2009-03-31 23:00:01');
|
|
|
|
$this->assertTrue($dateField->validate(new RequiredFields()), 'Time above min datetime');
|
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setMinDatetime('2009-03-31 23:00:00');
|
|
|
|
$dateField->setValue('2009-03-31 22:00:00');
|
|
|
|
$this->assertFalse($dateField->validate(new RequiredFields()), 'Time below min datetime');
|
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setMinDatetime('2009-03-31 23:00:00');
|
|
|
|
$dateField->setValue('2009-03-31 23:00:00');
|
|
|
|
$this->assertTrue($dateField->validate(new RequiredFields()), 'Date and time matching min datetime');
|
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setMinDatetime('2009-03-31 23:00:00');
|
|
|
|
$dateField->setValue('2008-03-31 23:00:00');
|
|
|
|
$this->assertFalse($dateField->validate(new RequiredFields()), 'Date below min datetime');
|
2017-04-27 04:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testValidateMinDateWithSubmittedValueAndTimezone()
|
|
|
|
{
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere winter
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
2017-04-26 03:49:59 +02:00
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
2017-04-27 04:59:11 +02:00
|
|
|
$dateField->setTimezone('Pacific/Auckland');
|
|
|
|
$dateField->setMinDatetime('2009-01-30 23:00:00'); // server timezone (Berlin)
|
|
|
|
$dateField->setSubmittedValue('2009-01-31T11:00:01'); // frontend timezone (Auckland)
|
|
|
|
$this->assertTrue($dateField->validate(new RequiredFields()), 'Time above min datetime');
|
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setTimezone('Pacific/Auckland');
|
|
|
|
$dateField->setMinDatetime('2009-01-30 23:00:00');
|
|
|
|
$dateField->setSubmittedValue('2009-01-31T10:00:00');
|
|
|
|
$this->assertFalse($dateField->validate(new RequiredFields()), 'Time below min datetime');
|
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setTimezone('Pacific/Auckland');
|
|
|
|
$dateField->setMinDatetime('2009-01-30 23:00:00');
|
|
|
|
$dateField->setSubmittedValue('2009-01-31T11:00:00');
|
|
|
|
$this->assertTrue($dateField->validate(new RequiredFields()), 'Date and time matching min datetime');
|
|
|
|
|
|
|
|
$dateField = new DatetimeField('Datetime');
|
|
|
|
$dateField->setTimezone('Pacific/Auckland');
|
|
|
|
$dateField->setMinDatetime('2009-01-30 23:00:00');
|
|
|
|
$dateField->setSubmittedValue('2008-01-31T11:00:00');
|
|
|
|
$this->assertFalse($dateField->validate(new RequiredFields()), 'Date below min datetime');
|
2017-04-26 03:49:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testValidateMinDateStrtotime()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMinDatetime('-7 days');
|
2022-04-06 01:34:34 +02:00
|
|
|
$f->setValue(date('Y-m-d H:i:s', strtotime('-8 days', DBDatetime::now()->getTimestamp())));
|
2017-04-26 03:49:40 +02:00
|
|
|
$this->assertFalse($f->validate(new RequiredFields()), 'Date below min datetime, with strtotime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMinDatetime('-7 days');
|
2022-04-06 01:34:34 +02:00
|
|
|
$f->setValue(date('Y-m-d H:i:s', strtotime('-7 days', DBDatetime::now()->getTimestamp())));
|
2017-04-26 03:49:40 +02:00
|
|
|
$this->assertTrue($f->validate(new RequiredFields()), 'Date matching min datetime, with strtotime');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testValidateMaxDateStrtotime()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMaxDatetime('7 days');
|
2022-04-06 01:34:34 +02:00
|
|
|
$f->setValue(date('Y-m-d H:i:s', strtotime('8 days', DBDatetime::now()->getTimestamp())));
|
2017-04-26 03:49:40 +02:00
|
|
|
$this->assertFalse($f->validate(new RequiredFields()), 'Date above max date, with strtotime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMaxDatetime('7 days');
|
2022-04-06 01:34:34 +02:00
|
|
|
$f->setValue(date('Y-m-d H:i:s', strtotime('7 days', DBDatetime::now()->getTimestamp())));
|
2017-04-26 03:49:40 +02:00
|
|
|
$this->assertTrue($f->validate(new RequiredFields()), 'Date matching max date, with strtotime');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testValidateMaxDate()
|
|
|
|
{
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMaxDatetime('2009-03-31 23:00:00');
|
|
|
|
$f->setValue('2009-03-31 22:00:00');
|
|
|
|
$this->assertTrue($f->validate(new RequiredFields()), 'Time below max datetime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMaxDatetime('2009-03-31 23:00:00');
|
|
|
|
$f->setValue('2010-03-31 23:00:01');
|
|
|
|
$this->assertFalse($f->validate(new RequiredFields()), 'Time above max datetime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMaxDatetime('2009-03-31 23:00:00');
|
|
|
|
$f->setValue('2009-03-31 23:00:00');
|
|
|
|
$this->assertTrue($f->validate(new RequiredFields()), 'Date and time matching max datetime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setMaxDatetime('2009-03-31 23:00:00');
|
|
|
|
$f->setValue('2010-03-31 23:00:00');
|
|
|
|
$this->assertFalse($f->validate(new RequiredFields()), 'Date above max datetime');
|
2017-04-27 04:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testValidateMaxDateWithSubmittedValueAndTimezone()
|
|
|
|
{
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere winter
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
2017-04-26 03:49:59 +02:00
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
2017-04-27 04:59:11 +02:00
|
|
|
$f->setTimezone('Pacific/Auckland');
|
|
|
|
$f->setMaxDatetime('2009-01-31 23:00:00'); // server timezone (Berlin)
|
|
|
|
$f->setSubmittedValue('2009-01-31T10:00:00'); // frontend timezone (Auckland)
|
|
|
|
$this->assertTrue($f->validate(new RequiredFields()), 'Time below max datetime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setTimezone('Pacific/Auckland');
|
|
|
|
$f->setMaxDatetime('2009-01-31 23:00:00');
|
|
|
|
$f->setSubmittedValue('2010-01-31T11:00:01');
|
|
|
|
$this->assertFalse($f->validate(new RequiredFields()), 'Time above max datetime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setTimezone('Pacific/Auckland');
|
|
|
|
$f->setMaxDatetime('2009-01-31 23:00:00');
|
|
|
|
$f->setSubmittedValue('2009-01-31T11:00:00');
|
|
|
|
$this->assertTrue($f->validate(new RequiredFields()), 'Date and time matching max datetime');
|
|
|
|
|
|
|
|
$f = new DatetimeField('Datetime');
|
|
|
|
$f->setTimezone('Pacific/Auckland');
|
|
|
|
$f->setMaxDatetime('2009-01-31 23:00:00');
|
|
|
|
$f->setSubmittedValue('2010-01-31T11:00:00');
|
|
|
|
$this->assertFalse($f->validate(new RequiredFields()), 'Date above max datetime');
|
2017-04-26 03:49:40 +02:00
|
|
|
}
|
|
|
|
|
2017-04-26 03:49:59 +02:00
|
|
|
public function testTimezoneSetValueLocalised()
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere winter
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField = new DatetimeField('Datetime', 'Datetime');
|
2017-04-03 09:35:40 +02:00
|
|
|
|
2017-04-20 05:08:44 +02:00
|
|
|
$datetimeField
|
2017-04-03 09:35:40 +02:00
|
|
|
->setHTML5(false)
|
2017-04-26 23:18:38 +02:00
|
|
|
->setDatetimeFormat('dd/MM/y HH:mm:ss');
|
2017-04-03 09:35:40 +02:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField->setTimezone('Pacific/Auckland');
|
|
|
|
$datetimeField->setValue('2003-12-24 23:59:59');
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2017-04-26 23:18:38 +02:00
|
|
|
'25/12/2003 11:59:59',
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField->Value(),
|
2016-12-16 05:34:21 +01:00
|
|
|
'User value is formatted, and in user timezone'
|
|
|
|
);
|
2017-04-20 05:08:44 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
|
|
|
'2003-12-24 23:59:59',
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField->dataValue(),
|
2017-04-26 03:49:59 +02:00
|
|
|
'Data value is in ISO format, and in server timezone'
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-04-26 03:49:59 +02:00
|
|
|
public function testTimezoneSetValueWithHtml5()
|
|
|
|
{
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere winter
|
|
|
|
$datetimeField = new DatetimeField('Datetime', 'Datetime');
|
|
|
|
|
|
|
|
$datetimeField->setTimezone('Pacific/Auckland');
|
|
|
|
$datetimeField->setValue('2003-12-24 23:59:59');
|
|
|
|
$this->assertEquals(
|
|
|
|
'2003-12-25T11:59:59',
|
|
|
|
$datetimeField->Value(),
|
|
|
|
'User value is in normalised ISO format and in user timezone'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'2003-12-24 23:59:59',
|
|
|
|
$datetimeField->dataValue(),
|
|
|
|
'Data value is in ISO format, and in server timezone'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testTimezoneSetSubmittedValueLocalised()
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere summer, but Berlin and Moscow only 2h.
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField = new DatetimeField('Datetime', 'Datetime');
|
2017-04-03 09:35:40 +02:00
|
|
|
|
2017-04-20 05:08:44 +02:00
|
|
|
$datetimeField
|
2017-04-03 09:35:40 +02:00
|
|
|
->setHTML5(false)
|
|
|
|
->setLocale('en_NZ');
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
$datetimeField->setTimezone('Europe/Moscow');
|
2017-04-20 05:08:44 +02:00
|
|
|
// pass in default format, at user time (Moscow)
|
|
|
|
$datetimeField->setSubmittedValue('24/06/2003 11:59:59 pm');
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->assertTrue($datetimeField->validate(new RequiredFields()));
|
|
|
|
$this->assertEquals('2003-06-24 21:59:59', $datetimeField->dataValue(), 'Data value matches server timezone');
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetName()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
|
|
|
|
$this->assertEquals('Datetime', $field->getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetName()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime', 'Datetime');
|
|
|
|
$field->setName('CustomDatetime');
|
|
|
|
$this->assertEquals('CustomDatetime', $field->getName());
|
|
|
|
}
|
|
|
|
|
2017-04-27 04:59:11 +02:00
|
|
|
public function testSchemaDataDefaultsIncludesMinMax()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
$field->setMinDatetime('2009-03-31 23:00:00');
|
|
|
|
$field->setMaxDatetime('2010-03-31 23:00:00');
|
|
|
|
$defaults = $field->getSchemaDataDefaults();
|
|
|
|
$this->assertEquals($defaults['data']['min'], '2009-03-31T23:00:00');
|
|
|
|
$this->assertEquals($defaults['data']['max'], '2010-03-31T23:00:00');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSchemaDataDefaultsAdjustsMinMaxToTimezone()
|
|
|
|
{
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere summer, but Berlin and Moscow only 2h.
|
|
|
|
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
$field->setTimezone('Pacific/Auckland');
|
|
|
|
$field->setMinDatetime('2009-01-31 11:00:00'); // server timezone
|
|
|
|
$field->setMaxDatetime('2010-01-31 11:00:00'); // server timezone
|
|
|
|
$defaults = $field->getSchemaDataDefaults();
|
|
|
|
$this->assertEquals($defaults['data']['min'], '2009-01-31T23:00:00'); // frontend timezone
|
|
|
|
$this->assertEquals($defaults['data']['max'], '2010-01-31T23:00:00'); // frontend timezone
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testAttributesIncludesMinMax()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
$field->setMinDatetime('2009-03-31 23:00:00');
|
|
|
|
$field->setMaxDatetime('2010-03-31 23:00:00');
|
|
|
|
$attrs = $field->getAttributes();
|
|
|
|
$this->assertEquals($attrs['min'], '2009-03-31T23:00:00');
|
|
|
|
$this->assertEquals($attrs['max'], '2010-03-31T23:00:00');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testAttributesAdjustsMinMaxToTimezone()
|
|
|
|
{
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
// Berlin and Auckland have 12h time difference in northern hemisphere summer, but Berlin and Moscow only 2h.
|
|
|
|
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
$field->setTimezone('Pacific/Auckland');
|
|
|
|
$field->setMinDatetime('2009-01-31 11:00:00'); // server timezone
|
|
|
|
$field->setMaxDatetime('2010-01-31 11:00:00'); // server timezone
|
|
|
|
$attrs = $field->getAttributes();
|
|
|
|
$this->assertEquals($attrs['min'], '2009-01-31T23:00:00'); // frontend timezone
|
|
|
|
$this->assertEquals($attrs['max'], '2010-01-31T23:00:00'); // frontend timezone
|
|
|
|
}
|
|
|
|
|
2018-10-20 18:29:07 +02:00
|
|
|
public function testAttributesNonHTML5()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
$field->setHTML5(false);
|
|
|
|
$result = $field->getAttributes();
|
|
|
|
$this->assertSame('text', $result['type']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFrontendToInternalEdgeCases()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
|
|
|
|
$this->assertNull($field->frontendToInternal(false));
|
|
|
|
$this->assertNull($field->frontendToInternal('sdfsdfsfs$%^&*'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testInternalToFrontendEdgeCases()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
|
|
|
|
$this->assertNull($field->internalToFrontend(false));
|
|
|
|
$this->assertNull($field->internalToFrontend('sdfsdfsfs$%^&*'));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testPerformReadonlyTransformation()
|
|
|
|
{
|
|
|
|
$field = new DatetimeField('Datetime');
|
|
|
|
|
|
|
|
$result = $field->performReadonlyTransformation();
|
|
|
|
$this->assertInstanceOf(DatetimeField::class, $result);
|
|
|
|
$this->assertNotSame($result, $field, 'Readonly field should be cloned');
|
|
|
|
$this->assertTrue($result->isReadonly());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetTimezoneThrowsExceptionWhenChangingTimezoneAfterSettingValue()
|
|
|
|
{
|
2021-10-27 04:39:47 +02:00
|
|
|
$this->expectException(\BadMethodCallException::class);
|
|
|
|
$this->expectExceptionMessage("Can't change timezone after setting a value");
|
2018-10-20 18:29:07 +02:00
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
$field = new DatetimeField('Datetime', 'Time', '2003-03-29 23:59:38');
|
|
|
|
$field->setTimezone('Pacific/Auckland');
|
|
|
|
}
|
|
|
|
|
2022-01-17 21:41:11 +01:00
|
|
|
public function testModifyReturnNewField(): void
|
|
|
|
{
|
|
|
|
$globalStateNow = '2020-01-01 00:00:00';
|
|
|
|
DBDatetime::set_mock_now($globalStateNow);
|
|
|
|
|
|
|
|
// Suppose we need to know the current time in our feature, we store it in a variable
|
|
|
|
// Make this field immutable, so future modifications don't apply to any other object references
|
|
|
|
$now = DBDatetime::now()->setImmutable(true);
|
|
|
|
|
|
|
|
// Later in the code we want to know the time value for 10 days later, we can reuse our $now variable
|
|
|
|
$later = $now->modify('+ 10 days')->Rfc2822();
|
|
|
|
|
|
|
|
// Our expectation is that this code should not apply the change to our
|
|
|
|
// $now variable declared earlier in the code
|
|
|
|
$this->assertSame('2020-01-11 00:00:00', $later, 'We expect to get a future datetime');
|
|
|
|
$this->assertSame($globalStateNow, $now->Rfc2822(), 'We expect to get the current datetime');
|
|
|
|
}
|
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
protected function getMockForm()
|
|
|
|
{
|
|
|
|
return new Form(
|
2017-06-22 12:50:45 +02:00
|
|
|
Controller::curr(),
|
2016-12-16 05:34:21 +01:00
|
|
|
'Form',
|
|
|
|
new FieldList(),
|
|
|
|
new FieldList(
|
|
|
|
new FormAction('doSubmit')
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2010-10-15 05:48:39 +02:00
|
|
|
}
|