PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/alaxos/libs/date_tool.php

https://github.com/zpartakov/pmCake
PHP | 665 lines | 426 code | 118 blank | 121 comment | 65 complexity | 973d31faa5081d0a789d43a39cccbc7d MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. <?php
  2. /**
  3. *
  4. * @author Nicolas Rod <nico@alaxos.com>
  5. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  6. * @link http://www.alaxos.ch
  7. */
  8. class DateTool
  9. {
  10. /**
  11. * Format a date according to the current locale
  12. *
  13. * @param $sql_date An SQL formatted date
  14. * @param $locale string The locale to use. If no locale is given, the current locale is used
  15. * @param $with_time boolean Indicates wether the time part must be added if present
  16. * @return string A date formatted according to the current locale
  17. */
  18. public static function sql_to_date($sql_date, $locale = null, $with_time = true)
  19. {
  20. $sql_date = trim($sql_date);
  21. if(strlen($sql_date) == 0 || $sql_date == '0000-00-00')
  22. {
  23. return null;
  24. }
  25. if($with_time && strpos($sql_date, ' ') !== false)
  26. {
  27. $format = DateTool :: get_datetime_format($locale);
  28. }
  29. else
  30. {
  31. $format = DateTool :: get_date_format($locale);
  32. }
  33. return date($format, strtotime($sql_date));
  34. }
  35. /**
  36. * Format a given date to an SQL formatted date.
  37. *
  38. * @param $date string The date to format
  39. * @param $locale string The locale in which the date is formatted. If no locale is given, the current locale is used
  40. * @param $with_time boolean Indicates wether the time part must be added if present
  41. * @return string
  42. */
  43. public static function date_to_sql($date, $locale = null, $with_time = true)
  44. {
  45. $date = trim($date);
  46. if($with_time && strpos($date, ' ') !== false)
  47. {
  48. return DateTool :: datetime_to_sql($date, $locale);
  49. }
  50. else
  51. {
  52. $format = DateTool :: get_date_format($locale);
  53. }
  54. $format = str_replace('Y', '%Y', $format);
  55. $format = str_replace('m', '%m', $format);
  56. $format = str_replace('d', '%d', $format);
  57. $date_array = strptime($date, $format);
  58. if($date_array !== false)
  59. {
  60. $day = sprintf("%02d", $date_array['tm_mday']);
  61. $month = sprintf("%02d", $date_array['tm_mon'] + 1);
  62. $year = DateTool :: get_complete_year(1900 + $date_array['tm_year']);
  63. return $year . '-' . $month . '-' . $day;
  64. }
  65. else
  66. {
  67. return null;
  68. }
  69. }
  70. function format_date_interval($dateStr, $separator = ' - ', $locale = null)
  71. {
  72. $dateStr = trim($dateStr);
  73. $separator_pos = strpos($dateStr, $separator);
  74. if($separator_pos !== false)
  75. {
  76. $first_date = substr($dateStr, 0, $separator_pos);
  77. $second_date = substr($dateStr, $separator_pos + strlen($separator));
  78. return DateTool :: sql_to_date($first_date, $locale) . ' - ' . DateTool :: sql_to_date($second_date, $locale);
  79. }
  80. else
  81. {
  82. return DateTool :: sql_to_date($dateStr, $locale);
  83. }
  84. }
  85. /**
  86. * Get the current locale format to parse/format a date string
  87. * @return string
  88. */
  89. public static function get_date_format($locale = null)
  90. {
  91. if(!isset($locale))
  92. {
  93. $locale = strtolower(DateTool :: get_current_locale());
  94. }
  95. switch($locale)
  96. {
  97. case 'fr_ch':
  98. case 'fr_ch.utf-8':
  99. case 'fr_fr':
  100. case 'fr_fr.utf-8':
  101. return 'd.m.Y';
  102. break;
  103. case 'en_en':
  104. case 'en_us':
  105. case 'en_en.utf-8':
  106. case 'en_us.utf-8':
  107. return 'Y-m-d';
  108. break;
  109. default:
  110. return 'Y-m-d';
  111. }
  112. }
  113. /*********************************************************************************************/
  114. public static function sql_to_datetime($sql_date, $locale = null)
  115. {
  116. $sql_date = trim($sql_date);
  117. if(strlen($sql_date) == 0 || $sql_date == '0000-00-00' || $sql_date == '0000-00-00 00:00:00')
  118. {
  119. return null;
  120. }
  121. $format = DateTool :: get_datetime_format($locale);
  122. return date($format, strtotime($sql_date));
  123. }
  124. public static function datetime_to_sql($date, $locale = null, $force_datetime = false)
  125. {
  126. $date = trim($date);
  127. $format = DateTool :: get_datetime_format($locale);
  128. /*
  129. * Check if the $date should be parsed as a date and not a datetime
  130. */
  131. if(!$force_datetime && stripos($format, ' ') !== false && stripos($date, ' ') === false)
  132. {
  133. return DateTool :: date_to_sql($date, $locale);
  134. }
  135. else
  136. {
  137. if($force_datetime && stripos($date, ' ') === false)
  138. {
  139. $date .= ' 00:00:00';
  140. }
  141. $format = str_replace('Y', '%Y', $format);
  142. $format = str_replace('m', '%m', $format);
  143. $format = str_replace('d', '%d', $format);
  144. $format = str_replace('H', '%H', $format);
  145. $format = str_replace('i', '%M', $format);
  146. $format = str_replace('s', '%S', $format);
  147. $date_array = strptime($date, $format);
  148. if($date_array !== false)
  149. {
  150. $day = sprintf("%02d", $date_array['tm_mday']);
  151. $month = sprintf("%02d", $date_array['tm_mon'] + 1);
  152. $year = 1900 + $date_array['tm_year'];
  153. $hour = sprintf("%02d", $date_array['tm_hour']);
  154. $min = sprintf("%02d", $date_array['tm_min']);
  155. $sec = sprintf("%02d", $date_array['tm_sec']);
  156. return $year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $min . ':' . $sec;
  157. }
  158. else
  159. {
  160. return null;
  161. }
  162. }
  163. }
  164. public static function get_datetime_format($locale = null)
  165. {
  166. if(!isset($locale))
  167. {
  168. $locale = strtolower(DateTool :: get_current_locale());
  169. }
  170. switch($locale)
  171. {
  172. case 'fr_ch':
  173. case 'fr_ch.utf-8':
  174. case 'fr_fr':
  175. case 'fr_fr.utf-8':
  176. return 'd.m.Y H:i:s';
  177. case 'en_en':
  178. case 'en_us':
  179. case 'en_en.utf-8':
  180. case 'en_us.utf-8':
  181. case 'sql':
  182. return 'Y-m-d H:i:s';
  183. default:
  184. return 'Y-m-d H:i:s';
  185. }
  186. }
  187. public static function get_current_datetime($locale = null)
  188. {
  189. return DateTool :: sql_to_datetime(date(DateTool :: get_datetime_format($locale)), $locale);
  190. }
  191. /*********************************************************************************************/
  192. /**
  193. * Format a time according to the current locale
  194. *
  195. * @param $sql_date An SQL formatted date
  196. * @param $locale string The locale to use. If no locale is given, the current locale is used
  197. * @return string A time formatted according to the given locale
  198. */
  199. public static function sql_to_time($sql_date, $locale = null)
  200. {
  201. $sql_date = trim($sql_date);
  202. if(strlen($sql_date) == 0 || $sql_date == '0000-00-00' || $sql_date == '0000-00-00 00:00:00')
  203. {
  204. return null;
  205. }
  206. $format = DateTool :: get_time_format($locale);
  207. return date($format, strtotime($sql_date));
  208. }
  209. function get_time_format($locale = null)
  210. {
  211. if(!isset($locale))
  212. {
  213. $locale = strtolower(DateTool :: get_current_locale());
  214. }
  215. $locale = strtolower($locale);
  216. switch($locale)
  217. {
  218. case 'fr_ch':
  219. case 'fr_ch.utf-8':
  220. case 'fr_fr':
  221. return 'H:i:s';
  222. case 'en_en':
  223. case 'en_us':
  224. case 'en_en.utf-8':
  225. case 'en_us.utf-8':
  226. return 'H:i:s';
  227. default:
  228. return 'H:i:s';
  229. }
  230. }
  231. /**
  232. * Complete timeStr if necessary
  233. *
  234. * 3 -> 03:00:00
  235. * 16:35 -> 16:35:00
  236. * 16:35:34 -> 16:35:34
  237. *
  238. * @param $timeStr
  239. * @return unknown_type
  240. */
  241. public static function get_complete_time($timeStr)
  242. {
  243. $timeStr = trim($timeStr);
  244. $time_array = explode(':', $timeStr);
  245. $timeStr = '';
  246. for($i = 0; $i < 3; $i++)
  247. {
  248. if(array_key_exists($i, $time_array))
  249. {
  250. $time_part = $time_array[$i];
  251. }
  252. else
  253. {
  254. $time_part = '00';
  255. }
  256. $timeStr .= sprintf('%02d', $time_part);
  257. if($i < 2)
  258. {
  259. $timeStr .= ':';
  260. }
  261. }
  262. //debug($timeStr);
  263. // $timeStr = trim($timeStr);
  264. //
  265. // if(substr_count($timeStr, ':') == 0)
  266. // {
  267. // $timeStr .= ':00:00';
  268. // }
  269. // elseif(substr_count($timeStr, ':') == 1)
  270. // {
  271. // $timeStr .= ':00';
  272. // }
  273. return $timeStr;
  274. }
  275. /**
  276. * Complete timeStr if necessary
  277. *
  278. * 3 -> 03:00:00
  279. * 16:35 -> 16:35:00
  280. * 16:35:34 -> 16:35:34
  281. *
  282. * @param $timeStr
  283. * @return unknown_type
  284. */
  285. public static function get_complete_datetime($timeStr)
  286. {
  287. $timeStr = trim($timeStr);
  288. if(substr_count($timeStr, ' ') > 0)
  289. {
  290. $date = substr($timeStr, 0, strpos($timeStr, ' '));
  291. $time = DateTool :: get_complete_time(substr($timeStr, strpos($timeStr, ' ')));
  292. return $date . ' ' . $time;
  293. }
  294. else
  295. {
  296. return $timeStr . ' 00:00:00';
  297. }
  298. }
  299. public static function get_complete_year($year)
  300. {
  301. $year_num = (int)$year;
  302. if($year_num < 100)
  303. {
  304. $current_year = date('y') + 100;
  305. if($current_year - $year_num > 80)
  306. {
  307. $year_num += 2000;
  308. }
  309. else
  310. {
  311. $year_num += 1900;
  312. }
  313. }
  314. return $year_num;
  315. }
  316. /**
  317. * Return a formatted time string from a number of hours
  318. * @param $hour float
  319. * @return string
  320. */
  321. public static function get_time_from_hour($hour)
  322. {
  323. $date = new Datetime();
  324. $date->setTime(floor($hour), ($hour - floor($hour)) * 60, 0);
  325. return $date->format('H:i');
  326. }
  327. public static function get_hour_as_float($time_string)
  328. {
  329. if(stripos($time_string, ' ') !== false)
  330. {
  331. $time_string = substr($time_string, stripos($time_string, ' '));
  332. }
  333. $hour_array = explode(':', $time_string);
  334. $hour = $hour_array[0];
  335. $min = isset($hour_array[1]) ? $hour_array[1] : 0;
  336. $sec = isset($hour_array[2]) ? $hour_array[2] : 0;
  337. return $hour + $min / 60 + $sec / 3600;
  338. }
  339. /**
  340. *
  341. * @param float $start_hour
  342. * @param float $end_hour
  343. * @param float $step_hour
  344. * @return array
  345. */
  346. public static function get_time_array($start_hour, $end_hour, $step_hour, $minimum_hour = null, $maximum_hour = null, $locale = null)
  347. {
  348. if(!is_numeric($start_hour) && !is_numeric($end_hour) && $step_hour > 0)
  349. {
  350. $sql_date1 = DateTool :: datetime_to_sql($start_hour, $locale);
  351. $sql_date2 = DateTool :: datetime_to_sql($end_hour, $locale);
  352. // debug($sql_date1);
  353. // debug($sql_date2);
  354. $timestamp1 = strtotime($sql_date1);
  355. $timestamp2 = strtotime($sql_date2);
  356. $hour_difference = ($timestamp2 - $timestamp1) / 3600;
  357. //debug($hour_difference);
  358. $start_hour = DateTool :: get_hour_as_float($start_hour);
  359. }
  360. elseif(is_numeric($start_hour) && is_numeric($end_hour) && $start_hour < $end_hour && $step_hour > 0)
  361. {
  362. $hour_difference = $end_hour - $start_hour;
  363. //debug($hour_difference);
  364. }
  365. if(isset($hour_difference))
  366. {
  367. //debug($hour_difference);
  368. $times = array();
  369. $current_time = $start_hour;
  370. $end_hour = $start_hour + $hour_difference;
  371. //debug($end_hour);
  372. while($current_time < $end_hour)
  373. {
  374. if(isset($minimum_hour) && isset($maximum_hour))
  375. {
  376. if($minimum_hour <= $current_time && $current_time < $maximum_hour)
  377. {
  378. $times[] = DateTool :: get_time_from_hour($current_time);
  379. }
  380. }
  381. elseif(!isset($minimum_hour) && isset($maximum_hour))
  382. {
  383. if($current_time < $maximum_hour)
  384. {
  385. $times[] = DateTool :: get_time_from_hour($current_time);
  386. }
  387. else
  388. {
  389. /*
  390. * Max time has been overcome
  391. */
  392. break;
  393. }
  394. }
  395. elseif(isset($minimum_hour) && !isset($maximum_hour))
  396. {
  397. if($minimum_hour <= $current_time)
  398. {
  399. $times[] = DateTool :: get_time_from_hour($current_time);
  400. }
  401. }
  402. else
  403. {
  404. $times[] = DateTool :: get_time_from_hour($current_time);
  405. }
  406. $current_time += $step_hour;
  407. }
  408. //debug($times);
  409. return $times;
  410. }
  411. }
  412. /*********************************************************************************************/
  413. public static function compare_dates($date1, $date2, $locale = null)
  414. {
  415. //debug($date1 . ' <---> ' . $date2);
  416. $sql_date1 = DateTool :: datetime_to_sql($date1, $locale);
  417. $sql_date2 = DateTool :: datetime_to_sql($date2, $locale);
  418. //debug($sql_date1 . ' <---> ' . $sql_date2);
  419. $timestamp1 = strtotime($sql_date1);
  420. $timestamp2 = strtotime($sql_date2);
  421. if($timestamp1 == $timestamp2)
  422. {
  423. return '=';
  424. }
  425. elseif($timestamp1 > $timestamp2)
  426. {
  427. return '>';
  428. }
  429. elseif($timestamp1 < $timestamp2)
  430. {
  431. return '<';
  432. }
  433. }
  434. /**
  435. *
  436. * @param string $start_datetime
  437. * @param string $end_datetime
  438. * @param string $datetime_to_check
  439. * @return bool Indicates wether the time to check is between the two given times
  440. */
  441. public static function datetime_is_in_interval($start_datetime, $end_datetime, $datetime_to_check = null, $locale = 'sql')
  442. {
  443. if(!isset($datetime_to_check))
  444. {
  445. $datetime_to_check = DateTool :: get_current_datetime($locale);
  446. }
  447. $start_datetime = DateTool :: get_complete_datetime($start_datetime);
  448. $end_datetime = DateTool :: get_complete_datetime($end_datetime);
  449. $datetime_to_check = DateTool :: get_complete_datetime($datetime_to_check);
  450. $comparison1 = DateTool :: compare_dates($start_datetime, $datetime_to_check, $locale);
  451. $comparison2 = DateTool :: compare_dates($datetime_to_check, $end_datetime, $locale);
  452. if(
  453. ($comparison1 == '<' || $comparison1 == '=')
  454. &&
  455. ($comparison2 == '<')
  456. )
  457. {
  458. return true;
  459. }
  460. else
  461. {
  462. return false;
  463. }
  464. }
  465. /*********************************************************************************************/
  466. /**
  467. * Set the PHP locale and set the CakePHP language
  468. *
  469. * @param $locale mixed string or array of string
  470. * @return string the new current locale
  471. */
  472. public static function set_current_locale($locale)
  473. {
  474. if(isset($locale))
  475. {
  476. if(is_string($locale))
  477. {
  478. $locale = strtolower($locale);
  479. /*
  480. * Depending on the server configuration, the locale that the method 'setlocale()'
  481. * is waiting for may be different.
  482. *
  483. * But as the 'setlocale()' can take an array of strings, we try to pass
  484. * an array instead of a string
  485. */
  486. switch($locale)
  487. {
  488. case 'fr':
  489. case 'fre':
  490. case 'fren':
  491. case 'french':
  492. case 'fr_ch':
  493. case 'fr_fr':
  494. case 'fr_ch.utf-8':
  495. case 'fr_fr.utf-8':
  496. case 'fr-ch':
  497. case 'fr-fr':
  498. case 'fr-ch.utf-8':
  499. case 'fr-fr.utf-8':
  500. $locale = array('fr_CH.UTF-8', 'fr_CH', 'fr_FR.UTF-8', 'fr_FR');
  501. break;
  502. case 'en':
  503. case 'eng':
  504. case 'english':
  505. case 'en_en':
  506. case 'en_us':
  507. case 'en_us.utf-8':
  508. case 'en_en.utf-8':
  509. case 'en-en':
  510. case 'en-us':
  511. case 'en-us.utf-8':
  512. case 'en-en.utf-8':
  513. $locale = array('en_US.UTF-8', 'en_US', 'en_EN.UTF-8', 'en_EN');
  514. break;
  515. default:
  516. $locale = array($locale);
  517. break;
  518. }
  519. }
  520. $new_locale = setlocale(LC_ALL, $locale);
  521. //debug($new_locale);
  522. if(stripos(strtolower($new_locale), 'utf-8') !== false)
  523. {
  524. header('Content-Type: text/html; charset=UTF-8');
  525. }
  526. if(StringTool :: start_with(strtolower($new_locale), 'fr_'))
  527. {
  528. Configure::write('Config.language', "fr");
  529. }
  530. elseif(StringTool :: start_with(strtolower($new_locale), 'en_'))
  531. {
  532. Configure::write('Config.language', "en");
  533. }
  534. return $new_locale;
  535. }
  536. }
  537. /**
  538. *
  539. * @return string The current locale code
  540. */
  541. public static function get_current_locale()
  542. {
  543. return setlocale(LC_ALL, '0');
  544. }
  545. /*********************************************************************************************/
  546. }
  547. ?>