Skip to content
Snippets Groups Projects
Unverified Commit 25318a4b authored by Peter Rotich's avatar Peter Rotich Committed by GitHub
Browse files

Merge pull request #4535 from protich/feature/DateTimePeriod

Add period to DateTimeField
parents a2ee0bcd 7d3dfd0a
Branches
Tags
No related merge requests found
...@@ -1974,10 +1974,25 @@ class DatetimeField extends FormField { ...@@ -1974,10 +1974,25 @@ class DatetimeField extends FormField {
'w' => _N('week', 'weeks', $count), 'w' => _N('week', 'weeks', $count),
'm' => _N('month', 'months', $count), 'm' => _N('month', 'months', $count),
); );
return $i ? $intervals[$i] : $intervals; return $i ? $intervals[$i] : $intervals;
} }
static function periods($period='') {
$periods = array(
'td' => __('Today'),
'yd' => __('Yesterday'),
'tw' => __('This Week'),
'tm' => __('This Month'),
'tq' => __('This Quater'),
'ty' => __('This Year'),
'lw' => __('Last Week'),
'lm' => __('Last Month'),
'lq' => __('Last Quater'),
'ly' => __('Last Year'),
);
return $period ? $periods[$period] : $periods;
}
// Get php DatateTime object of the field - null if value is empty // Get php DatateTime object of the field - null if value is empty
function getDateTime($value=null) { function getDateTime($value=null) {
return Format::parseDateTime($value ?: $this->value); return Format::parseDateTime($value ?: $this->value);
...@@ -2190,6 +2205,7 @@ class DatetimeField extends FormField { ...@@ -2190,6 +2205,7 @@ class DatetimeField extends FormField {
'before' => __('before'), 'before' => __('before'),
'after' => __('after'), 'after' => __('after'),
'between' => __('between'), 'between' => __('between'),
'period' => __('period'),
'ndaysago' => __('in the last n days'), 'ndaysago' => __('in the last n days'),
'ndays' => __('in the next n days'), 'ndays' => __('in the next n days'),
'future' => __('in the future'), 'future' => __('in the future'),
...@@ -2239,6 +2255,9 @@ class DatetimeField extends FormField { ...@@ -2239,6 +2255,9 @@ class DatetimeField extends FormField {
'right' => new DatetimeField(), 'right' => new DatetimeField(),
), ),
)), )),
'period' => array('ChoiceField', array(
'choices' => self::periods(),
)),
'ndaysago' => array('InlineformField', array('form'=>$nday_form())), 'ndaysago' => array('InlineformField', array('form'=>$nday_form())),
'ndays' => array('InlineformField', array('form'=>$nday_form())), 'ndays' => array('InlineformField', array('form'=>$nday_form())),
'distfut' => array('InlineformField', array('form'=>$nday_form())), 'distfut' => array('InlineformField', array('form'=>$nday_form())),
...@@ -2247,6 +2266,8 @@ class DatetimeField extends FormField { ...@@ -2247,6 +2266,8 @@ class DatetimeField extends FormField {
} }
function getSearchQ($method, $value, $name=false) { function getSearchQ($method, $value, $name=false) {
global $cfg;
static $intervals = array( static $intervals = array(
'm' => 'MONTH', 'm' => 'MONTH',
'w' => 'WEEK', 'w' => 'WEEK',
...@@ -2257,10 +2278,9 @@ class DatetimeField extends FormField { ...@@ -2257,10 +2278,9 @@ class DatetimeField extends FormField {
$name = $name ?: $this->get('name'); $name = $name ?: $this->get('name');
$now = SqlFunction::NOW(); $now = SqlFunction::NOW();
$config = $this->getConfiguration(); $config = $this->getConfiguration();
if (is_int($value)) if (is_int($value))
$value = DateTime::createFromFormat('U', !$config['gmt'] ? Misc::gmtime($value) : $value) ?: $value; $value = DateTime::createFromFormat('U', !$config['gmt'] ? Misc::gmtime($value) : $value) ?: $value;
elseif (is_string($value)) elseif (is_string($value) && strlen($value) > 2)
$value = Format::parseDateTime($value) ?: $value; $value = Format::parseDateTime($value) ?: $value;
switch ($method) { switch ($method) {
...@@ -2322,6 +2342,27 @@ class DatetimeField extends FormField { ...@@ -2322,6 +2342,27 @@ class DatetimeField extends FormField {
return new Q(array( return new Q(array(
"{$name}__gte" => $now->plus($interval), "{$name}__gte" => $now->plus($interval),
)); ));
case 'period':
// Get the period range boundaries - timezone doesn't matter
$period = Misc::date_range($value, Misc::gmtime('now'));
$tz = new DateTimeZone($cfg->getTimezone());
// Get datetime boundaries in user's effective timezone
$tz = new DateTimeZone($cfg->getTimezone());
$start = new DateTime($period->start->format('Y-m-d H:i:s'),
$tz);
$end = new DateTime($period->end->format('Y-m-d H:i:s'), $tz);
// Convert boundaries to db time
$dbtz = new DateTimeZone($cfg->getDbTimezone());
$start->setTimezone($dbtz);
$end->setTimezone($dbtz);
// Set the range
return new Q(array(
"{$name}__range" => array(
$start->format('Y-m-d H:i:s'),
$end->format('Y-m-d H:i:s')
)
));
break;
default: default:
return parent::getSearchQ($method, $value, $name); return parent::getSearchQ($method, $value, $name);
} }
...@@ -2347,6 +2388,8 @@ class DatetimeField extends FormField { ...@@ -2347,6 +2388,8 @@ class DatetimeField extends FormField {
return __('%1$s is in the future'); return __('%1$s is in the future');
case 'past': case 'past':
return __('%1$s is in the past'); return __('%1$s is in the past');
case 'period':
return __('%1$s is %2$s');
default: default:
return parent::describeSearchMethod($method); return parent::describeSearchMethod($method);
} }
...@@ -2375,6 +2418,8 @@ class DatetimeField extends FormField { ...@@ -2375,6 +2418,8 @@ class DatetimeField extends FormField {
case 'before': case 'before':
case 'after': case 'after':
return sprintf($desc, $name, $this->toString($value)); return sprintf($desc, $name, $this->toString($value));
case 'period':
return sprintf($desc, $name, self::periods($value) ?: $value);
default: default:
return parent::describeSearch($method, $value, $name); return parent::describeSearch($method, $value, $name);
} }
......
...@@ -143,6 +143,85 @@ class Misc { ...@@ -143,6 +143,85 @@ class Misc {
return ((float)$usec + (float)$sec); return ((float)$usec + (float)$sec);
} }
// Date range for the period in a given time
function date_range($period, $time=false) {
$time = $time ?: self::gmtime();
if (!($dt = Format::parseDateTime($time)))
return null;
// Force UTC
$dt->setTimezone(new DateTimeZone('UTC'));
// Make dt Immutable.
$dt = DateTimeImmutable::createFromMutable($dt);
switch ($period) {
case 'td':
case 'today':
$start = $end = $dt->modify('today');
break;
case 'yd':
case 'yesterday':
$start = $end = $dt->modify('yesterday');
break;
case 'tw':
case 'this-week':
$N = $dt->format('N');
$start = $dt->modify($N == 1 ? 'today' : 'last monday');
$end = $start->modify('next sunday');
break;
case 'tm':
case 'this-month';
$start = $dt->modify('first day of this month');
$end = $dt->modify('last day of this month');
break;
case 'tq':
case 'this-quater':
$offset = ($dt->format('m') - 1) % 3;
$start = $dt->modify(" - $offset month")
->modify('first day of this month');
$end = $start->modify('+ 3 month')->modify('- 1 day');
break;
case 'ty':
case 'this-year':
$start = $dt->modify('january')->modify('first day of this month');
$end = $dt->modify('december')->modify('last day of this month');
break;
case 'lw':
case 'last-week':
//TODO: address edge cases
$start = $dt->modify('- 1 week')->modify('last monday');
$end = $start->modify('next sunday');
break;
case 'lm':
case 'last-month';
$start = $dt->modify('- 1 month')->modify('first day of this month');
$end = $start->modify('last day of this month');
break;
case 'lq':
case 'last-quater':
$offset = (($dt->format('m') - 1) % 3)+3;
$start = $dt->modify(" - $offset month")
->modify('first day of this month');
$end = $start->modify('+ 3 month')->modify('- 1 day');
break;
case 'ly':
case 'last-year':
$start = $dt->modify('- 1 year')
->modify('january')
->modify('first day of this month');
$end = $start->modify('december')->modify('last day of this month');
break;
default:
return null;
}
if ($start)
$start = $start->setTime(00, 00, 00);
if ($end)
$end = $end->setTime(23, 59, 59);
return (object) array('start' => $start, 'end' => $end);
}
//Current page //Current page
function currentURL() { function currentURL() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment