]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/include/TimeDateTest.php
Release 6.2.0
[Github/sugarcrm.git] / tests / include / TimeDateTest.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37  
38 require_once 'include/TimeDate.php';
39
40 class TimeDateTest extends Sugar_PHPUnit_Framework_TestCase
41 {
42         /**
43          * @var TimeDate
44          */
45         protected $time_date;
46
47         const DEFAULT_TIME_FORMAT = 'H:i';
48
49         public static function setUpBeforeClass()
50         {
51             unset($GLOBALS['disable_date_format']);
52         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
53         }
54
55         public function setUp()
56         {
57                 $this->time_date = new TimeDate();
58                 $this->_noUserCache();
59         }
60
61         public function tearDown()
62         {
63             SugarDateTime::$use_php_parser = true;
64             SugarDateTime::$use_strptime = true;
65         }
66
67         public static function tearDownAfterClass()
68         {
69             SugarTestUserUtilities::removeAllCreatedAnonymousUsers();
70         unset($GLOBALS['current_user']);
71         }
72
73         public function dateTestSet()
74         {
75             return array(
76                 array("db" => '2005-10-25 07:00:00', "df" => 'd-m-Y', 'tf' => '',               'tz' => 'America/Los_Angeles',          "display" => '25-10-2005',                      "dbdate" => "2005-10-25 00:00:00"),
77                 // add times
78                 array("db" => '2005-10-26 06:42:00', "df" => 'd-m-Y', "tf" => 'h.iA',   'tz' => 'America/Los_Angeles',          "display" => '25-10-2005 11.42PM',      "dbdate" => "2005-10-25 23:42:00"),
79                 // GMT+0 timezone
80                 array("db" => '2005-11-25 00:00:00', "df" => 'd-m-Y', 'tf' => '',               'tz' => 'Europe/London',                        "display" => '25-11-2005',                      "dbdate" => "2005-11-25 00:00:00"),
81                 // GMT+1
82                 array("db" => '2005-11-24 23:00:00', "df" => 'd;m;Y', 'tf' => '',               'tz' => 'Europe/Oslo',                          "display" => '25;11;2005',                      "dbdate" => "2005-11-25 00:00:00"),
83                 // DST in effect
84                 array("db" => '2005-10-24 23:00:00', "df" => 'd-m-Y', 'tf' => '',               'tz' => 'Europe/London',                        "display" => '25-10-2005',                      "dbdate" => "2005-10-25 00:00:00"),
85                 // different format
86                 array("db" => '1997-10-25 07:00:00', "df" => 'Y-m-d', 'tf' => '',               'tz' => 'America/Los_Angeles',          "display" => '1997-10-25',                      "dbdate" => "1997-10-25 00:00:00"),
87                 array("db" => '1997-01-25 00:00:00', "df" => 'm-d-Y', 'tf' => '',               'tz' => 'Europe/London',                        "display" => '01-25-1997',                      "dbdate" => "1997-01-25 00:00:00"),
88                 // with times
89                 array("db" => '2005-10-25 10:42:24', "df" => 'd/m/Y', "tf" => "H:i:s",  'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 03:42:24', "dbdate" => "2005-10-25 03:42:24"),
90                 array("db" => '2005-10-25 02:42:24', "df" => 'd/m/Y', "tf" => "H:i:s",  'tz' => 'Europe/London',                        "display" => '25/10/2005 03:42:24', "dbdate" => "2005-10-25 03:42:24"),
91                 array("db" => '2005-10-25 01:42:24', "df" => 'd/m/Y', "tf" => "H:i:s",  'tz' => 'Asia/Jerusalem',                       "display" => '25/10/2005 03:42:24', "dbdate" => "2005-10-25 03:42:24"),
92                 // FAIL! FIXME: same format leads to no TZ conversion
93                 array("db" => '2005-10-25 10:42:24', "df" => 'Y-m-d', "tf" => "H:i:s",  'tz' => 'America/Los_Angeles',          "display" => '2005-10-25 03:42:24', "dbdate" => "2005-10-25 03:42:24"),
94                 // short times
95                 array("db" => '2005-10-25 10:42:00', "df" => 'd/m/Y', "tf" => "H:i",    'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 03:42',        "dbdate" => "2005-10-25 03:42:00"),
96                 array("db" => '2005-10-25 22:00:00', "df" => 'd/m/Y', "tf" => "ha",             'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 03pm',         "dbdate" => "2005-10-25 15:00:00"),
97                 array("db" => '2005-10-25 10:00:00', "df" => 'd/m/Y', "tf" => "h",              'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 03',           "dbdate" => "2005-10-25 03:00:00"),
98                 array("db" => '2005-10-25 20:00:00', "df" => 'd/m/Y', "tf" => "H",              'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 13',           "dbdate" => "2005-10-25 13:00:00"),
99                 array("db" => '2005-10-25 07:00:00', "df" => 'd/m/Y', "tf" => "ha",             'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 12am',         "dbdate" => "2005-10-25 00:00:00"),
100                 array("db" => '2005-10-25 19:00:00', "df" => 'd/m/Y', "tf" => "ha",             'tz' => 'America/Los_Angeles',          "display" => '25/10/2005 12pm',         "dbdate" => "2005-10-25 12:00:00"),
101                 );
102         }
103
104         public function timetestSet()
105         {
106             return array(
107                 // full time
108                 array("db" => "11:45:00", "tf" => '', "display" => "11:45"),
109                 array("db" => "05:17:28", "tf" => "H.i.s", "display" => "05.17.28"),
110                 // short ones
111                 array("db" => "17:34:00", "tf" => "H:i", "display" => "17:34"),
112                 array("db" => "11:42:00", "tf" => "h.iA", "display" => "11.42AM"),
113                 array("db" => "15:00:00", "tf" => "ha", "display" => "03pm"),
114                 array("db" => "15:00:00", "tf" => "H", "display" => "15"),
115                 // FIXME: is this a valid format? it doesn't allow roundtrip
116                 array("db" => "03:00:00", "tf" => "h", "display" => "03"),
117                 // weirdo
118                 array("db" => "16:42:34", "tf" => "s:i:H", "display" => "34:42:16"),
119                 );
120         }
121
122         protected function _noUserCache()
123         {
124                 $this->time_date->allow_cache = false;
125         }
126
127         protected function _setPrefs($datef, $timef, $tz)
128         {
129                         $GLOBALS['current_user']->setPreference('datef', $datef);
130                         $GLOBALS['current_user']->setPreference('timef', $timef);
131                         $GLOBALS['current_user']->setPreference('timezone', $tz);
132                         // new object to avoid TZ caching
133                         $this->time_date = new TimeDate();
134                         $this->_noUserCache();
135         }
136
137         protected function _dateOnly($datetime)
138         {
139                 // FIXME: assumes dates have no spaces
140                 $dt = explode(' ', $datetime);
141                 return $dt[0];
142         }
143
144         protected function _timeOnly($datetime)
145         {
146                 // FIXME: assumes dates have no spaces
147                 $dt = explode(' ', $datetime);
148                 if(count($dt) > 1) {
149                         return $dt[1];
150                 }
151                 return $datetime;
152         }
153
154         /**
155          * test conversion from local datetime to DB datetime
156          * @dataProvider dateTestSet
157          */
158         public function testToDbFormats($db, $df, $tf, $tz,  $display, $dbdate)
159         {
160                 $tf = empty($tf) ? self::DEFAULT_TIME_FORMAT : $tf;
161                 $this->_setPrefs($df, $tf, $tz);
162                 $this->assertEquals($db,
163         $this->time_date->to_db($display),
164                 "Broken conversion for '$df $tf' with date '$display' and TZ $tz");
165         }
166
167         /**
168          * test conversion from full local datetime to DB date
169          * @dataProvider dateTestSet
170          */
171         public function testToDbDateFormatsWithOffset($db, $df, $tf, $tz,  $display, $dbdate)
172         {
173                 $tf = empty($tf) ? self::DEFAULT_TIME_FORMAT : $tf;
174                 $this->_setPrefs($df, $tf, $tz);
175                 $this->assertEquals(
176                         $this->_dateOnly($db),
177                         $this->time_date->to_db_date($display, true),
178                         "Broken conversion for '{$df} $tf' with date '{$display}' and TZ {$tz}");
179         }
180
181         /**
182          * test conversion from local date to DB date, no TZ handling
183          * @dataProvider dateTestSet
184          */
185         public function testToDbDateFormatsNoOffset($db, $df, $tf, $tz,  $display, $dbdate)
186         {
187                 $tf = empty($tf) ? self::DEFAULT_TIME_FORMAT : $tf;
188             $this->_setPrefs($df, $tf, $tz);
189                 $this->assertEquals(
190                         $this->_dateOnly($dbdate),
191                         $this->time_date->to_db_date($this->_dateOnly($display), false),
192                         "Broken conversion for '{$df} $tf' with date '{$display}' and TZ {$tz}");
193         }
194
195         /**
196          * test conversion from full local datetime to DB time
197          * @dataProvider dateTestSet
198          */
199         public function testToDbTimeFormatsWithTz($db, $df, $tf, $tz,  $display, $dbdate)
200         {
201                 $tf = empty($tf) ? self::DEFAULT_TIME_FORMAT : $tf;
202                 $this->_setPrefs($df, $tf, $tz);
203                 if(strpos($display, ' ') === false) {
204                     $display = $this->time_date->expandDate($display, "$df $tf");
205                 }
206                 $this->assertEquals(
207                         $this->_timeOnly($db),
208                         $this->time_date->to_db_time($display, true),
209                         "Broken conversion for '{$df} $tf' with date '{$display}' and TZ {$tz}");
210         }
211
212         /**
213          * test conversion from local time to DB time, no TZ handling
214          * @dataProvider timeTestSet
215          */
216         public function testToDbTimeFormatsNoTz($db, $tf, $display)
217         {
218                 $tf = empty($tf) ? self::DEFAULT_TIME_FORMAT : $tf;
219                 $this->_setPrefs('Y-m-d', $tf, '');
220                 $this->assertEquals(
221                         $db,
222                         $this->time_date->to_db_time($display, false),
223                         "Broken conversion for '$tf' with date '{$display}'");
224         }
225
226         /**
227          * test conversion from local date+time to DB date+time, no TZ handling
228          * @dataProvider dateTestSet
229          */
230         public function testToDbDateTimeFormats($db, $df, $tf, $tz,  $display, $dbdate)
231         {
232                 $tf = empty($tf) ? self::DEFAULT_TIME_FORMAT : $tf;
233                 $this->_setPrefs($df, $tf, $tz);
234                 $dt = explode(' ', $display);
235                 if(count($dt) > 1) {
236                         list($date, $time) = $dt;
237                 } else {
238                         $date = $dt[0];
239                         $z = new DateTime("@0", new DateTimeZone("GMT"));
240                         $time = $z->format($tf);
241                 }
242                 $this->assertEquals(
243                         explode(' ',$dbdate),
244                         $this->time_date->to_db_date_time($date, $time),
245                         "Broken conversion for '{$df} $tf' with date '{$display}' and TZ {$tz}");
246         }
247
248
249         /**
250          * test conversion from DB date+time to local date+time with TZ handling
251          * @dataProvider dateTestSet
252          */
253         public function testToDisplayDateTimeFormats($db, $df, $tf, $tz,  $display, $dbdate)
254         {
255                 $this->_setPrefs($df, $tf, $tz);
256                 $result = $this->time_date->to_display_date_time($db, true, true, $GLOBALS['current_user']);
257                 if(empty($tf)) {
258                         $result = $this->_dateOnly($result);
259                 }
260                 $this->assertEquals(
261                         $display,
262                         $result,
263                         "Broken conversion for '$df' with date '{$db}' and TZ {$tz}");
264         }
265
266         /**
267          * test conversion from DB date+time to local date+time without TZ handling
268          * @dataProvider dateTestSet
269          */
270         public function testToDisplayFormatsNoTz($db, $df, $tf, $tz,  $display, $dbdate)
271         {
272             $this->_setPrefs($df, $tf, $tz);
273             if(!empty($tf)) {
274                 $df .= " $tf";
275             }
276                 $result = $this->time_date->to_display($dbdate, $this->time_date->get_db_date_time_format(), $df);
277                 if(empty($tf)) {
278                         $result = $this->_dateOnly($result);
279                 }
280                 $this->assertEquals(
281                         $display,
282                         $result,
283                         "Broken conversion for '$df' with date '{$db}' and TZ {$tz}");
284         }
285
286         /**
287          * test conversion from DB time to local time without TZ conversion
288          * @dataProvider timeTestSet
289          */
290         public function testToDisplayTimeFormatsNoTZ($db, $tf, $display)
291         {
292                 if(empty($tf)) return;
293                 $this->_setPrefs('Y-m-d', $tf, '');
294                 $this->assertEquals(
295                         $this->_timeOnly($display),
296                         $this->time_date->to_display_time($db, true, false),
297                         "Broken conversion for '$tf' with date '{$db}'");
298         }
299
300         /**
301          * test conversion from DB time to local time with TZ conversion
302          * @dataProvider dateTestSet
303          */
304         public function testToDisplayTimeFormatsWithTZ($db, $df, $tf, $tz,  $display, $dbdate)
305         {
306                 if(empty($tf)) return;
307                 $this->_setPrefs($df, $tf, $tz);
308                 $result = $this->time_date->to_display_time($db, true, true);
309                 $result = $this->_timeOnly($result);
310                 $this->assertEquals(
311                         $this->_timeOnly($display),
312                         $result,
313                         "Broken conversion for '{$tf}' with date '{$db}' and TZ {$tz}");
314         }
315
316
317         /**
318          * test conversion from DB date to local date without TZ handling
319          * @dataProvider dateTestSet
320          */
321         public function testToDisplayDateFormatsNoTz($db, $df, $tf, $tz,  $display, $dbdate)
322         {
323                 $this->_setPrefs($df, $tf, $tz);
324                 $result = $this->time_date->to_display_date($this->_dateOnly($dbdate), false);
325                 $this->assertEquals(
326                         $this->_dateOnly($display),
327                         $this->_dateOnly($result),
328                         "Broken conversion for '{$df}' with date '{$dbdate}' and TZ {$tz}");
329         }
330
331         /**
332          * test conversion from DB date to local date with TZ handling
333          * @dataProvider dateTestSet
334          */
335         public function testToDisplayDateFormatsWithTz($db, $df, $tf, $tz,  $display, $dbdate)
336         {
337                 $this->_setPrefs($df, $tf, $tz);
338                 $result = $this->time_date->to_display_date($db, true);
339                 $this->assertEquals(
340                         $this->_dateOnly($display),
341                         $this->_dateOnly($result),
342                         "Broken conversion for '{$df}' with date '{$dbdate}' and TZ {$tz}");
343         }
344
345         public function midnightDataSet()
346         {
347             return array(
348                         array("tf" => "H:i", "time" => "00:00"),
349                         array("tf" => "H:i:s", "time" => "00:00:00"),
350                         array("tf" => "h:i", "time" => "12:00"),
351                         array("tf" => "h:i:s", "time" => "12:00:00"),
352                         array("tf" => "h`iA", "time" => "12`00AM"),
353                         array("tf" => "h`i`sa", "time" => "12`00`00am"),
354                 );
355         }
356
357         /**
358          * test midnight formatting
359          * @dataProvider midnightDataSet
360          */
361         public function testGetMidnight($tf, $time)
362         {
363                 if(!is_callable(array($this->time_date, "get_default_midnight"))) {
364                         $this->markTestSkipped("Method is no longer public");
365                 }
366                 $this->_setPrefs('', $tf, "America/Los_Angeles");
367                 $this->assertEquals($time,  $this->time_date->get_default_midnight(true),
368                         "Bad midnight value for $time format $tf");
369         }
370
371         public function testSwapFormatsWithTheSameDateFormat()
372         {
373                 $original_date = '2005-12-25';
374                 $original_format = 'Y-m-d';
375                 $new_format = $original_format;
376                 $expected_new_date = $original_date;
377
378                 $new_date = $this->time_date->swap_formats($original_date,
379                         $original_format, $new_format);
380
381                 $this->assertEquals($expected_new_date, $new_date);
382         }
383
384         public function testSwapFormatsFromMdyFormatToDmyFormat()
385         {
386                 $original_date = '12-25-2005';
387                 $original_format = 'm-d-Y';
388                 $new_format = 'd-m-Y';
389                 $expected_new_date = '25-12-2005';
390
391                 $new_date = $this->time_date->swap_formats($original_date,
392                         $original_format, $new_format);
393
394                 $this->assertEquals($expected_new_date, $new_date,
395                         "Convert from $original_format to $new_format failed.");
396         }
397
398         public function testSwapFormatsWithTheSameDatetimeFormat()
399         {
400                 $original_date = '2005-12-25 12:55:35';
401                 $original_format = 'Y-m-d H:i:s';
402                 $new_format = $original_format;
403                 $expected_new_date = $original_date;
404
405                 $new_date = $this->time_date->swap_formats($original_date,
406                         $original_format, $new_format);
407
408                 $this->assertEquals($expected_new_date, $new_date,
409                         'Same datetime format not returned.');
410         }
411
412         public function testSwapFormatsFromYmdhiFormatToYmdhisFormat()
413         {
414                 $original_date = '2005-12-25 12:55';
415                 $original_format = 'Y-m-d H:i';
416                 $new_format = 'Y-m-d H:i:s';
417                 $expected_new_date = '2005-12-25 12:55:00';
418
419                 $new_date = $this->time_date->swap_formats($original_date,
420                         $original_format, $new_format);
421
422                 $this->assertEquals($expected_new_date, $new_date);
423         }
424
425         public function testSwapFormatsFromYmdhiFormatToYmdhiaFormat()
426         {
427                 $original = '2005-12-25 13:55';
428                 $original_format = 'Y-m-d H:i';
429                 $new_format = 'Y-m-d h:ia';
430                 $expected = '2005-12-25 01:55pm';
431
432                 $new = $this->time_date->swap_formats($original,
433                         $original_format, $new_format);
434
435                 $this->assertEquals($expected, $new);
436         }
437
438         public function testAllDateFormatSwappingCombinations()
439         {
440                 $orig_formats_and_dates = array(
441                         'Y-m-d' => '2006-12-23',
442                         'm-d-Y' => '12-23-2006',
443                         'd-m-Y' => '23-12-2006',
444                         'Y/m/d' => '2006/12/23',
445                         'm/d/Y' => '12/23/2006',
446                         'd/m/Y' => '23/12/2006');
447
448                 $new_formats_and_dates = $orig_formats_and_dates;
449
450                 foreach($orig_formats_and_dates as $orig_format => $orig_date)
451                 {
452                         foreach($new_formats_and_dates as $new_format => $expected_date)
453                         {
454                                 $new_date = $this->time_date->swap_formats($orig_date,
455                                         $orig_format, $new_format);
456
457                                 $this->assertEquals($expected_date, $new_date,
458                                         "Convert from $orig_format to $new_format failed.");
459
460                                 if($expected_date != $new_date)
461                                 {
462                                         return;
463                                 }
464                         }
465                 }
466         }
467
468     /**
469      * @ticket 17528
470      */
471         public function testSwapDatetimeFormatToDbFormat()
472         {
473                 $date = '10-25-2007 12:00am';
474                 $format = $this->time_date->get_date_time_format();
475                 $db_format = $this->time_date->get_db_date_time_format();
476
477                 $this->assertEquals(
478                         $this->time_date->swap_formats(
479                                 $date,
480                                 'm-d-Y h:ia',
481                                 $this->time_date->get_db_date_time_format()
482                         ),
483                         '2007-10-25 00:00:00'
484                 );
485         }
486
487         /**
488      * @ticket 17528
489      */
490         public function testTodbCanHandleDdmmyyyyFormats()
491         {
492                 $old_pattern = $GLOBALS['current_user']->getPreference('datef');
493                 $GLOBALS['current_user']->setPreference('datef','d-m-Y');
494                 $db_date_pattern = '/2007-10-25 [0-9]{2}:[0-9]{2}:[0-9]{2}/';
495                 $this->assertRegExp(
496                         $db_date_pattern,
497                         $this->time_date->to_db('25-10-2007')
498                 );
499
500                 $this->_noUserCache();
501                 $GLOBALS['current_user']->setPreference('datef','m-d-Y');
502                 $this->assertRegExp(
503                         $db_date_pattern,
504                         $this->time_date->to_db('10-25-2007')
505                 );
506                 $GLOBALS['current_user']->setPreference('datef',$old_pattern);
507         }
508
509         /**
510      * @ticket 17528
511      */
512         public function testTodbCanHandleMmddyyyyFormats()
513         {
514                 $old_date = $GLOBALS['current_user']->getPreference('datef');
515
516                 $GLOBALS['current_user']->setPreference('datef','m-d-Y');
517                 $db_date_pattern = '/2007-10-25 [0-9]{2}:[0-9]{2}:[0-9]{2}/';
518                 $this->assertRegExp(
519                         $db_date_pattern,
520                         $this->time_date->to_db('10-25-2007')
521                 );
522
523                 $GLOBALS['current_user']->setPreference('datef',$old_date);
524         }
525
526         /**
527      * @ticket 17528
528      */
529         public function testTodbdateCanHandleDdmmyyyyFormats()
530         {
531                 $old_date = $GLOBALS['current_user']->getPreference('datef');
532
533                 $GLOBALS['current_user']->setPreference('datef','d-m-Y');
534                 $this->assertEquals(
535                         $this->time_date->to_db_date('25-10-2007'),
536                         '2007-10-25'
537                 );
538
539                 $GLOBALS['current_user']->setPreference('datef',$old_date);
540         }
541
542         /**
543      * @ticket 17528
544      */
545         public function testTodbdateCanHandleMmddyyyyFormats()
546         {
547                 $old_date = $GLOBALS['current_user']->getPreference('datef');
548                 $GLOBALS['current_user']->setPreference('datef','m-d-Y');
549                 $this->assertEquals(
550                         '2007-10-25',
551                         $this->time_date->to_db_date('10-25-2007')
552                 );
553
554                 $GLOBALS['current_user']->setPreference('datef',$old_date);
555         }
556
557         public function testConvertMmddyyyyFormatToYyyymmdd()
558         {
559                 $this->assertEquals(
560                         '2007-11-02',
561                         $this->time_date->swap_formats(
562                                 '11-02-2007',
563                                 'm-d-Y',
564                                 'Y-m-d'
565                         )
566                 );
567         }
568
569         public function testGeneratingDefaultMidnight()
570         {
571                 if(!is_callable(array($this->time_date, "get_default_midnight"))) {
572                         $this->markTestSkipped("Method is no longer public");
573                 }
574                 $old_time = $GLOBALS['current_user']->getPreference('timef');
575
576                 $GLOBALS['current_user']->setPreference('timef','H:i:s');
577                 $this->assertEquals(
578                         '00:00:00',
579                         $this->time_date->get_default_midnight(true)
580                 );
581
582                 $GLOBALS['current_user']->setPreference('timef','h:ia');
583                 $this->assertEquals(
584                         '12:00am',
585                         $this->time_date->get_default_midnight(true)
586                 );
587
588                 $GLOBALS['current_user']->setPreference('timef',$old_time);
589         }
590
591         /**
592          * tests for check_matching_format
593          * @dataProvider dateTestSet
594          */
595         public function testCheckMatchingFormats($db, $df, $tf, $tz,  $display, $dbdate)
596         {
597         if(!empty($tf)) {
598             $df = $this->time_date->merge_date_time($df, $tf);
599         }
600                 $this->assertTrue($this->time_date->check_matching_format($display, $df),
601                                 "Broken match for '$df' with date '{$display}'");
602         }
603
604         public function badMatchTestSet()
605         {
606             return  array(
607                         array("format" => "Y-m-d", "date" => ""),
608                         array("format" => "Y-m-d", "date" => "blah-blah-blah"),
609                         array("format" => "Y-m-d", "date" => "1-2"),
610                         array("format" => "Y-m-d", "date" => "2007-10"),
611                         //FIXME: array("format" => "Y-m-d", "date" => "200-10-25"),
612                         array("format" => "Y-m-d", "date" => "2007-101-25"),
613                         array("format" => "Y-m-d", "date" => "2007-Oct-25"),
614                         //FIXME: array("format" => "Y-m-d", "date" => "2007-10-250"),
615                         array("format" => "d-m-Y", "date" => "2007-10-25"),
616                         array("format" => "d-m-Y", "date" => "10/25/2007"),
617                         //FIXME: array("format" => "Y-m-d", "date" => "here: 2007-20-25"),
618                         //FIXME: array("format" => "Y-m-d", "date" => "2007-20-25 here"),
619                 );
620         }
621
622         /**
623          * tests for check_matching_format
624          * @dataProvider badMatchTestSet
625          */
626         public function testCheckbadMatchingFormats($format, $date)
627         {
628                 // Some bad dates not detected by current code, it's too lenient
629                 $this->assertFalse($this->time_date->check_matching_format($date, $format),
630                         "Broken match for '$format' with date '$date'");
631         }
632
633         /**
634          * test fetching user settings
635          */
636         public function testGetUserSettings()
637         {
638                 $this->_setPrefs('d/m/Y', 'h:i:sA', "America/Lima");
639                 $this->assertEquals('dd/mm/yyyy', $this->time_date->get_user_date_format());
640                 //FIXME: $this->assertEquals('11:00:00PM', $this->time_date->get_user_time_format());
641                 $tz = $this->time_date->getUserTimeZone();
642                 $this->assertEquals(-300, $tz["gmtOffset"]);
643 //              $this->assertEquals(60, $tz["dstOffset"]);
644         }
645
646         /**
647          * test getting GMT dates
648          */
649         public function testGetGMT()
650         {
651                 if (is_windows() || !function_exists("strptime")) {
652             $this->markTestSkipped('Skipping on Windows, no strptime');
653         }
654         $gmt = $this->time_date->nowDb();
655                 $dt = strptime($gmt, "%Y-%m-%d %H:%M:%S");
656                 $this->assertEquals($dt['tm_year']+1900, gmdate("Y"));
657                 $this->assertEquals($dt['tm_mon']+1, gmdate("m"));
658                 $this->assertEquals($dt['tm_mday'], gmdate("d"));
659
660                 $gmt = $this->time_date->nowDb();
661                 $dt = strptime($gmt, "%Y-%m-%d");
662                 $this->assertEquals($dt['tm_year']+1900, gmdate("Y"));
663                 $this->assertEquals($dt['tm_mon']+1, gmdate("m"));
664                 $this->assertEquals($dt['tm_mday'], gmdate("d"));
665         }
666
667         /**
668          * test getting DB date formats indifferent ways
669          */
670         public function testGetDB()
671         {
672                 $this->assertEquals(gmdate($this->time_date->merge_date_time($this->time_date->get_db_date_format(),
673                                                                                                                                                 $this->time_date->get_db_time_format())),
674                          $this->time_date->nowDb());
675         }
676
677         public function testGetCalFormats()
678         {
679                 $cal_tests = array(
680                         array("df" => "Y-m-d", "caldf" => "%Y-%m-%d", "tf" => "H:i:s", "caltf" => "%H:%M:%S"),
681                         array("df" => "d/m/Y", "caldf" => "%d/%m/%Y", "tf" => "h:i:sa", "caltf" => "%I:%M:%S%P"),
682                         array("df" => "m/d/Y", "caldf" => "%m/%d/%Y", "tf" => "H:i", "caltf" => "%H:%M"),
683                         array("df" => "Y-m-d", "caldf" => "%Y-%m-%d", "tf" => "h:iA", "caltf" => "%I:%M%p"),
684                 );
685                 foreach($cal_tests as $datetest) {
686                         $this->_setPrefs($datetest["df"], $datetest["tf"], "America/Los_Angeles");
687                         $this->assertEquals(
688                                 $datetest["caldf"],
689                                 $this->time_date->get_cal_date_format(),
690                                 "Bad cal date format for '{$datetest["df"]}'");
691                         $this->assertEquals(
692                                 $datetest["caltf"],
693                                 $this->time_date->get_cal_time_format(),
694                                 "Bad cal time format for '{$datetest["tf"]}'");
695                         $this->assertEquals(
696                                 $this->time_date->merge_date_time($datetest["caldf"], $datetest["caltf"]),
697                                 $this->time_date->get_cal_date_time_format(),
698                                 "Bad cal datetime format for '{$datetest["df"]} {$datetest["tf"]}'");
699                 }
700         }
701
702         public function dayDataSet()
703         {
704             return array(
705                         array("date" => "2010-05-19", "start" => "2010-05-19 07:00:00", "end" => "2010-05-20 06:59:59", 'tz' => 'America/Los_Angeles'),
706                         array("date" => "2010-01-19", "start" => "2010-01-19 08:00:00", "end" => "2010-01-20 07:59:59", 'tz' => 'America/Los_Angeles'),
707                         array("date" => "2010-05-19", "start" => "2010-05-18 23:00:00", "end" => "2010-05-19 22:59:59", 'tz' => 'Europe/London'),
708                         array("date" => "2010-01-19", "start" => "2010-01-19 00:00:00", "end" => "2010-01-19 23:59:59", 'tz' => 'Europe/London'),
709                         array("date" => "2010-05-19", "start" => "2010-05-18 22:00:00", "end" => "2010-05-19 21:59:59", 'tz' => 'Europe/Oslo'),
710                 );
711         }
712
713         /**
714          * test for handleOffsetMax
715          * @dataProvider dayDataSet
716          */
717         public function testDayMinMax($date, $start, $end, $tz)
718         {
719                 $this->_setPrefs('', '', $tz);
720                 $dates = $this->time_date->handleOffsetMax($date, '');
721                 $this->assertEquals($start, $dates["min"],
722                                 "Bad min result for {$date} tz {$tz}");
723                 $this->assertEquals($end, $dates["max"],
724                                 "Bad max result for {$date} tz {$tz}");
725         }
726
727         /**
728          * test for getDayStartEndGMT
729          * @dataProvider dayDataSet
730          */
731         public function testGetDayStartEnd($date, $start, $end, $tz)
732         {
733                 $this->_setPrefs('m/d/Y', '', $tz);
734         $date_arr = explode("-", $date);
735         $date = $date_arr[1].'/'.$date_arr[2].'/'.$date_arr[0];
736         $dates = $this->time_date->getDayStartEndGMT($date);
737                 $this->assertEquals($start, $dates["start"],
738                                 "Bad min result for {$date} tz {$tz}");
739                 $this->assertEquals($end, $dates["end"],
740                                 "Bad max result for {$date} tz {$tz}");
741         }
742
743         public function ampmDataSet()
744         {
745             return array(
746                         array("date" => "05:17:28", "mer" => "am", "tf" => "H:i:s", "display" => "05:17:28"),
747                         array("date" => "05:17:28", "mer" => "am", "tf" => "h:i:sa", "display" => "05:17:28am"),
748                         // short ones
749                         array("date" => "17:34", "mer" => "pm", "tf" => "H:i", "display" => "17:34"),
750                         array("date" => "11:42", "mer" => "PM", "tf" => "h:iA", "display" => "11:42PM"),
751                         array("date" => "11:42", "mer" => "pm", "tf" => "h:iA", "display" => "11:42pm"),
752                         array("date" => "03", "mer" => "AM", "tf" => "ha", "display" => "03AM"),
753                         array("date" => "15", "mer" => "AM", "tf" => "H", "display" => "15"),
754                 );
755         }
756
757         /**
758          * test for merge_time_meridiem
759          * @dataProvider ampmDataSet
760          */
761         public function testMergeAmPm($date, $mer, $tf, $display)
762         {
763                 $amdate = $this->time_date->merge_time_meridiem($date, $tf, $mer);
764                 $this->assertEquals($display, $amdate,
765                                 "Bad min result for {$date} format {$tf}");
766         }
767
768         public function providerSplitDateTime()
769         {
770             return array(
771                 array("2009-10-04 02:00:00","2009-10-04","02:00:00"),
772                 array("10/04/2010 2:00pm","10/04/2010","2:00pm"),
773                 array("10-04-2010 2:00","10-04-2010","2:00"),
774                 );
775         }
776
777         /**
778          * @dataProvider providerSplitDateTime
779          */
780         public function testSplitDateTime(
781             $datetime,
782             $date,
783             $time
784             )
785         {
786             $this->assertEquals($date,$this->time_date->getDatePart($datetime));
787             $this->assertEquals($time,$this->time_date->getTimePart($datetime));
788         }
789
790         public function testNoCache()
791         {
792         $this->_setPrefs("Y-m-d", "H:i:s", "GMT");
793             $now1 = $this->time_date->now();
794             sleep(2);
795             $now2 = $this->time_date->now();
796             $this->assertNotEquals($now1, $now2, "now() should produce different result when not cached");
797         }
798
799         public function testCache()
800         {
801         $this->_setPrefs("Y-m-d", "H:i:s", "GMT");
802             $this->time_date->allow_cache = true;
803             $now1 = $this->time_date->now();
804             sleep(2);
805             $now2 = $this->time_date->now();
806             $this->assertEquals($now1, $now2, "now() should produce same result when cached");
807         }
808
809         public function stringFormats()
810         {
811             return array(
812                 array("H:i", "15:38", "15:38:00"),
813                 array("h:ia", "03:38pm", "15:38:00"),
814                 array("h:iA", "03:38PM", "15:38:00"),
815                 array("h:ia", "03:38am", "03:38:00"),
816                 array("h:iA", "03:38AM", "03:38:00"),
817                 array("H.i", "15.38", "15:38:00"),
818                 array("h.ia", "03.38pm", "15:38:00"),
819                 array("h.iA", "03.38PM", "15:38:00"),
820                 array("h:ia", "03:38 pm", "15:38:00"),
821                 array("h:iA", "03:38 PM", "15:38:00"),
822                 array("h.ia", "03.38am", "03:38:00"),
823                 array("h.iA", "03.38AM", "03:38:00"),
824                 array("h:ia", "03:38 am", "03:38:00"),
825                 array("h:iA", "03:38 AM", "03:38:00"),
826                 );
827         }
828
829         /**
830          * @dataProvider stringFormats
831          * @param string $format
832          * @param string $string
833          * @param string $result
834          */
835         public function testCreateFromString($format, $string, $result)
836         {
837         $this->_setPrefs("Y-m-d", $format, "GMT");
838         $tz = new DateTimeZone("GMT");
839         SugarDateTime::$use_php_parser = true;
840             $date = SugarDateTime::createFromFormat($format, $string, $tz);
841             $this->assertInstanceOf("SugarDateTime", $date, "Parsing $string failed with PHP parser");
842             $this->assertEquals($result, $this->time_date->getTimePart($date->asDb()));
843
844             SugarDateTime::$use_php_parser = false;
845             $date = SugarDateTime::createFromFormat($format, $string, $tz);
846             $this->assertInstanceOf("SugarDateTime", $date, "Parsing $string failed with strptime");
847             $this->assertEquals($result, $this->time_date->getTimePart($date->asDb()));
848
849             SugarDateTime::$use_strptime = false;
850             $date = SugarDateTime::createFromFormat($format, $string, $tz);
851             $this->assertInstanceOf("SugarDateTime", $date, "Parsing $string failed with manual parser");
852             $this->assertEquals($result, $this->time_date->getTimePart($date->asDb()));
853
854             SugarDateTime::$use_php_parser = true;
855             SugarDateTime::$use_strptime = true;
856         }
857
858         public function testGetTimeDate()
859         {
860             global $current_user;
861             $this->_setPrefs("Y-m-d", "H:i", "GMT");
862
863             $f = $this->time_date->get_date_time_format();
864             $this->assertEquals("Y-m-d H:i", $f);
865
866             $f = $this->time_date->get_date_time_format(true);
867             $this->assertEquals("Y-m-d H:i", $f);
868
869             $f = $this->time_date->get_date_time_format(false);
870             $this->assertEquals("Y-m-d H:i", $f);
871
872             $f = $this->time_date->get_date_time_format(null);
873             $this->assertEquals("Y-m-d H:i", $f);
874
875             $f = $this->time_date->get_date_time_format(true, null);
876             $this->assertEquals("Y-m-d H:i", $f);
877
878             $f = $this->time_date->get_date_time_format(false, null);
879             $this->assertEquals("Y-m-d H:i", $f);
880
881             $f = $this->time_date->get_date_time_format(null, null);
882             $this->assertEquals("Y-m-d H:i", $f);
883
884             $f = $this->time_date->get_date_time_format(true, $current_user);
885             $this->assertEquals("Y-m-d H:i", $f);
886
887             $f = $this->time_date->get_date_time_format(false, $current_user);
888             $this->assertEquals("Y-m-d H:i", $f);
889
890             $f = $this->time_date->get_date_time_format(null, $current_user);
891             $this->assertEquals("Y-m-d H:i", $f);
892
893             $f = $this->time_date->get_date_time_format($current_user);
894             $this->assertEquals("Y-m-d H:i", $f);
895
896             $f = $this->time_date->get_date_time_format($current_user);
897             $this->assertEquals("Y-m-d H:i", $f);
898
899             $f = $this->time_date->get_date_time_format($current_user);
900             $this->assertEquals("Y-m-d H:i", $f);
901         }
902 }