2009-02-02 00:49:53 +01:00
|
|
|
<?php
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2016-10-14 03:30:05 +02:00
|
|
|
namespace SilverStripe\ORM\Tests;
|
2016-06-15 06:03:16 +02:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
use PHPUnit_Framework_Error_Notice;
|
|
|
|
use SilverStripe\i18n\i18n;
|
|
|
|
use SilverStripe\ORM\FieldType\DBDate;
|
2016-06-15 06:03:16 +02:00
|
|
|
use SilverStripe\ORM\FieldType\DBField;
|
|
|
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\Dev\SapphireTest;
|
2016-10-14 03:30:05 +02:00
|
|
|
use SilverStripe\Security\Member;
|
2016-08-19 00:51:35 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
class DBDateTest extends SapphireTest
|
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
protected $oldError = null;
|
2016-12-16 05:34:21 +01:00
|
|
|
|
|
|
|
public function setUp()
|
|
|
|
{
|
|
|
|
parent::setUp();
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->oldError = error_reporting();
|
|
|
|
// Validate setup
|
|
|
|
assert(date_default_timezone_get() === 'UTC');
|
|
|
|
i18n::set_locale('en_NZ');
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function tearDown()
|
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->restoreNotices();
|
2016-12-16 05:34:21 +01:00
|
|
|
parent::tearDown();
|
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Temporarily disable notices
|
|
|
|
*/
|
|
|
|
protected function suppressNotices()
|
|
|
|
{
|
|
|
|
error_reporting(error_reporting() & ~E_USER_NOTICE);
|
|
|
|
\PHPUnit_Framework_Error_Notice::$enabled = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Restore notices
|
|
|
|
*/
|
|
|
|
protected function restoreNotices()
|
|
|
|
{
|
|
|
|
error_reporting($this->oldError);
|
|
|
|
\PHPUnit_Framework_Error_Notice::$enabled = true;
|
|
|
|
}
|
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testNiceDate()
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
'31/03/2008',
|
|
|
|
DBField::create_field('Date', 1206968400)->Nice(),
|
|
|
|
"Date->Nice() works with timestamp integers"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'30/03/2008',
|
|
|
|
DBField::create_field('Date', 1206882000)->Nice(),
|
|
|
|
"Date->Nice() works with timestamp integers"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'31/03/2008',
|
|
|
|
DBField::create_field('Date', '1206968400')->Nice(),
|
|
|
|
"Date->Nice() works with timestamp strings"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'30/03/2008',
|
|
|
|
DBField::create_field('Date', '1206882000')->Nice(),
|
|
|
|
"Date->Nice() works with timestamp strings"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '4.3.2003')->Nice(),
|
|
|
|
"Date->Nice() works with D.M.YYYY format"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '04.03.2003')->Nice(),
|
|
|
|
"Date->Nice() works with DD.MM.YYYY format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '2003-3-4')->Nice(),
|
|
|
|
"Date->Nice() works with YYYY-M-D format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '2003-03-04')->Nice(),
|
|
|
|
"Date->Nice() works with YYYY-MM-DD format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
2017-01-26 05:20:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testMDYConversion()
|
|
|
|
{
|
|
|
|
// Disable notices
|
|
|
|
$this->suppressNotices();
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '3/4/2003')->Nice(),
|
|
|
|
"Date->Nice() works with M/D/YYYY format"
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->setExpectedException(
|
|
|
|
PHPUnit_Framework_Error_Notice::class,
|
|
|
|
"Implicit m/d/y conversion. Use " . DBDate::ISO_DATE . " to prevent this notice."
|
|
|
|
);
|
|
|
|
$this->restoreNotices();
|
|
|
|
DBField::create_field('Date', '3/4/2003');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testYDMConversion()
|
|
|
|
{
|
|
|
|
// Disable notices
|
|
|
|
$this->suppressNotices();
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '2003/4/3')->Nice(),
|
|
|
|
"Date->Nice() works with YYYY/D/M format"
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->setExpectedException(
|
|
|
|
PHPUnit_Framework_Error_Notice::class,
|
|
|
|
"Implicit y/d/m conversion. Use " . DBDate::ISO_DATE . " to prevent this notice."
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->restoreNotices();
|
|
|
|
DBField::create_field('Date', '2003/4/3');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testY2kCorrection()
|
|
|
|
{
|
|
|
|
$this->suppressNotices();
|
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '4.3.03')->Nice(),
|
|
|
|
"Date->Nice() works with D.M.YY format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '04.03.03')->Nice(),
|
|
|
|
"Date->Nice() works with DD.MM.YY format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '4.3.03')->Nice(),
|
|
|
|
"Date->Nice() works with D.M.YY format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '4.03.03')->Nice(),
|
|
|
|
"Date->Nice() works with D.M.YY format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '03-03-04')->Nice(),
|
|
|
|
"Date->Nice() works with Y-m-d format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->setExpectedException(
|
|
|
|
PHPUnit_Framework_Error_Notice::class,
|
|
|
|
"Implicit y2k conversion. Please use full YYYY year for dates"
|
|
|
|
);
|
|
|
|
$this->restoreNotices();
|
|
|
|
DBField::create_field('Date', '03-03-04');
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
public function testInvertedYearCorrection()
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->suppressNotices();
|
|
|
|
|
|
|
|
// iso8601 expects year first
|
2016-12-16 05:34:21 +01:00
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'4/03/2003',
|
|
|
|
DBField::create_field('Date', '04-03-2003')->Nice(),
|
|
|
|
"Date->Nice() works with DD-MM-YYYY format"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
2017-01-26 05:20:08 +01:00
|
|
|
|
|
|
|
$this->setExpectedException(
|
|
|
|
PHPUnit_Framework_Error_Notice::class,
|
|
|
|
"Unexpected date order. Use " . DBDate::ISO_DATE . " to prevent this notice."
|
|
|
|
);
|
|
|
|
$this->restoreNotices();
|
|
|
|
DBField::create_field('Date', '04-03-2003');
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testYear()
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
'2008',
|
|
|
|
DBField::create_field('Date', 1206968400)->Year(),
|
|
|
|
"Date->Year() works with timestamp integers"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
public function testDayOfWeek()
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
'Monday',
|
2017-01-26 05:20:08 +01:00
|
|
|
DBField::create_field('Date', 1206968400)->DayOfWeek(),
|
2016-12-16 05:34:21 +01:00
|
|
|
"Date->Day() works with timestamp integers"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testMonth()
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
'March',
|
|
|
|
DBField::create_field('Date', 1206968400)->Month(),
|
|
|
|
"Date->Month() works with timestamp integers"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testShortMonth()
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
'Mar',
|
|
|
|
DBField::create_field('Date', 1206968400)->ShortMonth(),
|
|
|
|
"Date->ShortMonth() works with timestamp integers"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testLongDate()
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
|
|
|
'31 March 2008',
|
|
|
|
DBField::create_field('Date', 1206968400)->Long(),
|
|
|
|
"Date->Long() works with numeric timestamp"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'31 March 2008',
|
|
|
|
DBField::create_field('Date', '1206968400')->Long(),
|
|
|
|
"Date->Long() works with string timestamp"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'30 March 2008',
|
|
|
|
DBField::create_field('Date', 1206882000)->Long(),
|
|
|
|
"Date->Long() works with numeric timestamp"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'30 March 2008',
|
|
|
|
DBField::create_field('Date', '1206882000')->Long(),
|
|
|
|
"Date->Long() works with numeric timestamp"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'3 April 2003',
|
|
|
|
DBField::create_field('Date', '2003-4-3')->Long(),
|
|
|
|
"Date->Long() works with YYYY-M-D"
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
'3 April 2003',
|
2017-01-26 05:20:08 +01:00
|
|
|
DBField::create_field('Date', '3.4.2003')->Long(),
|
|
|
|
"Date->Long() works with D.M.YYYY"
|
2016-12-16 05:34:21 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFull()
|
|
|
|
{
|
|
|
|
$this->assertEquals(
|
2017-01-26 05:20:08 +01:00
|
|
|
'Monday, 31 March 2008',
|
2016-12-16 05:34:21 +01:00
|
|
|
DBField::create_field('Date', 1206968400)->Full(),
|
|
|
|
"Date->Full() works with timestamp integers"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetNullAndZeroValues()
|
|
|
|
{
|
|
|
|
$date = DBField::create_field('Date', '');
|
|
|
|
$this->assertNull($date->getValue(), 'Empty string evaluates to NULL');
|
|
|
|
|
|
|
|
$date = DBField::create_field('Date', null);
|
|
|
|
$this->assertNull($date->getValue(), 'NULL is set as NULL');
|
|
|
|
|
|
|
|
$date = DBField::create_field('Date', false);
|
|
|
|
$this->assertNull($date->getValue(), 'Boolean FALSE evaluates to NULL');
|
|
|
|
|
|
|
|
$date = DBField::create_field('Date', array());
|
|
|
|
$this->assertNull($date->getValue(), 'Empty array evaluates to NULL');
|
|
|
|
|
|
|
|
$date = DBField::create_field('Date', '0');
|
|
|
|
$this->assertEquals('1970-01-01', $date->getValue(), 'Zero is UNIX epoch date');
|
|
|
|
|
|
|
|
$date = DBField::create_field('Date', 0);
|
|
|
|
$this->assertEquals('1970-01-01', $date->getValue(), 'Zero is UNIX epoch date');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testDayOfMonth()
|
|
|
|
{
|
|
|
|
$date = DBField::create_field('Date', '2000-10-10');
|
|
|
|
$this->assertEquals('10', $date->DayOfMonth());
|
|
|
|
$this->assertEquals('10th', $date->DayOfMonth(true));
|
|
|
|
|
|
|
|
$range = $date->RangeString(DBField::create_field('Date', '2000-10-20'));
|
|
|
|
$this->assertEquals('10 - 20 Oct 2000', $range);
|
|
|
|
$range = $date->RangeString(DBField::create_field('Date', '2000-10-20'), true);
|
|
|
|
$this->assertEquals('10th - 20th Oct 2000', $range);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testExtendedDates()
|
|
|
|
{
|
|
|
|
$date = DBField::create_field('Date', '1800-10-10');
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->assertEquals('10 Oct 1800', $date->Format('dd MMM y'));
|
2016-12-16 05:34:21 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// Note: Fails around 1500 or older
|
|
|
|
$date = DBField::create_field('Date', '1600-10-10');
|
|
|
|
$this->assertEquals('10 Oct 1600', $date->Format('dd MMM y'));
|
2016-12-16 05:34:21 +01:00
|
|
|
|
|
|
|
$date = DBField::create_field('Date', '3000-4-3');
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->assertEquals('03 Apr 3000', $date->Format('dd MMM y'));
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testAgoInPast()
|
|
|
|
{
|
|
|
|
DBDatetime::set_mock_now('2000-12-31 12:00:00');
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'1 month ago',
|
|
|
|
DBField::create_field('Date', '2000-11-26')->Ago(true, 1),
|
|
|
|
'Past match on days, less than two months, lowest significance'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'50 days ago', // Rounded from 49.5 days up
|
|
|
|
DBField::create_field('Date', '2000-11-12')->Ago(),
|
|
|
|
'Past match on days, less than two months'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'2 months ago',
|
|
|
|
DBField::create_field('Date', '2000-10-27')->Ago(),
|
|
|
|
'Past match on days, over two months'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'66 days ago', // rounded from 65.5 days up
|
|
|
|
DBField::create_field('Date', '2000-10-27')->Ago(true, 3),
|
|
|
|
'Past match on days, over two months, significance of 3'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'10 years ago',
|
|
|
|
DBField::create_field('Date', '1990-12-31')->Ago(),
|
|
|
|
'Exact past match on years'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'10 years ago',
|
|
|
|
DBField::create_field('Date', '1990-12-30')->Ago(),
|
|
|
|
'Approximate past match on years'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'1 year ago',
|
|
|
|
DBField::create_field('Date', '1999-12-30')->Ago(true, 1),
|
|
|
|
'Approximate past match in singular, lowest significance'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'12 months ago',
|
|
|
|
DBField::create_field('Date', '1999-12-30')->Ago(),
|
|
|
|
'Approximate past match in singular'
|
|
|
|
);
|
|
|
|
|
|
|
|
DBDatetime::clear_mock_now();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testAgoInFuture()
|
|
|
|
{
|
|
|
|
DBDatetime::set_mock_now('2000-12-31 00:00:00');
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'in 10 years',
|
|
|
|
DBField::create_field('Date', '2010-12-31')->Ago(),
|
|
|
|
'Exact past match on years'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'in 1 day',
|
|
|
|
DBField::create_field('Date', '2001-01-01')->Ago(true, 1),
|
|
|
|
'Approximate past match on minutes'
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
'in 24 hours',
|
|
|
|
DBField::create_field('Date', '2001-01-01')->Ago(),
|
|
|
|
'Approximate past match on minutes'
|
|
|
|
);
|
|
|
|
|
|
|
|
DBDatetime::clear_mock_now();
|
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* @see testFormatFromSettings
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function dataTestFormatFromSettings()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
['2000-12-31', '31/12/2000'],
|
|
|
|
['31-12-2000', '31/12/2000'],
|
|
|
|
['12/31/2000', '31/12/2000'],
|
|
|
|
['2014-04-01', '01/04/2014'],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataTestFormatFromSettings
|
|
|
|
* @param string $from
|
|
|
|
* @param string $to
|
|
|
|
*/
|
|
|
|
public function testFormatFromSettings($from, $to)
|
2016-12-16 05:34:21 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->suppressNotices();
|
|
|
|
$member = new Member();
|
|
|
|
$member->DateFormat = 'dd/MM/y';
|
2016-12-16 05:34:21 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
$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());
|
2016-12-16 05:34:21 +01:00
|
|
|
}
|
2009-02-02 00:49:53 +01:00
|
|
|
}
|