1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/agendav_ynh.git synced 2024-09-03 20:36:12 +02:00
agendav_ynh/sources/web/application/libraries/Dates.php
2014-01-07 17:53:08 +01:00

431 lines
12 KiB
PHP

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* Copyright 2011-2012 Jorge López Pérez <jorge@adobo.org>
*
* This file is part of AgenDAV.
*
* AgenDAV is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* AgenDAV is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AgenDAV. If not, see <http://www.gnu.org/licenses/>.
*/
class Dates {
// Possible time formats
static $timeformats = array(
'24' => array(
'strftime' => '%H:%M',
'date' => 'H:i',
'fullcalendar' => 'HH:mm',
),
'12' => array(
'strftime' => '%l:%M', // %P will be simulated, not working
// in all systems
'date' => 'h:i A', // Match timepicker format
'fullcalendar' => 'h(:mm)tt',
));
// Possible date formats (not needed for strftime)
static $dateformats = array(
'ymd' => array(
'date' => 'Y-m-d',
'datepicker' => 'yy-mm-dd',
'strftime' => '%Y-%m-%d',
),
'dmy' => array(
'date' => 'd/m/Y',
'datepicker' => 'dd/mm/yy',
'strftime' => '%d/%m/%Y',
),
'mdy' => array(
'date' => 'm/d/Y',
'datepicker' => 'mm/dd/yy',
'strftime' => '%m/%d/%Y',
),
);
private $CI;
private $cfg_time;
private $cfg_date;
function __construct() {
$this->CI =& get_instance();
// Load time and date formats
$cfg_time = $this->CI->config->item('default_time_format');
if ($cfg_time === FALSE
|| ($cfg_time != '12' && $cfg_time != '24')) {
log_message('ERROR',
'Invalid default_time_format configuration value');
$this->cfg_time = '24';
} else {
$this->cfg_time = $cfg_time;
}
$cfg_date = $this->CI->config->item('default_date_format');
if ($cfg_date === FALSE
|| ($cfg_date != 'ymd' && $cfg_date != 'dmy'
&& $cfg_date != 'mdy')) {
log_message('ERROR',
'Invalid default_date_format configuration value');
$this->cfg_date = 'ymd';
} else {
$this->cfg_date = $cfg_date;
}
}
/**
* Returns a DatTime object with date approximated by factor seconds.
* Defaults to 30 minutes (60*30 = 1800)
*/
function approx_by_factor($time = null, $tz = null, $factor = 1800) {
if (is_null($time)) {
$time = time();
}
if (is_null($tz)) {
$tz =
$this->CI->timezonemanager->getTz(
$this->CI->config->item('default_timezone'));
}
$rounded = (round($time/$factor))*$factor;
return $this->ts2datetime($rounded, $tz);
}
/**
* Creates a DateTime object from an UNIX timestamp using the specified
* Timezone. If no TZ is specified then default one is used
*/
function ts2datetime($ts, $tz = null) {
if (is_null($tz)) {
$tz = $this->CI->timezonemanager->getTz(
$this->CI->config->item('default_timezone'));
}
$obj = new DateTime('@' . $ts);
// When creating by timestamp, DateTime ignores current timezone
$obj->setTimeZone($tz);
return $obj;
}
/**
* Creates a DateTime object from a date formatted by frontend (such as
* m/d/Y H:i).
*
* Returns FALSE on date parsing error
*/
function frontend2datetime($str, $tz = null) {
if (is_null($tz)) {
$tz = $this->CI->timezonemanager->getTz(
$this->CI->config->item('default_timezone'));
}
$format = $this->date_format_string('date') . ' '.
$this->time_format_string('date');
$obj = $this->create_datetime($format, $str, $tz);
return $obj;
}
/**
* Creates a DateTime object from a date formatted by Fullcalendar
* events: yyyymmddHHii).
*
* Returns FALSE on date parsing error
*/
function fullcalendar2datetime($str, $tz = null) {
if (is_null($tz)) {
$tz = $this->CI->timezonemanager->getTz(
$this->CI->config->item('default_timezone'));
}
$format = 'YmdHis';
$obj = $this->create_datetime($format, $str, $tz);
return $obj;
}
/**
* Converts a DateTime to DATE-TIME format
* in UTC time by default
*
* If no object is passed, current time is used
*/
function datetime2idt($dt = null, $tz = null, $format = '') {
if (is_null($tz)) {
$tz = $this->CI->timezonemanager->getTz('UTC');
}
if (is_null($dt)) {
$dt = new DateTime('now', $tz);
} else {
$dt->setTimeZone($tz);
}
if (empty($format)) {
$format = $this->format_for('DATE-TIME', $tz);
}
$str = $dt->format($format);
return $str;
}
/**
* Converts a DATE-TIME/DATE formatted string to DateTime
* in UTC time by default.
*
* Default timezone is used if not specified
*/
function idt2datetime($id_arr, $tz = null) {
if (is_null($tz)) {
$tz = $this->CI->timezonemanager->getTz('UTC');
}
$format = 'YmdHis';
// $tz should be enough
unset($id_arr['tz']);
$str = '';
foreach ($id_arr as $k => $v) {
$str .= $v;
}
// VALUE=DATE
if (!isset($id_arr['hour'])) {
$str .= '000000';
}
$obj = $this->create_datetime($format, $str, $tz);
return $obj;
}
/**
* Returns a suitable date() format string according to specified
* timezone to parse a DATE-TIME/DATE iCalendar string.
*
* Defaults to UTC
*/
function format_for($type = 'DATE-TIME', $tz = null) {
$format = '';
if (is_null($tz)) {
$tz = $this->CI->timezonemanager->getTz('UTC');
}
if ($type == 'DATE') {
$format = 'Ymd';
} else {
$format = 'Ymd\THis';
}
if ($tz->getName() == 'UTC' && $type != 'DATE') {
$format .= '\Z';
}
return $format;
}
/**
* Converts a DateInterval to a DURATION string
*
* Parameter has to be the result of add() or diff() to an existing
* DateTime object
*/
function di2duration($di) {
if ($obj->days === FALSE) {
// We have a problem
return FALSE;
}
$days = $obj->days;
$seconds = $obj->s + $obj->i*60 + $obj->h*3600;
$str = '';
// Simplest case
if ($days%7 == 0 && $seconds == 0) {
$str = ($days/7) . 'W';
} else {
$time_units = array(
'3600' => 'H',
'60' => 'M',
'1' => 'S',
);
$str_time = '';
foreach ($time_units as $k => $v) {
if ($seconds >= $k) {
$str_time .= floor($seconds/$k) . $v;
$seconds %= $k;
}
}
// No days
if ($days == 0) {
$str = 'T' . $str_time;
} else {
$str = $days . 'D' . (empty($str_time) ? '' : 'T' . $str_time);
}
}
return ($obj->invert == '1' ? '-' : '') . 'P' . $str;
}
/**
* Convertes a DURATION string to a DateInterval
* Allows the use of '-' in front of the string
*/
function duration2di($str) {
$minus;
$new_str = preg_replace('/^(-)/', '', $str, -1, $minus);
$interval = new DateInterval($new_str);
if ($minus == 1) {
$interval->invert = 1;
}
return $interval;
}
/**
* Converts a X-CURRENT-DTSTART/X-CURRENT-DTEND string to a DateTime
* object
*/
function x_current2datetime($str, $tz) {
$matches = array();
$res = preg_match('/^(\d+)-(\d+)-(\d+)( (\d+):(\d+):(\d+)( (\S+))?)?$/', $str, $matches);
if ($res === FALSE || $res != 1) {
log_message('ERROR',
'Error processing [' . $str . '] as X-CURRENT-*'
.' string');
return new DateTime();
}
$y = $matches[1];
$m = $matches[2];
$d = $matches[3];
$h = isset($matches[5]) ? $matches[5] : '00';
$i = isset($matches[6]) ? $matches[6] : '00';
$s = isset($matches[7]) ? $matches[7] : '00';
// Timezone is ignored, we already have $tz
//$e = isset($matches[9]) ? $matches[9] : $tz;
$format = 'dmY His';
$new_str = $d.$m.$y.' '.$h.$i.$s;
$dt = $this->create_datetime($format, $new_str, $tz);
if ($dt === FALSE) {
$this->CI->extended_logs->message('ERROR',
'Error processing ' . $new_str . ' (post) as a string'
.' for X-CURRENT-*');
return new DateTime();
}
return $dt;
}
/**
* Returns a time format string for the current user
*
* @param string Type of format (fullcalendar, date, strftime)
* @return string Format string. Default formats on invalid params
*/
function time_format_string($type) {
switch($type) {
case 'fullcalendar':
case 'date':
case 'strftime':
return Dates::$timeformats[$this->cfg_time][$type];
break;
default:
$this->CI->extended_logs->message('ERROR',
'Invalid type for time_format_string() passed'
.' ('.$type.')');
break;
}
}
/**
* Returns a date format string for the current user
*
* @param string Type of format (date, datepicker)
* @return string Format string. Default formats on invalid params
*/
function date_format_string($type) {
switch($type) {
case 'date':
case 'datepicker':
case 'strftime':
return Dates::$dateformats[$this->cfg_date][$type];
break;
default:
$this->CI->extended_logs->message('ERROR',
'Invalid type for date_format_string() passed'
.' ('.$type.')');
break;
}
}
/**
* Formats a timestamp time using strftime
*
* @param int Timestamp
* @param DateTime DateTime object (used to calculate am/pm)
* @return string Formatted time string with strftime
*/
function strftime_time($timestamp, $dt) {
$format = Dates::$timeformats[$this->cfg_time]['strftime'];
$result = strftime($format, $timestamp);
if ($this->cfg_time == '12') {
$result .= $dt->format('a');
}
return $result;
}
/**
* Returns a DateTime object using createFromFormat
*
* @param string Format used to parse the given string
* @param string String that contains date-time
* @param DateTimeZone Timezone
* @return DateTime/boolean FALSE on error
*/
function create_datetime($format, $str, $tz) {
$dt = DateTime::createFromFormat($format, $str, $tz);
// Check for errors
$err = DateTime::getLastErrors();
if (FALSE === $dt || $err['warning_count']>0) {
$dt = FALSE;
}
return $dt;
}
}