Passed
Push — master ( 65bdac...4e88da )
by Alxarafe
32:38
created

DateLib::dol_time_plus_duree()   B

Complexity

Conditions 11
Paths 131

Size

Total Lines 43
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 30
nc 131
nop 3
dl 0
loc 43
rs 7.0583
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2004-2011 Laurent Destailleur  <[email protected]>
3
 * Copyright (C) 2005-2011 Regis Houssin        <[email protected]>
4
 * Copyright (C) 2011-2015 Juanjo Menent        <[email protected]>
5
 * Copyright (C) 2017      Ferran Marcet        <[email protected]>
6
 * Copyright (C) 2018      Charlene Benke       <[email protected]>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
 * or see http://www.gnu.org/
21
 */
22
namespace Alixar\Helpers;
23
24
use Alixar\Helpers\DolUtils;
25
26
class DateLib
27
{
28
29
    /**
30
     *  Return an array with timezone values
31
     *
32
     *  @return     array   Array with timezone values
33
     */
34
    function get_tz_array()
35
    {
36
        $tzarray = array(
37
            -11 => "Pacific/Midway",
38
            -10 => "Pacific/Fakaofo",
39
            -9 => "America/Anchorage",
40
            -8 => "America/Los_Angeles",
41
            -7 => "America/Dawson_Creek",
42
            -6 => "America/Chicago",
43
            -5 => "America/Bogota",
44
            -4 => "America/Anguilla",
45
            -3 => "America/Araguaina",
46
            -2 => "America/Noronha",
47
            -1 => "Atlantic/Azores",
48
            0 => "Africa/Abidjan",
49
            1 => "Europe/Paris",
50
            2 => "Europe/Helsinki",
51
            3 => "Europe/Moscow",
52
            4 => "Asia/Dubai",
53
            5 => "Asia/Karachi",
54
            6 => "Indian/Chagos",
55
            7 => "Asia/Jakarta",
56
            8 => "Asia/Hong_Kong",
57
            9 => "Asia/Tokyo",
58
            10 => "Australia/Sydney",
59
            11 => "Pacific/Noumea",
60
            12 => "Pacific/Auckland",
61
            13 => "Pacific/Enderbury"
62
        );
63
        return $tzarray;
64
    }
65
66
    /**
67
     * Return server timezone string
68
     *
69
     * @return string			PHP server timezone string ('Europe/Paris')
70
     */
71
    function getServerTimeZoneString()
72
    {
73
        return @date_default_timezone_get();
74
    }
75
76
    /**
77
     * Return server timezone int.
78
     *
79
     * @param	string	$refgmtdate		Reference period for timezone (timezone differs on winter and summer. May be 'now', 'winter' or 'summer')
80
     * @return 	int						An offset in hour (+1 for Europe/Paris on winter and +2 for Europe/Paris on summer)
81
     */
82
    function getServerTimeZoneInt($refgmtdate = 'now')
83
    {
84
        global $conf;
85
        if (method_exists('DateTimeZone', 'getOffset')) {
86
            // Method 1 (include daylight)
87
            $gmtnow = dol_now('gmt');
88
            $yearref = dol_print_date($gmtnow, '%Y');
89
            $monthref = dol_print_date($gmtnow, '%m');
90
            $dayref = dol_print_date($gmtnow, '%d');
91
            if ($refgmtdate == 'now')
92
                $newrefgmtdate = $yearref . '-' . $monthref . '-' . $dayref;
93
            elseif ($refgmtdate == 'summer')
94
                $newrefgmtdate = $yearref . '-08-01';
95
            else
96
                $newrefgmtdate = $yearref . '-01-01';
97
            $newrefgmtdate .= 'T00:00:00+00:00';
98
            $localtz = new DateTimeZone(getServerTimeZoneString());
0 ignored issues
show
Bug introduced by
The type Alixar\Helpers\DateTimeZone was not found. Did you mean DateTimeZone? If so, make sure to prefix the type with \.
Loading history...
99
            $localdt = new DateTime($newrefgmtdate, $localtz);
0 ignored issues
show
Bug introduced by
The type Alixar\Helpers\DateTime was not found. Did you mean DateTime? If so, make sure to prefix the type with \.
Loading history...
100
            $tmp = -1 * $localtz->getOffset($localdt);
101
            //print $refgmtdate.'='.$tmp;
102
        }
103
        else {
104
            $tmp = 0;
105
            dol_print_error('', 'PHP version must be 5.3+');
106
        }
107
        $tz = round(($tmp < 0 ? 1 : -1) * abs($tmp / 3600));
108
        return $tz;
109
    }
110
111
    /**
112
     *  Add a delay to a date
113
     *
114
     *  @param      int			$time               Date timestamp (or string with format YYYY-MM-DD)
115
     *  @param      int			$duration_value     Value of delay to add
116
     *  @param      int			$duration_unit      Unit of added delay (d, m, y, w, h)
117
     *  @return     int      			        	New timestamp
118
     */
119
    function dol_time_plus_duree($time, $duration_value, $duration_unit)
120
    {
121
        global $conf;
122
123
        if ($duration_value == 0)
124
            return $time;
125
        if ($duration_unit == 'h')
126
            return $time + (3600 * $duration_value);
127
        if ($duration_unit == 'w')
128
            return $time + (3600 * 24 * 7 * $duration_value);
129
130
        $deltastring = 'P';
131
132
        if ($duration_value > 0) {
133
            $deltastring .= abs($duration_value);
134
            $sub = false;
135
        }
136
        if ($duration_value < 0) {
137
            $deltastring .= abs($duration_value);
138
            $sub = true;
139
        }
140
        if ($duration_unit == 'd') {
141
            $deltastring .= "D";
142
        }
143
        if ($duration_unit == 'm') {
144
            $deltastring .= "M";
145
        }
146
        if ($duration_unit == 'y') {
147
            $deltastring .= "Y";
148
        }
149
150
        $date = new DateTime();
151
        if (!empty($conf->global->MAIN_DATE_IN_MEMORY_ARE_GMT))
152
            $date->setTimezone(new DateTimeZone('UTC'));
153
        $date->setTimestamp($time);
154
        $interval = new DateInterval($deltastring);
0 ignored issues
show
Bug introduced by
The type Alixar\Helpers\DateInterval was not found. Did you mean DateInterval? If so, make sure to prefix the type with \.
Loading history...
155
156
        if ($sub)
157
            $date->sub($interval);
158
        else
159
            $date->add($interval);
160
161
        return $date->getTimestamp();
162
    }
163
164
    /**
165
     * Convert hours and minutes into seconds
166
     *
167
     * @param      int		$iHours     	Hours
168
     * @param      int		$iMinutes   	Minutes
169
     * @param      int		$iSeconds   	Seconds
170
     * @return     int						Time into seconds
171
     * @see convertSecondToTime
172
     */
173
    function convertTime2Seconds($iHours = 0, $iMinutes = 0, $iSeconds = 0)
174
    {
175
        $iResult = ($iHours * 3600) + ($iMinutes * 60) + $iSeconds;
176
        return $iResult;
177
    }
178
179
    /** 	  	Return, in clear text, value of a number of seconds in days, hours and minutes.
180
     *      Can be used to show a duration.
181
     *
182
     *    	@param      int		$iSecond		Number of seconds
183
     *    	@param      string	$format		    Output format ('all': total delay days hour:min like "2 days 12:30",
184
     *                                          - 'allwithouthour': total delay days without hour part like "2 days",
185
     *                                          - 'allhourmin': total delay with format hours:min like "60:30",
186
     *                                          - 'allhour': total delay hours without min/sec like "60:30",
187
     *                                          - 'fullhour': total delay hour decimal like "60.5" for 60:30,
188
     *                                          - 'hour': only hours part "12",
189
     *                                          - 'min': only minutes part "30",
190
     *                                          - 'sec': only seconds part,
191
     *                                          - 'month': only month part,
192
     *                                          - 'year': only year part);
193
     *      @param      int		$lengthOfDay    Length of day (default 86400 seconds for 1 day, 28800 for 8 hour)
194
     *      @param      int		$lengthOfWeek   Length of week (default 7)
195
     *    	@return     string		 		 	Formated text of duration
196
     * 	                                		Example: 0 return 00:00, 3600 return 1:00, 86400 return 1d, 90000 return 1 Day 01:00
197
     *      @see convertTime2Seconds
198
     */
199
    function convertSecondToTime($iSecond, $format = 'all', $lengthOfDay = 86400, $lengthOfWeek = 7)
200
    {
201
        global $langs;
202
203
        if (empty($lengthOfDay))
204
            $lengthOfDay = 86400;         // 1 day = 24 hours
205
        if (empty($lengthOfWeek))
206
            $lengthOfWeek = 7;            // 1 week = 7 days
207
208
        if ($format == 'all' || $format == 'allwithouthour' || $format == 'allhour' || $format == 'allhourmin') {
209
            if ((int) $iSecond === 0)
210
                return '0'; // This is to avoid having 0 return a 12:00 AM for en_US
211
212
            $sTime = '';
213
            $sDay = 0;
214
            $sWeek = 0;
215
216
            if ($iSecond >= $lengthOfDay) {
217
                for ($i = $iSecond; $i >= $lengthOfDay; $i -= $lengthOfDay) {
218
                    $sDay++;
219
                    $iSecond -= $lengthOfDay;
220
                }
221
                $dayTranslate = $langs->trans("Day");
222
                if ($iSecond >= ($lengthOfDay * 2))
223
                    $dayTranslate = $langs->trans("Days");
224
            }
225
226
            if ($lengthOfWeek < 7) {
227
                if ($sDay) {
228
                    if ($sDay >= $lengthOfWeek) {
229
                        $sWeek = (int) (($sDay - $sDay % $lengthOfWeek ) / $lengthOfWeek);
230
                        $sDay = $sDay % $lengthOfWeek;
231
                        $weekTranslate = $langs->trans("DurationWeek");
232
                        if ($sWeek >= 2)
233
                            $weekTranslate = $langs->trans("DurationWeeks");
234
                        $sTime .= $sWeek . ' ' . $weekTranslate . ' ';
235
                    }
236
                }
237
            }
238
            if ($sDay > 0) {
239
                $dayTranslate = $langs->trans("Day");
240
                if ($sDay > 1)
241
                    $dayTranslate = $langs->trans("Days");
242
                $sTime .= $sDay . ' ' . $dayTranslate . ' ';
243
            }
244
245
            if ($format == 'all') {
246
                if ($iSecond || empty($sDay)) {
247
                    $sTime .= dol_print_date($iSecond, 'hourduration', true);
248
                }
249
            }
250
            if ($format == 'allhourmin') {
251
                return sprintf("%02d", ($sWeek * $lengthOfWeek * 24 + $sDay * 24 + (int) floor($iSecond / 3600))) . ':' . sprintf("%02d", ((int) floor(($iSecond % 3600) / 60)));
252
            }
253
            if ($format == 'allhour') {
254
                return sprintf("%02d", ($sWeek * $lengthOfWeek * 24 + $sDay * 24 + (int) floor($iSecond / 3600)));
255
            }
256
        } else if ($format == 'hour') { // only hour part
257
            $sTime = dol_print_date($iSecond, '%H', true);
258
        } else if ($format == 'fullhour') {
259
            if (!empty($iSecond)) {
260
                $iSecond = $iSecond / 3600;
261
            } else {
262
                $iSecond = 0;
263
            }
264
            $sTime = $iSecond;
265
        } else if ($format == 'min') { // only min part
266
            $sTime = dol_print_date($iSecond, '%M', true);
267
        } else if ($format == 'sec') { // only sec part
268
            $sTime = dol_print_date($iSecond, '%S', true);
269
        } else if ($format == 'month') { // only month part
270
            $sTime = dol_print_date($iSecond, '%m', true);
271
        } else if ($format == 'year') { // only year part
272
            $sTime = dol_print_date($iSecond, '%Y', true);
273
        }
274
        return trim($sTime);
275
    }
276
277
    /**
278
     * Generate a SQL string to make a filter into a range (for second of date until last second of date)
279
     *
280
     * @param      string	$datefield		Name of SQL field where apply sql date filter
281
     * @param      int		$day_date		Day date
282
     * @param      int		$month_date		Month date
283
     * @param      int		$year_date		Year date
284
     * @return     string	$sqldate		String with SQL filter
285
     */
286
    function dolSqlDateFilter($datefield, $day_date, $month_date, $year_date)
287
    {
288
        global $db;
289
        $sqldate = "";
290
        if ($month_date > 0) {
291
            if ($year_date > 0 && empty($day_date)) {
292
                $sqldate .= " AND " . $datefield . " BETWEEN '" . $db->idate(dol_get_first_day($year_date, $month_date, false));
293
                $sqldate .= "' AND '" . $db->idate(dol_get_last_day($year_date, $month_date, false)) . "'";
294
            } else if ($year_date > 0 && !empty($day_date)) {
295
                $sqldate .= " AND " . $datefield . " BETWEEN '" . $db->idate(dol_mktime(0, 0, 0, $month_date, $day_date, $year_date));
296
                $sqldate .= "' AND '" . $db->idate(dol_mktime(23, 59, 59, $month_date, $day_date, $year_date)) . "'";
297
            } else
298
                $sqldate .= " AND date_format( " . $datefield . ", '%m') = '" . $db->escape($month_date) . "'";
299
        } else if ($year_date > 0) {
300
            $sqldate .= " AND " . $datefield . " BETWEEN '" . $db->idate(dol_get_first_day($year_date, 1, false));
301
            $sqldate .= "' AND '" . $db->idate(dol_get_last_day($year_date, 12, false)) . "'";
302
        }
303
        return $sqldate;
304
    }
305
306
    /**
307
     * 	Convert a string date into a GM Timestamps date
308
     * 	Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not supported. If parameter gm is 1, we will use no TZ, if not we will use TZ of server, not the one inside string.
309
     *
310
     * 	@param	string	$string		Date in a string
311
     * 				     	        YYYYMMDD
312
     * 	                 			YYYYMMDDHHMMSS
313
     * 								YYYYMMDDTHHMMSSZ
314
     * 								YYYY-MM-DDTHH:MM:SSZ (RFC3339)
315
     * 		                		DD/MM/YY or DD/MM/YYYY (deprecated)
316
     * 		                		DD/MM/YY HH:MM:SS or DD/MM/YYYY HH:MM:SS (deprecated)
317
     *  @param	int		$gm         1 =Input date is GM date,
318
     *                              0 =Input date is local date using PHP server timezone
319
     *  @return	int					Date as a timestamp
320
     * 		                		19700101020000 -> 7200 with gm=1
321
     *
322
     *  @see    dol_print_date, dol_mktime, dol_getdate
323
     */
324
    static function dol_stringtotime($string, $gm = 1)
325
    {
326
        // Convert date with format DD/MM/YYY HH:MM:SS. This part of code should not be used.
327
        if (preg_match('/^([0-9]+)\/([0-9]+)\/([0-9]+)\s?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i', $string, $reg)) {
328
            dol_syslog("dol_stringtotime call to function with deprecated parameter format", LOG_WARNING);
329
            // Date est au format 'DD/MM/YY' ou 'DD/MM/YY HH:MM:SS'
330
            // Date est au format 'DD/MM/YYYY' ou 'DD/MM/YYYY HH:MM:SS'
331
            $sday = $reg[1];
332
            $smonth = $reg[2];
333
            $syear = $reg[3];
334
            $shour = $reg[4];
335
            $smin = $reg[5];
336
            $ssec = $reg[6];
337
            if ($syear < 50)
338
                $syear += 1900;
339
            if ($syear >= 50 && $syear < 100)
340
                $syear += 2000;
341
            $string = sprintf("%04d%02d%02d%02d%02d%02d", $syear, $smonth, $sday, $shour, $smin, $ssec);
342
        }
343
        else if (
344
            preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z$/i', $string, $reg) // Convert date with format YYYY-MM-DDTHH:MM:SSZ (RFC3339)
345
            || preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/i', $string, $reg) // Convert date with format YYYY-MM-DD HH:MM:SS
346
            || preg_match('/^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z$/i', $string, $reg)  // Convert date with format YYYYMMDDTHHMMSSZ
347
        ) {
348
            $syear = $reg[1];
349
            $smonth = $reg[2];
350
            $sday = $reg[3];
351
            $shour = $reg[4];
352
            $smin = $reg[5];
353
            $ssec = $reg[6];
354
            $string = sprintf("%04d%02d%02d%02d%02d%02d", $syear, $smonth, $sday, $shour, $smin, $ssec);
355
        }
356
357
        $string = preg_replace('/([^0-9])/i', '', $string);
358
        $tmp = $string . '000000';
359
        $date = DolUtils::dol_mktime(substr($tmp, 8, 2), substr($tmp, 10, 2), substr($tmp, 12, 2), substr($tmp, 4, 2), substr($tmp, 6, 2), substr($tmp, 0, 4), ($gm ? 1 : 0));
360
        return $date;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $date also could return the type string which is incompatible with the documented return type integer.
Loading history...
361
    }
362
363
    /** Return previous day
364
     *
365
     *  @param      int			$day     	Day
366
     *  @param      int			$month   	Month
367
     *  @param      int			$year    	Year
368
     *  @return     array   				Previous year,month,day
369
     */
370
    function dol_get_prev_day($day, $month, $year)
371
    {
372
        $time = dol_mktime(12, 0, 0, $month, $day, $year, 1, 0);
373
        $time -= 24 * 60 * 60;
374
        $tmparray = dol_getdate($time, true);
375
        return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
376
    }
377
378
    /** Return next day
379
     *
380
     *  @param      int			$day    	Day
381
     *  @param      int			$month  	Month
382
     *  @param      int			$year   	Year
383
     *  @return     array   				Next year,month,day
384
     */
385
    function dol_get_next_day($day, $month, $year)
386
    {
387
        $time = dol_mktime(12, 0, 0, $month, $day, $year, 1, 0);
388
        $time += 24 * 60 * 60;
389
        $tmparray = dol_getdate($time, true);
390
        return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
391
    }
392
393
    /** 	Return previous month
394
     *
395
     * 	@param		int			$month		Month
396
     * 	@param		int			$year		Year
397
     * 	@return		array					Previous year,month
398
     */
399
    function dol_get_prev_month($month, $year)
400
    {
401
        if ($month == 1) {
402
            $prev_month = 12;
403
            $prev_year = $year - 1;
404
        } else {
405
            $prev_month = $month - 1;
406
            $prev_year = $year;
407
        }
408
        return array('year' => $prev_year, 'month' => $prev_month);
409
    }
410
411
    /** 	Return next month
412
     *
413
     * 	@param		int			$month		Month
414
     * 	@param		int			$year		Year
415
     * 	@return		array					Next year,month
416
     */
417
    function dol_get_next_month($month, $year)
418
    {
419
        if ($month == 12) {
420
            $next_month = 1;
421
            $next_year = $year + 1;
422
        } else {
423
            $next_month = $month + 1;
424
            $next_year = $year;
425
        }
426
        return array('year' => $next_year, 'month' => $next_month);
427
    }
428
429
    /** 	Return previous week
430
     *
431
     *  @param      int			$day     	Day
432
     *  @param      int			$week    	Week
433
     *  @param      int			$month   	Month
434
     * 	@param		int			$year		Year
435
     * 	@return		array					Previous year,month,day
436
     */
437
    function dol_get_prev_week($day, $week, $month, $year)
438
    {
439
        $tmparray = dol_get_first_day_week($day, $month, $year);
440
441
        $time = dol_mktime(12, 0, 0, $month, $tmparray['first_day'], $year, 1, 0);
442
        $time -= 24 * 60 * 60 * 7;
443
        $tmparray = dol_getdate($time, true);
444
        return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
445
    }
446
447
    /** 	Return next week
448
     *
449
     *  @param      int			$day     	Day
450
     *  @param      int			$week    	Week
451
     *  @param      int			$month   	Month
452
     * 	@param		int			$year		Year
453
     * 	@return		array					Next year,month,day
454
     */
455
    function dol_get_next_week($day, $week, $month, $year)
456
    {
457
        $tmparray = dol_get_first_day_week($day, $month, $year);
458
459
        $time = dol_mktime(12, 0, 0, $tmparray['first_month'], $tmparray['first_day'], $tmparray['first_year'], 1, 0);
460
        $time += 24 * 60 * 60 * 7;
461
        $tmparray = dol_getdate($time, true);
462
463
        return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
464
    }
465
466
    /** 	Return GMT time for first day of a month or year
467
     *
468
     * 	@param		int			$year		Year
469
     * 	@param		int			$month		Month
470
     * 	@param		mixed		$gm			False or 0 or 'server' = Return date to compare with server TZ, True or 1 to compare with GM date.
471
     *                          			Exemple: dol_get_first_day(1970,1,false) will return -3600 with TZ+1, after a dol_print_date will return 1970-01-01 00:00:00
472
     *                          			Exemple: dol_get_first_day(1970,1,true) will return 0 whatever is TZ, after a dol_print_date will return 1970-01-01 00:00:00
473
     *  @return		int						Date for first day, '' if error
474
     */
475
    function dol_get_first_day($year, $month = 1, $gm = false)
476
    {
477
        if ($year > 9999)
478
            return '';
479
        return dol_mktime(0, 0, 0, $month, 1, $year, $gm);
0 ignored issues
show
Bug Best Practice introduced by
The expression return dol_mktime(0, 0, 0, $month, 1, $year, $gm) also could return the type string which is incompatible with the documented return type integer.
Loading history...
480
    }
481
482
    /** 	Return GMT time for last day of a month or year
483
     *
484
     * 	@param		int			$year		Year
485
     * 	@param		int			$month		Month
486
     * 	@param		boolean		$gm			False or 0 or 'server' = Return date to compare with server TZ, True or 1 to compare with GM date.
487
     * 	@return		int						Date for first day, '' if error
488
     */
489
    function dol_get_last_day($year, $month = 12, $gm = false)
490
    {
491
        if ($year > 9999)
492
            return '';
493
        if ($month == 12) {
494
            $month = 1;
495
            $year += 1;
496
        } else {
497
            $month += 1;
498
        }
499
500
        // On se deplace au debut du mois suivant, et on retire un jour
501
        $datelim = dol_mktime(23, 59, 59, $month, 1, $year, $gm);
502
        $datelim -= (3600 * 24);
503
504
        return $datelim;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $datelim also could return the type string which is incompatible with the documented return type integer.
Loading history...
505
    }
506
507
    /** 	Return first day of week for a date. First day of week may be monday if option MAIN_START_WEEK is 1.
508
     *
509
     * 	@param		int		$day		Day
510
     * 	@param		int		$month		Month
511
     *  @param		int		$year		Year
512
     * 	@param		int		$gm			False or 0 or 'server' = Return date to compare with server TZ, True or 1 to compare with GM date.
513
     * 	@return		array				year,month,week,first_day,first_month,first_year,prev_day,prev_month,prev_year
514
     */
515
    function dol_get_first_day_week($day, $month, $year, $gm = false)
516
    {
517
        global $conf;
518
519
        //$day=2; $month=2; $year=2015;
520
        $date = dol_mktime(0, 0, 0, $month, $day, $year, $gm);
521
522
        //Checking conf of start week
523
        $start_week = (isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1);
524
525
        $tmparray = dol_getdate($date, true); // detail of current day
526
        //Calculate days = offset from current day
527
        $days = $start_week - $tmparray['wday'];
528
        if ($days >= 1)
529
            $days = 7 - $days;
530
        $days = abs($days);
531
        $seconds = $days * 24 * 60 * 60;
532
        //print 'start_week='.$start_week.' tmparray[wday]='.$tmparray['wday'].' day offset='.$days.' seconds offset='.$seconds.'<br>';
533
        //Get first day of week
534
        $tmpdaytms = date($tmparray[0]) - $seconds; // $tmparray[0] is day of parameters
535
        $tmpday = date("d", $tmpdaytms);
536
537
        //Check first day of week is in same month than current day or not
538
        if ($tmpday > $day) {
539
            $prev_month = $month - 1;
540
            $prev_year = $year;
541
542
            if ($prev_month == 0) {
543
                $prev_month = 12;
544
                $prev_year = $year - 1;
545
            }
546
        } else {
547
            $prev_month = $month;
548
            $prev_year = $year;
549
        }
550
        $tmpmonth = $prev_month;
551
        $tmpyear = $prev_year;
552
553
        //Get first day of next week
554
        $tmptime = dol_mktime(12, 0, 0, $month, $tmpday, $year, 1, 0);
555
        $tmptime -= 24 * 60 * 60 * 7;
556
        $tmparray = dol_getdate($tmptime, true);
557
        $prev_day = $tmparray['mday'];
558
559
        //Check prev day of week is in same month than first day or not
560
        if ($prev_day > $tmpday) {
561
            $prev_month = $month - 1;
562
            $prev_year = $year;
563
564
            if ($prev_month == 0) {
565
                $prev_month = 12;
566
                $prev_year = $year - 1;
567
            }
568
        }
569
570
        $week = date("W", dol_mktime(0, 0, 0, $tmpmonth, $tmpday, $tmpyear, $gm));
571
572
        return array('year' => $year, 'month' => $month, 'week' => $week, 'first_day' => $tmpday, 'first_month' => $tmpmonth, 'first_year' => $tmpyear, 'prev_year' => $prev_year, 'prev_month' => $prev_month, 'prev_day' => $prev_day);
573
    }
574
575
    /**
576
     * 	Fonction retournant le nombre de jour feries, samedis et dimanches entre 2 dates entrees en timestamp. Dates must be UTC with hour, day, min to 0
577
     * 	Called by function num_open_day
578
     *
579
     * 	@param	    int			$timestampStart     Timestamp de debut
580
     * 	@param	    int			$timestampEnd       Timestamp de fin
581
     *  @param      string		$countrycode        Country code
582
     * 	@param      int			$lastday            Last day is included, 0: no, 1:yes
583
     * 	@return   	int								Nombre de jours feries
584
     *  @see num_between_day, num_open_day
585
     */
586
    function num_public_holiday($timestampStart, $timestampEnd, $countrycode = 'FR', $lastday = 0)
587
    {
588
        global $conf;
589
590
        $nbFerie = 0;
591
592
        // Check to ensure we use correct parameters
593
        if ((($timestampEnd - $timestampStart) % 86400) != 0)
594
            return 'ErrorDates must use same hours and must be GMT dates';
595
596
        $i = 0;
597
        while (( ($lastday == 0 && $timestampStart < $timestampEnd) || ($lastday && $timestampStart <= $timestampEnd) ) && ($i < 50000)) {  // Loop end when equals (Test on i is a security loop to avoid infinite loop)
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($lastday == 0 && $times...stampEnd) && $i < 50000, Probably Intended Meaning: $lastday == 0 && $timest...stampEnd && $i < 50000)
Loading history...
598
            $ferie = false;
599
            $countryfound = 0;
600
            $includesaturdayandsunday = 1;
601
602
            $jour = date("d", $timestampStart);
603
            $mois = date("m", $timestampStart);
604
            $annee = date("Y", $timestampStart);
605
606
607
            // Check into var $conf->global->HOLIDAY_MORE_DAYS   MM-DD,YYYY-MM-DD, ...
608
            if (!empty($conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS)) {
609
                $arrayofdaystring = explode(',', $conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS);
610
                foreach ($arrayofdaystring as $daystring) {
611
                    $tmp = explode('-', $daystring);
612
                    if ($tmp[2]) {
613
                        if ($tmp[0] == $annee && $tmp[1] == $mois && $tmp[2] == $jour)
614
                            $ferie = true;
615
                    }
616
                    else {
617
                        if ($tmp[0] == $mois && $tmp[1] == $jour)
618
                            $ferie = true;
619
                    }
620
                }
621
            }
622
623
            if ($countrycode == 'FR') {
624
                $countryfound = 1;
625
626
                // Definition of fixed working days
627
                if ($jour == 1 && $mois == 1)
628
                    $ferie = true; // 1er january
629
                if ($jour == 1 && $mois == 5)
630
                    $ferie = true; // 1er may
631
                if ($jour == 8 && $mois == 5)
632
                    $ferie = true; // 5 may
633
                if ($jour == 14 && $mois == 7)
634
                    $ferie = true; // 14 july
635
                if ($jour == 15 && $mois == 8)
636
                    $ferie = true; // 15 august
637
                if ($jour == 1 && $mois == 11)
638
                    $ferie = true; // 1 november
639
                if ($jour == 11 && $mois == 11)
640
                    $ferie = true; // 11 november
641
                if ($jour == 25 && $mois == 12)
642
                    $ferie = true; // 25 december
643
644
645
                    
646
// Calculation for easter date
647
                $date_paques = easter_date($annee);
648
                $jour_paques = date("d", $date_paques);
649
                $mois_paques = date("m", $date_paques);
650
                if ($jour_paques == $jour && $mois_paques == $mois)
651
                    $ferie = true;
652
                // Pâques
653
                // Calculation for the monday of easter date
654
                $date_lundi_paques = mktime(
655
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 1, date("Y", $date_paques)
656
                );
657
                $jour_lundi_ascension = date("d", $date_lundi_paques);
658
                $mois_lundi_ascension = date("m", $date_lundi_paques);
659
                if ($jour_lundi_ascension == $jour && $mois_lundi_ascension == $mois)
660
                    $ferie = true;
661
                // Lundi de Pâques
662
                // Calcul du jour de l'ascension (38 days after easter day)
663
                $date_ascension = mktime(
664
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 39, date("Y", $date_paques)
665
                );
666
                $jour_ascension = date("d", $date_ascension);
667
                $mois_ascension = date("m", $date_ascension);
668
                if ($jour_ascension == $jour && $mois_ascension == $mois)
669
                    $ferie = true;
670
                // Ascension
671
                // Calculation of "Pentecote" (11 days after easter day)
672
                $date_pentecote = mktime(
673
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 49, date("Y", $date_paques)
674
                );
675
                $jour_pentecote = date("d", $date_pentecote);
676
                $mois_pentecote = date("m", $date_pentecote);
677
                if ($jour_pentecote == $jour && $mois_pentecote == $mois)
678
                    $ferie = true;
679
                // "Pentecote"
680
            }
681
682
            // Pentecoste and Ascensione in Italy go to the sunday after: isn't holiday.
683
            // Pentecoste is 50 days after Easter, Ascensione 40
684
            if ($countrycode == 'IT') {
685
                $countryfound = 1;
686
687
                // Definition des dates feriees fixes
688
                if ($jour == 1 && $mois == 1)
689
                    $ferie = true; // Capodanno
690
                if ($jour == 6 && $mois == 1)
691
                    $ferie = true; // Epifania
692
                if ($jour == 25 && $mois == 4)
693
                    $ferie = true; // Anniversario Liberazione
694
                if ($jour == 1 && $mois == 5)
695
                    $ferie = true; // Festa del Lavoro
696
                if ($jour == 2 && $mois == 6)
697
                    $ferie = true; // Festa della Repubblica
698
                if ($jour == 15 && $mois == 8)
699
                    $ferie = true; // Ferragosto
700
                if ($jour == 1 && $mois == 11)
701
                    $ferie = true; // Tutti i Santi
702
                if ($jour == 8 && $mois == 12)
703
                    $ferie = true; // Immacolata Concezione
704
                if ($jour == 25 && $mois == 12)
705
                    $ferie = true; // 25 decembre
706
                if ($jour == 26 && $mois == 12)
707
                    $ferie = true; // Santo Stefano
708
709
710
                    
711
// Calcul du jour de paques
712
                $date_paques = easter_date($annee);
713
                $jour_paques = date("d", $date_paques);
714
                $mois_paques = date("m", $date_paques);
715
                if ($jour_paques == $jour && $mois_paques == $mois)
716
                    $ferie = true;
717
                // Paques
718
            }
719
720
            if ($countrycode == 'IN') {
721
                $countryfound = 1;
722
723
                if ($jour == 1 && $mois == 1)
724
                    $ferie = true; // New Year's Day
725
                if ($jour == 26 && $mois == 1)
726
                    $ferie = true; // Republic Day
727
                if ($jour == 1 && $mois == 5)
728
                    $ferie = true; // May Day
729
                if ($jour == 15 && $mois == 8)
730
                    $ferie = true; // Independence Day
731
                if ($jour == 2 && $mois == 10)
732
                    $ferie = true; // Gandhi Jayanti
733
                if ($jour == 25 && $mois == 12)
734
                    $ferie = true; // Christmas
735
            }
736
737
            if ($countrycode == 'ES') {
738
                $countryfound = 1;
739
740
                // Definition des dates feriees fixes
741
                if ($jour == 1 && $mois == 1)
742
                    $ferie = true; // Año nuevo
743
                if ($jour == 6 && $mois == 1)
744
                    $ferie = true; // Día Reyes
745
                if ($jour == 1 && $mois == 5)
746
                    $ferie = true; // 1 Mayo
747
                if ($jour == 15 && $mois == 8)
748
                    $ferie = true; // 15 Agosto
749
                if ($jour == 12 && $mois == 10)
750
                    $ferie = true; // Día Hispanidad
751
                if ($jour == 1 && $mois == 11)
752
                    $ferie = true; // 1 noviembre
753
                if ($jour == 6 && $mois == 12)
754
                    $ferie = true; // Constitución
755
                if ($jour == 8 && $mois == 12)
756
                    $ferie = true; // Inmaculada
757
                if ($jour == 25 && $mois == 12)
758
                    $ferie = true; // 25 diciembre
759
760
761
                    
762
// Calcul día de Pascua
763
                $date_paques = easter_date($annee);
764
                $jour_paques = date("d", $date_paques);
765
                $mois_paques = date("m", $date_paques);
766
                if ($jour_paques == $jour && $mois_paques == $mois)
767
                    $ferie = true;
768
                // Paques
769
                // Viernes Santo
770
                $date_viernes = mktime(
771
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) - 2, date("Y", $date_paques)
772
                );
773
                $jour_viernes = date("d", $date_viernes);
774
                $mois_viernes = date("m", $date_viernes);
775
                if ($jour_viernes == $jour && $mois_viernes == $mois)
776
                    $ferie = true;
777
                //Viernes Santo
778
            }
779
780
            if ($countrycode == 'AT') {
781
                $countryfound = 1;
782
783
                // Definition des dates feriees fixes
784
                if ($jour == 1 && $mois == 1)
785
                    $ferie = true; // Neujahr
786
                if ($jour == 6 && $mois == 1)
787
                    $ferie = true; // Hl. 3 Koenige
788
                if ($jour == 1 && $mois == 5)
789
                    $ferie = true; // 1. Mai
790
                if ($jour == 15 && $mois == 8)
791
                    $ferie = true; // Mariae Himmelfahrt
792
                if ($jour == 26 && $mois == 10)
793
                    $ferie = true; // 26. Oktober
794
                if ($jour == 1 && $mois == 11)
795
                    $ferie = true; // Allerheiligen
796
                if ($jour == 8 && $mois == 12)
797
                    $ferie = true; // Mariae Empfaengnis
798
                if ($jour == 24 && $mois == 12)
799
                    $ferie = true; // Heilig abend
800
                if ($jour == 25 && $mois == 12)
801
                    $ferie = true; // Christtag
802
                if ($jour == 26 && $mois == 12)
803
                    $ferie = true; // Stefanietag
804
                if ($jour == 31 && $mois == 12)
805
                    $ferie = true; // Silvester
806
807
808
                    
809
// Easter calculation
810
                $date_paques = easter_date($annee);
811
                $jour_paques = date("d", $date_paques);
812
                $mois_paques = date("m", $date_paques);
813
                if ($jour_paques == $jour && $mois_paques == $mois)
814
                    $ferie = true;
815
                // Easter sunday
816
                // Monday after easter
817
                $date_eastermonday = mktime(
818
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 1, date("Y", $date_paques)
819
                );
820
                $jour_eastermonday = date("d", $date_eastermonday);
821
                $mois_eastermonday = date("m", $date_eastermonday);
822
                if ($jour_eastermonday == $jour && $mois_eastermonday == $mois)
823
                    $ferie = true;
824
                // Easter monday
825
                // Christi Himmelfahrt (39 days after easter sunday)
826
                $date_ch = mktime(
827
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 39, date("Y", $date_paques)
828
                );
829
                $jour_ch = date("d", $date_ch);
830
                $mois_ch = date("m", $date_ch);
831
                if ($jour_ch == $jour && $mois_ch == $mois)
832
                    $ferie = true;
833
                // Christi Himmelfahrt
834
                // Pfingsten (50 days after easter sunday)
835
                $date_pentecote = mktime(
836
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 50, date("Y", $date_paques)
837
                );
838
                $jour_pentecote = date("d", $date_pentecote);
839
                $mois_pentecote = date("m", $date_pentecote);
840
                if ($jour_pentecote == $jour && $mois_pentecote == $mois)
841
                    $ferie = true;
842
                // Pfingsten
843
                // Fronleichnam (60 days after easter sunday)
844
                $date_fronleichnam = mktime(
845
                    date("H", $date_paques), date("i", $date_paques), date("s", $date_paques), date("m", $date_paques), date("d", $date_paques) + 60, date("Y", $date_paques)
846
                );
847
                $jour_fronleichnam = date("d", $date_fronleichnam);
848
                $mois_fronleichnam = date("m", $date_fronleichnam);
849
                if ($jour_fronleichnam == $jour && $mois_fronleichnam == $mois)
850
                    $ferie = true;
851
                // Fronleichnam
852
            }
853
854
            // If we have to include saturday and sunday
855
            if ($includesaturdayandsunday) {
856
                $jour_julien = unixtojd($timestampStart);
857
                $jour_semaine = jddayofweek($jour_julien, 0);
858
                if ($jour_semaine == 0 || $jour_semaine == 6)
859
                    $ferie = true;
860
                //Saturday (6) and Sunday (0)
861
            }
862
863
            // On incremente compteur
864
            if ($ferie)
865
                $nbFerie++;
866
867
            // Increase number of days (on go up into loop)
868
            $timestampStart = dol_time_plus_duree($timestampStart, 1, 'd');
869
            //var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart);
870
871
            $i++;
872
        }
873
874
        return $nbFerie;
875
    }
876
877
    /**
878
     * 	Function to return number of days between two dates (date must be UTC date !)
879
     *  Example: 2012-01-01 2012-01-02 => 1 if lastday=0, 2 if lastday=1
880
     *
881
     * 	@param	   int			$timestampStart     Timestamp start UTC
882
     * 	@param	   int			$timestampEnd       Timestamp end UTC
883
     * 	@param     int			$lastday            Last day is included, 0: no, 1:yes
884
     * 	@return    int								Number of days
885
     *  @see also num_public_holiday, num_open_day
886
     */
887
    function num_between_day($timestampStart, $timestampEnd, $lastday = 0)
888
    {
889
        if ($timestampStart < $timestampEnd) {
890
            if ($lastday == 1) {
891
                $bit = 0;
892
            } else {
893
                $bit = 1;
894
            }
895
            $nbjours = (int) floor(($timestampEnd - $timestampStart) / (60 * 60 * 24)) + 1 - $bit;
896
        }
897
        //print ($timestampEnd - $timestampStart) - $lastday;
898
        return $nbjours;
899
    }
900
901
    /**
902
     * 	Function to return number of working days (and text of units) between two dates (working days)
903
     *
904
     * 	@param	   	int			$timestampStart     Timestamp for start date (date must be UTC to avoid calculation errors)
905
     * 	@param	   	int			$timestampEnd       Timestamp for end date (date must be UTC to avoid calculation errors)
906
     * 	@param     	int			$inhour             0: return number of days, 1: return number of hours
907
     * 	@param		int			$lastday            We include last day, 0: no, 1:yes
908
     *  @param		int			$halfday			Tag to define half day when holiday start and end
909
     *  @param      string		$country_code       Country code (company country code if not defined)
910
     * 	@return    	int								Number of days or hours
911
     *  @see also num_between_day, num_public_holiday
912
     */
913
    function num_open_day($timestampStart, $timestampEnd, $inhour = 0, $lastday = 0, $halfday = 0, $country_code = '')
914
    {
915
        global $langs, $mysoc;
916
917
        if (empty($country_code))
918
            $country_code = $mysoc->country_code;
919
920
        dol_syslog('num_open_day timestampStart=' . $timestampStart . ' timestampEnd=' . $timestampEnd . ' bit=' . $lastday . ' country_code=' . $country_code);
921
922
        // Check parameters
923
        if (!is_int($timestampStart) && !is_float($timestampStart))
924
            return 'ErrorBadParameter_num_open_day';
925
        if (!is_int($timestampEnd) && !is_float($timestampEnd))
926
            return 'ErrorBadParameter_num_open_day';
927
928
        //print 'num_open_day timestampStart='.$timestampStart.' timestampEnd='.$timestampEnd.' bit='.$lastday;
929
        if ($timestampStart < $timestampEnd) {
930
            $numdays = num_between_day($timestampStart, $timestampEnd, $lastday);
931
            $numholidays = num_public_holiday($timestampStart, $timestampEnd, $country_code, $lastday);
932
            $nbOpenDay = $numdays - $numholidays;
933
            $nbOpenDay .= " " . $langs->trans("Days");
934
            if ($inhour == 1 && $nbOpenDay <= 3)
935
                $nbOpenDay = $nbOpenDay * 24 . $langs->trans("HourShort");
936
            return $nbOpenDay - (($inhour == 1 ? 12 : 0.5) * abs($halfday));
937
        }
938
        elseif ($timestampStart == $timestampEnd) {
939
            $nbOpenDay = $lastday;
940
            if ($inhour == 1)
941
                $nbOpenDay = $nbOpenDay * 24 . $langs->trans("HourShort");
942
            return $nbOpenDay - (($inhour == 1 ? 12 : 0.5) * abs($halfday));
943
        }
944
        else {
945
            return $langs->trans("Error");
946
        }
947
    }
948
949
    /**
950
     * 	Return array of translated months or selected month.
951
     *  This replace old function monthArrayOrSelected.
952
     *
953
     * 	@param	Translate	$outputlangs	Object langs
0 ignored issues
show
Bug introduced by
The type Alixar\Helpers\Translate was not found. Did you mean Translate? If so, make sure to prefix the type with \.
Loading history...
954
     *  @param	int			$short			0=Return long label, 1=Return short label
955
     * 	@return array						Month string or array if selected < 0
956
     */
957
    function monthArray($outputlangs, $short = 0)
958
    {
959
        $montharray = array(
960
            1 => $outputlangs->trans("Month01"),
961
            2 => $outputlangs->trans("Month02"),
962
            3 => $outputlangs->trans("Month03"),
963
            4 => $outputlangs->trans("Month04"),
964
            5 => $outputlangs->trans("Month05"),
965
            6 => $outputlangs->trans("Month06"),
966
            7 => $outputlangs->trans("Month07"),
967
            8 => $outputlangs->trans("Month08"),
968
            9 => $outputlangs->trans("Month09"),
969
            10 => $outputlangs->trans("Month10"),
970
            11 => $outputlangs->trans("Month11"),
971
            12 => $outputlangs->trans("Month12")
972
        );
973
974
        if (!empty($short)) {
975
            $montharray = array(
976
                1 => $outputlangs->trans("MonthShort01"),
977
                2 => $outputlangs->trans("MonthShort02"),
978
                3 => $outputlangs->trans("MonthShort03"),
979
                4 => $outputlangs->trans("MonthShort04"),
980
                5 => $outputlangs->trans("MonthShort05"),
981
                6 => $outputlangs->trans("MonthShort06"),
982
                7 => $outputlangs->trans("MonthShort07"),
983
                8 => $outputlangs->trans("MonthShort08"),
984
                9 => $outputlangs->trans("MonthShort09"),
985
                10 => $outputlangs->trans("MonthShort10"),
986
                11 => $outputlangs->trans("MonthShort11"),
987
                12 => $outputlangs->trans("MonthShort12")
988
            );
989
        }
990
991
        return $montharray;
992
    }
993
}
994