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