silverstripe-framework/model/fieldtypes/Datetime.php

129 lines
3.7 KiB
PHP
Raw Normal View History

<?php
/**
* Represents a date-time field.
* The field currently supports New Zealand date format (DD/MM/YYYY),
* or an ISO 8601 formatted date and time (Y-m-d H:i:s).
* Alternatively you can set a timestamp that is evaluated through
* PHP's built-in date() and strtotime() function according to your system locale.
*
* For all computations involving the current date and time,
* please use {@link SS_Datetime::now()} instead of PHP's built-in date() and time()
* methods. This ensures that all time-based computations are testable with mock dates
* through {@link SS_Datetime::set_mock_now()}.
*
* Example definition via {@link DataObject::$db}:
* <code>
* static $db = array(
* "Expires" => "SS_Datetime",
* );
* </code>
*
* @todo Add localization support, see http://open.silverstripe.com/ticket/2931
*
* @package sapphire
* @subpackage model
*/
class SS_Datetime extends Date {
function setValue($value, $record = null) {
if($value === false || $value === null || (is_string($value) && !strlen($value))) {
// don't try to evaluate empty values with strtotime() below, as it returns "1970-01-01" when it should be saved as NULL in database
$this->value = null;
return;
}
// Default to NZ date format - strtotime expects a US date
2012-02-27 22:14:02 +01:00
if(preg_match('#^([0-9]+)/([0-9]+)/([0-9]+)$#', $value, $parts)) {
$value = "$parts[2]/$parts[1]/$parts[3]";
}
2012-02-27 22:14:02 +01:00
if(is_numeric($value)) {
$this->value = date('Y-m-d H:i:s', $value);
} elseif(is_string($value)) {
$this->value = date('Y-m-d H:i:s', strtotime($value));
}
}
/**
* Returns the date in the raw SQL-format, e.g. “2006-01-18 16:32:04
*/
function Nice() {
if($this->value) return date('d/m/Y g:ia', strtotime($this->value));
}
function Nice24() {
if($this->value) return date('d/m/Y H:i', strtotime($this->value));
}
function Date() {
if($this->value) return date('d/m/Y', strtotime($this->value));
}
function Time() {
if($this->value) return date('g:ia', strtotime($this->value));
}
function Time24() {
if($this->value) return date('H:i', strtotime($this->value));
}
function requireField() {
$parts=Array('datatype'=>'datetime', 'arrayValue'=>$this->arrayValue);
$values=Array('type'=>'SS_Datetime', 'parts'=>$parts);
DB::requireField($this->tableName, $this->name, $values);
}
function URLDatetime() {
if($this->value) return date('Y-m-d%20H:i:s', strtotime($this->value));
}
public function scaffoldFormField($title = null, $params = null) {
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
return new DatetimeField($this->name, $title);
}
/**
*
*/
protected static $mock_now = null;
/**
* Returns either the current system date as determined
* by date(), or a mocked date through {@link set_mock_now()}.
*
* @return SS_Datetime
*/
static function now() {
if(self::$mock_now) {
return self::$mock_now;
} else {
return DBField::create_field('SS_Datetime', date('Y-m-d H:i:s'));
}
}
/**
* Mock the system date temporarily, which is useful for time-based unit testing.
* Use {@link clear_mock_now()} to revert to the current system date.
* Caution: This sets a fixed date that doesn't increment with time.
*
* @param SS_Datetime|string $datetime Either in object format, or as a SS_Datetime compatible string.
*/
static function set_mock_now($datetime) {
if($datetime instanceof SS_Datetime) {
self::$mock_now = $datetime;
} elseif(is_string($datetime)) {
self::$mock_now = DBField::create_field('SS_Datetime', $datetime);
} else {
throw new Exception('SS_Datetime::set_mock_now(): Wrong format: ' . $datetime);
}
}
/**
* Clear any mocked date, which causes
* {@link Now()} to return the current system date.
*/
static function clear_mock_now() {
self::$mock_now = null;
}
}