2008-08-29 22:18:28 +02:00
< ? php
2011-05-25 15:27:07 +02:00
/* Copyright ( C ) 2004 - 2011 Laurent Destailleur < eldy @ users . sourceforge . net >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2005 - 2011 Regis Houssin < regis . houssin @ inodbox . com >
2015-04-18 19:14:30 +02:00
* Copyright ( C ) 2011 - 2015 Juanjo Menent < jmenent @ 2 byte . es >
2017-08-02 10:31:16 +02:00
* Copyright ( C ) 2017 Ferran Marcet < fmarcet @ 2 byte . es >
2018-12-01 00:41:46 +01:00
* Copyright ( C ) 2018 Charlene Benke < charlie @ patas - monkey . com >
*
2008-08-29 22:18:28 +02:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2008-08-29 22:18:28 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2008-08-29 22:18:28 +02:00
*/
/**
2011-10-24 11:25:54 +02:00
* \file htdocs / core / lib / date . lib . php
2010-11-21 17:11:52 +01:00
* \brief Set of function to manipulate dates
2008-08-29 22:18:28 +02:00
*/
2011-06-10 22:31:10 +02:00
/**
* Return an array with timezone values
2011-09-16 19:19:24 +02:00
*
2011-06-10 22:31:10 +02:00
* @ return array Array with timezone values
*/
function get_tz_array ()
{
2020-04-10 10:59:32 +02:00
$tzarray = array (
2012-01-22 02:12:11 +01:00
- 11 => " Pacific/Midway " ,
- 10 => " Pacific/Fakaofo " ,
- 9 => " America/Anchorage " ,
- 8 => " America/Los_Angeles " ,
- 7 => " America/Dawson_Creek " ,
- 6 => " America/Chicago " ,
- 5 => " America/Bogota " ,
- 4 => " America/Anguilla " ,
- 3 => " America/Araguaina " ,
- 2 => " America/Noronha " ,
- 1 => " Atlantic/Azores " ,
0 => " Africa/Abidjan " ,
1 => " Europe/Paris " ,
2 => " Europe/Helsinki " ,
3 => " Europe/Moscow " ,
4 => " Asia/Dubai " ,
5 => " Asia/Karachi " ,
6 => " Indian/Chagos " ,
7 => " Asia/Jakarta " ,
8 => " Asia/Hong_Kong " ,
9 => " Asia/Tokyo " ,
10 => " Australia/Sydney " ,
11 => " Pacific/Noumea " ,
12 => " Pacific/Auckland " ,
13 => " Pacific/Enderbury "
);
2011-06-10 22:31:10 +02:00
return $tzarray ;
}
2011-11-01 04:57:45 +01:00
/**
2012-02-05 15:13:31 +01:00
* Return server timezone string
2011-11-01 04:57:45 +01:00
*
2012-02-05 15:13:31 +01:00
* @ return string PHP server timezone string ( 'Europe/Paris' )
2011-11-01 04:57:45 +01:00
*/
2012-02-06 05:31:19 +01:00
function getServerTimeZoneString ()
2011-11-01 04:57:45 +01:00
{
2014-03-21 18:05:08 +01:00
return @ date_default_timezone_get ();
2012-02-05 15:13:31 +01:00
}
/**
* Return server timezone int .
*
2012-05-14 16:46:48 +02:00
* @ param string $refgmtdate Reference period for timezone ( timezone differs on winter and summer . May be 'now' , 'winter' or 'summer' )
2012-02-07 10:25:58 +01:00
* @ return int An offset in hour ( + 1 for Europe / Paris on winter and + 2 for Europe / Paris on summer )
2012-02-05 15:13:31 +01:00
*/
2019-01-27 15:20:16 +01:00
function getServerTimeZoneInt ( $refgmtdate = 'now' )
2012-02-05 15:13:31 +01:00
{
2019-01-27 11:55:16 +01:00
if ( method_exists ( 'DateTimeZone' , 'getOffset' ))
2012-02-05 15:13:31 +01:00
{
// Method 1 (include daylight)
2020-04-10 10:59:32 +02:00
$gmtnow = dol_now ( 'gmt' ); $yearref = dol_print_date ( $gmtnow , '%Y' ); $monthref = dol_print_date ( $gmtnow , '%m' ); $dayref = dol_print_date ( $gmtnow , '%d' );
if ( $refgmtdate == 'now' ) $newrefgmtdate = $yearref . '-' . $monthref . '-' . $dayref ;
elseif ( $refgmtdate == 'summer' ) $newrefgmtdate = $yearref . '-08-01' ;
else $newrefgmtdate = $yearref . '-01-01' ;
$newrefgmtdate .= 'T00:00:00+00:00' ;
2012-02-06 05:31:19 +01:00
$localtz = new DateTimeZone ( getServerTimeZoneString ());
2012-05-15 00:48:59 +02:00
$localdt = new DateTime ( $newrefgmtdate , $localtz );
2020-04-10 10:59:32 +02:00
$tmp = - 1 * $localtz -> getOffset ( $localdt );
2012-05-15 00:48:59 +02:00
//print $refgmtdate.'='.$tmp;
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$tmp = 0 ;
2019-01-27 11:55:16 +01:00
dol_print_error ( '' , 'PHP version must be 5.3+' );
2012-02-05 15:13:31 +01:00
}
2020-04-10 10:59:32 +02:00
$tz = round (( $tmp < 0 ? 1 : - 1 ) * abs ( $tmp / 3600 ));
2011-11-01 04:57:45 +01:00
return $tz ;
}
2010-10-02 01:37:36 +02:00
/**
* Add a delay to a date
2011-09-16 19:19:24 +02:00
*
2013-11-07 21:12:11 +01:00
* @ param int $time Date timestamp ( or string with format YYYY - MM - DD )
2011-09-16 19:19:24 +02:00
* @ param int $duration_value Value of delay to add
2020-08-27 10:29:23 +02:00
* @ param int $duration_unit Unit of added delay ( d , m , y , w , h , i )
2014-09-05 13:48:55 +02:00
* @ return int New timestamp
2010-10-02 01:37:36 +02:00
*/
2016-02-16 00:31:05 +01:00
function dol_time_plus_duree ( $time , $duration_value , $duration_unit )
2010-10-02 01:37:36 +02:00
{
2017-09-11 02:09:48 +02:00
global $conf ;
2012-01-22 02:12:11 +01:00
if ( $duration_value == 0 ) return $time ;
2020-08-27 10:29:23 +02:00
if ( $duration_unit == 'i' ) return $time + ( 60 * $duration_value );
2020-04-10 10:59:32 +02:00
if ( $duration_unit == 'h' ) return $time + ( 3600 * $duration_value );
if ( $duration_unit == 'w' ) return $time + ( 3600 * 24 * 7 * $duration_value );
2017-09-11 02:09:48 +02:00
2020-04-10 10:59:32 +02:00
$deltastring = 'P' ;
2017-09-11 02:09:48 +02:00
2020-04-10 10:59:32 +02:00
if ( $duration_value > 0 ) { $deltastring .= abs ( $duration_value ); $sub = false ; }
if ( $duration_value < 0 ) { $deltastring .= abs ( $duration_value ); $sub = true ; }
if ( $duration_unit == 'd' ) { $deltastring .= " D " ; }
if ( $duration_unit == 'm' ) { $deltastring .= " M " ; }
if ( $duration_unit == 'y' ) { $deltastring .= " Y " ; }
2017-09-11 02:09:48 +02:00
2016-06-30 16:16:27 +02:00
$date = new DateTime ();
2020-04-10 10:59:32 +02:00
if ( ! empty ( $conf -> global -> MAIN_DATE_IN_MEMORY_ARE_GMT )) $date -> setTimezone ( new DateTimeZone ( 'UTC' ));
2016-06-30 16:16:27 +02:00
$date -> setTimestamp ( $time );
$interval = new DateInterval ( $deltastring );
2017-09-11 02:09:48 +02:00
2020-04-10 10:59:32 +02:00
if ( $sub ) $date -> sub ( $interval );
2019-02-10 10:45:49 +01:00
else $date -> add ( $interval );
2017-09-11 02:09:48 +02:00
2016-06-30 16:16:27 +02:00
return $date -> getTimestamp ();
2010-10-02 01:37:36 +02:00
}
2012-02-04 14:39:47 +01:00
/**
* Convert hours and minutes into seconds
2011-09-16 19:19:24 +02:00
*
2012-02-04 14:39:47 +01:00
* @ param int $iHours Hours
* @ param int $iMinutes Minutes
* @ param int $iSeconds Seconds
* @ return int Time into seconds
2019-03-11 01:01:15 +01:00
* @ see convertSecondToTime ()
2008-08-29 22:18:28 +02:00
*/
2019-01-27 15:20:16 +01:00
function convertTime2Seconds ( $iHours = 0 , $iMinutes = 0 , $iSeconds = 0 )
2008-08-29 22:18:28 +02:00
{
2020-04-10 10:59:32 +02:00
$iResult = ( $iHours * 3600 ) + ( $iMinutes * 60 ) + $iSeconds ;
2008-08-29 22:18:28 +02:00
return $iResult ;
}
2018-01-04 19:54:30 +01:00
/** Return , in clear text , value of a number of seconds in days , hours and minutes .
* Can be used to show a duration .
2011-09-16 19:19:24 +02:00
*
* @ param int $iSecond Number of seconds
2018-05-27 15:04:12 +02:00
* @ param string $format Output format ( 'all' : total delay days hour : min like " 2 days 12:30 " ,
2018-08-09 11:50:07 +02:00
* - 'allwithouthour' : total delay days without hour part like " 2 days " ,
* - 'allhourmin' : total delay with format hours : min like " 60:30 " ,
2019-01-17 17:50:21 +01:00
* - 'allhourminsec' : total delay with format hours : min : sec like " 60:30:10 " ,
2018-08-09 11:50:07 +02:00
* - 'allhour' : total delay hours without min / sec like " 60:30 " ,
* - 'fullhour' : total delay hour decimal like " 60.5 " for 60 : 30 ,
* - 'hour' : only hours part " 12 " ,
* - 'min' : only minutes part " 30 " ,
* - 'sec' : only seconds part ,
* - 'month' : only month part ,
* - 'year' : only year part );
2011-09-16 19:19:24 +02:00
* @ param int $lengthOfDay Length of day ( default 86400 seconds for 1 day , 28800 for 8 hour )
* @ param int $lengthOfWeek Length of week ( default 7 )
2014-12-28 20:12:32 +01:00
* @ return string Formated text of duration
2011-09-16 19:19:24 +02:00
* Example : 0 return 00 : 00 , 3600 return 1 : 00 , 86400 return 1 d , 90000 return 1 Day 01 : 00
2019-03-11 01:01:15 +01:00
* @ see convertTime2Seconds ()
2008-08-29 22:18:28 +02:00
*/
2019-01-27 15:20:16 +01:00
function convertSecondToTime ( $iSecond , $format = 'all' , $lengthOfDay = 86400 , $lengthOfWeek = 7 )
2008-11-05 20:46:09 +01:00
{
2008-11-03 20:24:41 +01:00
global $langs ;
2009-11-17 12:25:11 +01:00
2020-04-10 10:59:32 +02:00
if ( empty ( $lengthOfDay )) $lengthOfDay = 86400 ; // 1 day = 24 hours
if ( empty ( $lengthOfWeek )) $lengthOfWeek = 7 ; // 1 week = 7 days
2008-11-05 20:46:09 +01:00
2019-01-17 17:50:21 +01:00
if ( $format == 'all' || $format == 'allwithouthour' || $format == 'allhour' || $format == 'allhourmin' || $format == 'allhourminsec' )
2008-11-05 20:46:09 +01:00
{
2020-04-10 10:59:32 +02:00
if (( int ) $iSecond === 0 ) return '0' ; // This is to avoid having 0 return a 12:00 AM for en_US
2010-07-10 01:49:41 +02:00
2020-04-10 10:59:32 +02:00
$sTime = '' ;
$sDay = 0 ;
$sWeek = 0 ;
2011-02-19 15:14:05 +01:00
2009-10-29 09:57:05 +01:00
if ( $iSecond >= $lengthOfDay )
2008-11-03 20:24:41 +01:00
{
2020-04-10 10:59:32 +02:00
for ( $i = $iSecond ; $i >= $lengthOfDay ; $i -= $lengthOfDay )
2009-10-29 09:57:05 +01:00
{
$sDay ++ ;
2020-04-10 10:59:32 +02:00
$iSecond -= $lengthOfDay ;
2009-10-29 09:57:05 +01:00
}
2008-11-03 20:24:41 +01:00
$dayTranslate = $langs -> trans ( " Day " );
2020-04-10 10:59:32 +02:00
if ( $iSecond >= ( $lengthOfDay * 2 )) $dayTranslate = $langs -> trans ( " Days " );
2008-11-03 20:24:41 +01:00
}
2011-02-19 15:14:05 +01:00
if ( $lengthOfWeek < 7 )
{
if ( $sDay )
{
if ( $sDay >= $lengthOfWeek )
{
2020-04-10 10:59:32 +02:00
$sWeek = ( int ) (( $sDay - $sDay % $lengthOfWeek ) / $lengthOfWeek );
2011-02-19 15:14:05 +01:00
$sDay = $sDay % $lengthOfWeek ;
$weekTranslate = $langs -> trans ( " DurationWeek " );
if ( $sWeek >= 2 ) $weekTranslate = $langs -> trans ( " DurationWeeks " );
2020-04-10 10:59:32 +02:00
$sTime .= $sWeek . ' ' . $weekTranslate . ' ' ;
2011-02-19 15:14:05 +01:00
}
}
}
2020-04-10 10:59:32 +02:00
if ( $sDay > 0 )
2012-06-10 12:42:19 +02:00
{
$dayTranslate = $langs -> trans ( " Day " );
if ( $sDay > 1 ) $dayTranslate = $langs -> trans ( " Days " );
2020-04-10 10:59:32 +02:00
$sTime .= $sDay . ' ' . $dayTranslate . ' ' ;
2012-06-10 12:42:19 +02:00
}
2011-02-19 15:14:05 +01:00
2013-10-30 21:44:04 +01:00
if ( $format == 'all' )
{
if ( $iSecond || empty ( $sDay ))
{
2020-04-10 10:59:32 +02:00
$sTime .= dol_print_date ( $iSecond , 'hourduration' , true );
2013-10-30 21:44:04 +01:00
}
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'allhourminsec' )
2019-01-17 17:50:21 +01:00
{
2020-04-10 10:59:32 +02:00
return sprintf ( " %02d " , ( $sWeek * $lengthOfWeek * 24 + $sDay * 24 + ( int ) floor ( $iSecond / 3600 ))) . ':' . sprintf ( " %02d " , (( int ) floor (( $iSecond % 3600 ) / 60 ))) . ':' . sprintf ( " %02d " , (( int ) ( $iSecond % 60 )));
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'allhourmin' )
2013-10-30 21:44:04 +01:00
{
2020-04-10 10:59:32 +02:00
return sprintf ( " %02d " , ( $sWeek * $lengthOfWeek * 24 + $sDay * 24 + ( int ) floor ( $iSecond / 3600 ))) . ':' . sprintf ( " %02d " , (( int ) floor (( $iSecond % 3600 ) / 60 )));
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'allhour' )
2009-10-29 08:53:33 +01:00
{
2020-04-10 10:59:32 +02:00
return sprintf ( " %02d " , ( $sWeek * $lengthOfWeek * 24 + $sDay * 24 + ( int ) floor ( $iSecond / 3600 )));
2009-10-29 08:53:33 +01:00
}
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'hour' ) // only hour part
2009-10-29 08:53:33 +01:00
{
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%H' , true );
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'fullhour' )
2013-05-15 14:19:16 +02:00
{
if ( ! empty ( $iSecond )) {
2020-04-10 10:59:32 +02:00
$iSecond = $iSecond / 3600 ;
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$iSecond = 0 ;
2013-05-15 14:19:16 +02:00
}
2020-04-10 10:59:32 +02:00
$sTime = $iSecond ;
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'min' ) // only min part
2009-10-29 08:53:33 +01:00
{
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%M' , true );
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'sec' ) // only sec part
2011-06-10 22:31:10 +02:00
{
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%S' , true );
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'month' ) // only month part
2011-08-20 17:11:31 +02:00
{
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%m' , true );
2020-05-21 15:05:19 +02:00
} elseif ( $format == 'year' ) // only year part
2011-08-20 17:11:31 +02:00
{
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%Y' , true );
2011-08-20 17:11:31 +02:00
}
return trim ( $sTime );
2008-08-29 22:18:28 +02:00
}
2018-12-01 00:41:46 +01:00
/**
2018-12-14 19:21:19 +01:00
* Generate a SQL string to make a filter into a range ( for second of date until last second of date )
2018-12-01 00:41:46 +01:00
*
2019-09-28 13:22:05 +02:00
* @ param string $datefield Name of SQL field where apply sql date filter
* @ param int $day_date Day date
* @ param int $month_date Month date
* @ param int $year_date Year date
* @ param int $excludefirstand Exclude first and
* @ return string $sqldate String with SQL filter
2018-12-01 00:41:46 +01:00
*/
2019-09-28 13:22:05 +02:00
function dolSqlDateFilter ( $datefield , $day_date , $month_date , $year_date , $excludefirstand = 0 )
2018-12-14 19:21:19 +01:00
{
2018-12-01 00:41:46 +01:00
global $db ;
2020-04-10 10:59:32 +02:00
$sqldate = " " ;
2018-12-01 00:41:46 +01:00
if ( $month_date > 0 ) {
if ( $year_date > 0 && empty ( $day_date )) {
2020-04-10 10:59:32 +02:00
$sqldate .= ( $excludefirstand ? " " : " AND " ) . $datefield . " BETWEEN ' " . $db -> idate ( dol_get_first_day ( $year_date , $month_date , false ));
$sqldate .= " ' AND ' " . $db -> idate ( dol_get_last_day ( $year_date , $month_date , false )) . " ' " ;
} elseif ( $year_date > 0 && ! empty ( $day_date )) {
$sqldate .= ( $excludefirstand ? " " : " AND " ) . $datefield . " BETWEEN ' " . $db -> idate ( dol_mktime ( 0 , 0 , 0 , $month_date , $day_date , $year_date ));
$sqldate .= " ' AND ' " . $db -> idate ( dol_mktime ( 23 , 59 , 59 , $month_date , $day_date , $year_date )) . " ' " ;
2020-05-21 01:41:27 +02:00
} else $sqldate .= ( $excludefirstand ? " " : " AND " ) . " date_format( " . $datefield . " , '%c') = ' " . $db -> escape ( $month_date ) . " ' " ;
2020-04-10 10:59:32 +02:00
} elseif ( $year_date > 0 ) {
$sqldate .= ( $excludefirstand ? " " : " AND " ) . $datefield . " BETWEEN ' " . $db -> idate ( dol_get_first_day ( $year_date , 1 , false ));
$sqldate .= " ' AND ' " . $db -> idate ( dol_get_last_day ( $year_date , 12 , false )) . " ' " ;
2018-12-01 00:41:46 +01:00
}
return $sqldate ;
}
2012-01-21 14:10:22 +01:00
/**
* Convert a string date into a GM Timestamps date
2015-07-21 00:13:13 +02:00
* 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 .
2012-01-21 14:10:22 +01:00
*
* @ param string $string Date in a string
* YYYYMMDD
* YYYYMMDDHHMMSS
* YYYYMMDDTHHMMSSZ
* YYYY - MM - DDTHH : MM : SSZ ( RFC3339 )
2015-04-23 23:21:06 +02:00
* DD / MM / YY or DD / MM / YYYY ( deprecated )
* DD / MM / YY HH : MM : SS or DD / MM / YYYY HH : MM : SS ( deprecated )
2012-01-22 02:12:11 +01:00
* @ param int $gm 1 = Input date is GM date ,
* 0 = Input date is local date using PHP server timezone
2013-11-07 21:12:11 +01:00
* @ return int Date as a timestamp
2012-01-22 02:12:11 +01:00
* 19700101020000 -> 7200 with gm = 1
2019-09-17 17:55:30 +02:00
* 19700101000000 -> 0 with gm = 1
2012-01-21 14:10:22 +01:00
*
2019-03-11 01:01:15 +01:00
* @ see dol_print_date (), dol_mktime (), dol_getdate ()
2012-01-21 14:10:22 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_stringtotime ( $string , $gm = 1 )
2012-01-21 14:10:22 +01:00
{
2020-04-10 10:59:32 +02:00
$reg = array ();
2012-01-21 14:10:22 +01:00
// Convert date with format DD/MM/YYY HH:MM:SS. This part of code should not be used.
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/^([0-9]+)\/([0-9]+)\/([0-9]+)\s?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i' , $string , $reg ))
2012-01-21 14:10:22 +01:00
{
2015-04-23 23:21:06 +02:00
dol_syslog ( " dol_stringtotime call to function with deprecated parameter format " , LOG_WARNING );
2012-01-21 14:10:22 +01:00
// Date est au format 'DD/MM/YY' ou 'DD/MM/YY HH:MM:SS'
// Date est au format 'DD/MM/YYYY' ou 'DD/MM/YYYY HH:MM:SS'
$sday = $reg [ 1 ];
$smonth = $reg [ 2 ];
$syear = $reg [ 3 ];
$shour = $reg [ 4 ];
$smin = $reg [ 5 ];
$ssec = $reg [ 6 ];
2020-04-10 10:59:32 +02:00
if ( $syear < 50 ) $syear += 1900 ;
if ( $syear >= 50 && $syear < 100 ) $syear += 2000 ;
$string = sprintf ( " %04d%02d%02d%02d%02d%02d " , $syear , $smonth , $sday , $shour , $smin , $ssec );
2020-05-21 15:05:19 +02:00
} elseif (
2019-01-27 11:55:16 +01:00
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)
|| 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
|| 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
2013-06-27 16:02:52 +02:00
)
2012-01-21 14:10:22 +01:00
{
$syear = $reg [ 1 ];
$smonth = $reg [ 2 ];
$sday = $reg [ 3 ];
$shour = $reg [ 4 ];
$smin = $reg [ 5 ];
$ssec = $reg [ 6 ];
2020-04-10 10:59:32 +02:00
$string = sprintf ( " %04d%02d%02d%02d%02d%02d " , $syear , $smonth , $sday , $shour , $smin , $ssec );
2012-01-21 14:10:22 +01:00
}
2020-04-10 10:59:32 +02:00
$string = preg_replace ( '/([^0-9])/i' , '' , $string );
$tmp = $string . '000000' ;
$date = 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 ));
2012-01-21 14:10:22 +01:00
return $date ;
}
2011-02-02 16:51:18 +01:00
/** Return previous day
2011-09-16 19:19:24 +02:00
*
* @ param int $day Day
* @ param int $month Month
* @ param int $year Year
* @ return array Previous year , month , day
2011-02-02 16:51:18 +01:00
*/
function dol_get_prev_day ( $day , $month , $year )
{
2020-04-10 10:59:32 +02:00
$time = dol_mktime ( 12 , 0 , 0 , $month , $day , $year , 1 , 0 );
$time -= 24 * 60 * 60 ;
$tmparray = dol_getdate ( $time , true );
2011-02-11 01:00:47 +01:00
return array ( 'year' => $tmparray [ 'year' ], 'month' => $tmparray [ 'mon' ], 'day' => $tmparray [ 'mday' ]);
2011-02-02 16:51:18 +01:00
}
/** Return next day
2011-09-16 19:19:24 +02:00
*
* @ param int $day Day
* @ param int $month Month
* @ param int $year Year
* @ return array Next year , month , day
2011-02-02 16:51:18 +01:00
*/
function dol_get_next_day ( $day , $month , $year )
{
2020-04-10 10:59:32 +02:00
$time = dol_mktime ( 12 , 0 , 0 , $month , $day , $year , 1 , 0 );
$time += 24 * 60 * 60 ;
$tmparray = dol_getdate ( $time , true );
2011-02-11 01:00:47 +01:00
return array ( 'year' => $tmparray [ 'year' ], 'month' => $tmparray [ 'mon' ], 'day' => $tmparray [ 'mday' ]);
2011-02-02 16:51:18 +01:00
}
2010-10-02 01:37:36 +02:00
/** Return previous month
2011-09-16 19:19:24 +02:00
*
* @ param int $month Month
* @ param int $year Year
* @ return array Previous year , month
2008-08-29 22:18:28 +02:00
*/
function dol_get_prev_month ( $month , $year )
{
if ( $month == 1 )
{
$prev_month = 12 ;
$prev_year = $year - 1 ;
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$prev_month = $month - 1 ;
2008-08-29 22:18:28 +02:00
$prev_year = $year ;
}
return array ( 'year' => $prev_year , 'month' => $prev_month );
}
2010-10-02 01:37:36 +02:00
/** Return next month
2011-09-16 19:19:24 +02:00
*
* @ param int $month Month
* @ param int $year Year
* @ return array Next year , month
2008-08-29 22:18:28 +02:00
*/
2010-01-12 00:25:54 +01:00
function dol_get_next_month ( $month , $year )
2008-08-29 22:18:28 +02:00
{
if ( $month == 12 )
{
$next_month = 1 ;
$next_year = $year + 1 ;
2020-05-21 15:05:19 +02:00
} else {
2008-08-29 22:18:28 +02:00
$next_month = $month + 1 ;
$next_year = $year ;
}
return array ( 'year' => $next_year , 'month' => $next_month );
}
2011-03-09 02:35:25 +01:00
/** Return previous week
2011-09-16 19:19:24 +02:00
*
* @ param int $day Day
* @ param int $week Week
* @ param int $month Month
* @ param int $year Year
* @ return array Previous year , month , day
2011-03-09 02:35:25 +01:00
*/
2011-03-09 17:53:30 +01:00
function dol_get_prev_week ( $day , $week , $month , $year )
2011-03-09 02:35:25 +01:00
{
2011-03-09 17:53:30 +01:00
$tmparray = dol_get_first_day_week ( $day , $month , $year );
2011-05-25 15:27:07 +02:00
2020-04-10 10:59:32 +02:00
$time = dol_mktime ( 12 , 0 , 0 , $month , $tmparray [ 'first_day' ], $year , 1 , 0 );
$time -= 24 * 60 * 60 * 7 ;
$tmparray = dol_getdate ( $time , true );
2011-03-09 17:53:30 +01:00
return array ( 'year' => $tmparray [ 'year' ], 'month' => $tmparray [ 'mon' ], 'day' => $tmparray [ 'mday' ]);
2011-03-09 02:35:25 +01:00
}
2011-05-25 15:27:07 +02:00
2011-03-09 02:35:25 +01:00
/** Return next week
2011-09-16 19:19:24 +02:00
*
* @ param int $day Day
* @ param int $week Week
* @ param int $month Month
* @ param int $year Year
* @ return array Next year , month , day
2011-03-09 02:35:25 +01:00
*/
2011-05-25 15:27:07 +02:00
function dol_get_next_week ( $day , $week , $month , $year )
2011-03-09 02:35:25 +01:00
{
2011-03-09 17:53:30 +01:00
$tmparray = dol_get_first_day_week ( $day , $month , $year );
2011-05-25 15:27:07 +02:00
2020-04-10 10:59:32 +02:00
$time = dol_mktime ( 12 , 0 , 0 , $tmparray [ 'first_month' ], $tmparray [ 'first_day' ], $tmparray [ 'first_year' ], 1 , 0 );
$time += 24 * 60 * 60 * 7 ;
$tmparray = dol_getdate ( $time , true );
2011-05-25 15:27:07 +02:00
2011-03-09 17:53:30 +01:00
return array ( 'year' => $tmparray [ 'year' ], 'month' => $tmparray [ 'mon' ], 'day' => $tmparray [ 'mday' ]);
2011-03-09 02:35:25 +01:00
}
2008-08-29 22:18:28 +02:00
2010-10-02 01:37:36 +02:00
/** Return GMT time for first day of a month or year
2011-09-16 19:19:24 +02:00
*
* @ param int $year Year
* @ param int $month Month
2014-03-21 16:22:41 +01:00
* @ param mixed $gm False or 0 or 'server' = Return date to compare with server TZ , True or 1 to compare with GM date .
2020-09-22 14:45:19 +02:00
* Exemple : dol_get_first_day ( 1970 , 1 , false ) will return - 3600 with TZ + 1 , a dol_print_date on it will return 1970 - 01 - 01 00 : 00 : 00
* Exemple : dol_get_first_day ( 1970 , 1 , true ) will return 0 whatever is TZ , a dol_print_date on it will return 1970 - 01 - 01 00 : 00 : 00
2014-10-29 20:21:24 +01:00
* @ return int Date for first day , '' if error
2009-12-03 20:25:35 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_get_first_day ( $year , $month = 1 , $gm = false )
2009-12-03 20:25:35 +01:00
{
2014-10-29 20:21:24 +01:00
if ( $year > 9999 ) return '' ;
2019-01-27 11:55:16 +01:00
return dol_mktime ( 0 , 0 , 0 , $month , 1 , $year , $gm );
2009-12-03 20:25:35 +01:00
}
2010-10-02 01:37:36 +02:00
/** Return GMT time for last day of a month or year
2011-09-16 19:19:24 +02:00
*
* @ param int $year Year
* @ param int $month Month
2014-03-21 16:22:41 +01:00
* @ param boolean $gm False or 0 or 'server' = Return date to compare with server TZ , True or 1 to compare with GM date .
2014-10-29 20:21:24 +01:00
* @ return int Date for first day , '' if error
2009-12-03 20:25:35 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_get_last_day ( $year , $month = 12 , $gm = false )
2009-12-03 20:25:35 +01:00
{
2014-10-29 20:21:24 +01:00
if ( $year > 9999 ) return '' ;
2009-12-03 20:25:35 +01:00
if ( $month == 12 )
{
$month = 1 ;
$year += 1 ;
2020-05-21 15:05:19 +02:00
} else {
2009-12-03 20:25:35 +01:00
$month += 1 ;
}
2010-01-12 00:25:54 +01:00
2009-12-03 20:25:35 +01:00
// On se deplace au debut du mois suivant, et on retire un jour
2020-04-10 10:59:32 +02:00
$datelim = dol_mktime ( 23 , 59 , 59 , $month , 1 , $year , $gm );
2009-12-03 20:25:35 +01:00
$datelim -= ( 3600 * 24 );
2010-01-12 00:25:54 +01:00
return $datelim ;
2009-12-03 20:25:35 +01:00
}
2020-09-22 14:45:19 +02:00
/** Return GMT time for last hour of a given GMT date ( it removes hours , min and second part )
*
2020-09-22 15:55:30 +02:00
* @ param int $date Date
2020-09-22 14:45:19 +02:00
* @ return int Date for last hour of a given date
*/
function dol_get_last_hour ( $date )
{
$tmparray = dol_getdate ( $date );
return dol_mktime ( 23 , 59 , 59 , $tmparray [ 'mon' ], $tmparray [ 'mday' ], $tmparray [ 'year' ], false );
}
/** Return GMT time for first hour of a given GMT date ( it removes hours , min and second part )
*
2020-09-22 15:55:30 +02:00
* @ param int $date Date
2020-09-22 14:45:19 +02:00
* @ return int Date for last hour of a given date
*/
function dol_get_first_hour ( $date )
{
$tmparray = dol_getdate ( $date );
return dol_mktime ( 0 , 0 , 0 , $tmparray [ 'mon' ], $tmparray [ 'mday' ], $tmparray [ 'year' ], false );
}
2015-02-03 11:25:51 +01:00
/** Return first day of week for a date . First day of week may be monday if option MAIN_START_WEEK is 1.
2011-09-16 19:19:24 +02:00
*
* @ param int $day Day
* @ param int $month Month
* @ param int $year Year
2014-03-21 16:22:41 +01:00
* @ param int $gm False or 0 or 'server' = Return date to compare with server TZ , True or 1 to compare with GM date .
2015-02-03 11:25:51 +01:00
* @ return array year , month , week , first_day , first_month , first_year , prev_day , prev_month , prev_year
2011-03-09 02:35:25 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_get_first_day_week ( $day , $month , $year , $gm = false )
2011-03-09 02:35:25 +01:00
{
2011-03-09 17:53:30 +01:00
global $conf ;
2011-05-25 15:27:07 +02:00
2015-02-03 11:25:51 +01:00
//$day=2; $month=2; $year=2015;
2019-01-27 11:55:16 +01:00
$date = dol_mktime ( 0 , 0 , 0 , $month , $day , $year , $gm );
2011-05-25 15:27:07 +02:00
2011-03-09 23:56:50 +01:00
//Checking conf of start week
2020-04-10 10:59:32 +02:00
$start_week = ( isset ( $conf -> global -> MAIN_START_WEEK ) ? $conf -> global -> MAIN_START_WEEK : 1 );
2011-05-25 15:27:07 +02:00
2020-04-10 10:59:32 +02:00
$tmparray = dol_getdate ( $date , true ); // detail of current day
2011-05-25 15:27:07 +02:00
2015-02-03 11:25:51 +01:00
//Calculate days = offset from current day
2011-03-09 23:56:50 +01:00
$days = $start_week - $tmparray [ 'wday' ];
2020-04-10 10:59:32 +02:00
if ( $days >= 1 ) $days = 7 - $days ;
2011-03-09 23:56:50 +01:00
$days = abs ( $days );
2020-04-10 10:59:32 +02:00
$seconds = $days * 24 * 60 * 60 ;
2015-02-03 11:25:51 +01:00
//print 'start_week='.$start_week.' tmparray[wday]='.$tmparray['wday'].' day offset='.$days.' seconds offset='.$seconds.'<br>';
2011-05-25 15:27:07 +02:00
2011-03-09 23:56:50 +01:00
//Get first day of week
2020-04-10 10:59:32 +02:00
$tmpdaytms = date ( $tmparray [ 0 ]) - $seconds ; // $tmparray[0] is day of parameters
2019-01-27 11:55:16 +01:00
$tmpday = date ( " d " , $tmpdaytms );
2011-05-25 15:27:07 +02:00
2014-09-05 13:48:55 +02:00
//Check first day of week is in same month than current day or not
2020-04-10 10:59:32 +02:00
if ( $tmpday > $day )
2011-03-09 17:53:30 +01:00
{
2020-04-10 10:59:32 +02:00
$prev_month = $month - 1 ;
$prev_year = $year ;
2011-05-25 15:27:07 +02:00
2020-04-10 10:59:32 +02:00
if ( $prev_month == 0 )
2011-03-09 17:53:30 +01:00
{
$prev_month = 12 ;
2020-04-10 10:59:32 +02:00
$prev_year = $year - 1 ;
2011-03-09 17:53:30 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2011-03-09 17:53:30 +01:00
$prev_month = $month ;
2020-04-10 10:59:32 +02:00
$prev_year = $year ;
2011-03-09 17:53:30 +01:00
}
2014-09-05 13:48:55 +02:00
$tmpmonth = $prev_month ;
$tmpyear = $prev_year ;
2011-03-09 23:56:50 +01:00
2014-09-07 12:22:04 +02:00
//Get first day of next week
2020-04-10 10:59:32 +02:00
$tmptime = dol_mktime ( 12 , 0 , 0 , $month , $tmpday , $year , 1 , 0 );
$tmptime -= 24 * 60 * 60 * 7 ;
$tmparray = dol_getdate ( $tmptime , true );
$prev_day = $tmparray [ 'mday' ];
2011-05-25 15:27:07 +02:00
2014-09-05 13:48:55 +02:00
//Check prev day of week is in same month than first day or not
2014-09-07 12:22:04 +02:00
if ( $prev_day > $tmpday )
2011-03-09 17:53:30 +01:00
{
2020-04-10 10:59:32 +02:00
$prev_month = $month - 1 ;
$prev_year = $year ;
2011-05-25 15:27:07 +02:00
2020-04-10 10:59:32 +02:00
if ( $prev_month == 0 )
2011-03-09 17:53:30 +01:00
{
$prev_month = 12 ;
2020-04-10 10:59:32 +02:00
$prev_year = $year - 1 ;
2011-03-09 17:53:30 +01:00
}
}
2011-05-25 15:27:07 +02:00
2019-01-27 11:55:16 +01:00
$week = date ( " W " , dol_mktime ( 0 , 0 , 0 , $tmpmonth , $tmpday , $tmpyear , $gm ));
2011-05-25 15:27:07 +02:00
2014-09-05 13:48:55 +02:00
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 );
2011-03-09 02:35:25 +01:00
}
2009-12-03 20:25:35 +01:00
2008-08-29 22:18:28 +02:00
/**
2019-09-09 10:27:56 +02:00
* Return the number of non working days including saturday and sunday ( or not ) between 2 dates in timestamp .
* Dates must be UTC with hour , day , min to 0.
2011-05-25 15:27:07 +02:00
* Called by function num_open_day
2011-09-16 19:19:24 +02:00
*
2014-04-23 15:48:20 +02:00
* @ param int $timestampStart Timestamp de debut
* @ param int $timestampEnd Timestamp de fin
2019-09-09 10:53:13 +02:00
* @ param string $country_code Country code
2015-11-28 16:11:15 +01:00
* @ param int $lastday Last day is included , 0 : no , 1 : yes
2019-09-09 10:27:56 +02:00
* @ param int $includesaturday Include saturday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
* @ param int $includesunday Include sunday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
* @ return int | string Number of non working days or error message string if error
2019-03-11 01:01:15 +01:00
* @ see num_between_day (), num_open_day ()
2008-08-29 22:18:28 +02:00
*/
2019-09-09 10:53:13 +02:00
function num_public_holiday ( $timestampStart , $timestampEnd , $country_code = '' , $lastday = 0 , $includesaturday = - 1 , $includesunday = - 1 )
2008-08-29 22:18:28 +02:00
{
2019-09-09 10:27:56 +02:00
global $db , $conf , $mysoc ;
2018-10-11 13:12:13 +02:00
2008-08-29 22:18:28 +02:00
$nbFerie = 0 ;
2019-09-09 10:27:56 +02:00
$specialdayrule = array ();
2008-08-29 22:18:28 +02:00
2014-03-05 21:29:33 +01:00
// Check to ensure we use correct parameters
2014-11-02 21:16:31 +01:00
if ((( $timestampEnd - $timestampStart ) % 86400 ) != 0 ) return 'ErrorDates must use same hours and must be GMT dates' ;
2014-03-05 21:29:33 +01:00
2019-09-09 10:53:13 +02:00
if ( empty ( $country_code )) $country_code = $mysoc -> country_code ;
2019-09-09 10:27:56 +02:00
if ( $includesaturday < 0 ) $includesaturday = ( isset ( $conf -> global -> MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY ) ? $conf -> global -> MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY : 1 );
if ( $includesunday < 0 ) $includesunday = ( isset ( $conf -> global -> MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY ) ? $conf -> global -> MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY : 1 );
2020-04-10 10:59:32 +02:00
$i = 0 ;
while ((( $lastday == 0 && $timestampStart < $timestampEnd ) || ( $lastday && $timestampStart <= $timestampEnd ))
2015-11-28 16:11:15 +01:00
&& ( $i < 50000 )) // Loop end when equals (Test on i is a security loop to avoid infinite loop)
2008-08-29 22:18:28 +02:00
{
2020-04-10 10:59:32 +02:00
$ferie = false ;
2008-08-29 22:18:28 +02:00
$jour = date ( " d " , $timestampStart );
$mois = date ( " m " , $timestampStart );
$annee = date ( " Y " , $timestampStart );
2018-10-11 13:12:13 +02:00
2019-09-09 10:53:13 +02:00
$country_id = dol_getIdFromCode ( $db , $country_code , 'c_country' , 'code' , 'rowid' );
2019-09-09 10:27:56 +02:00
// Loop on public holiday defined into hrm_public_holiday
$sql = " SELECT code, entity, fk_country, dayrule, year, month, day, active " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_hrm_public_holiday " ;
$sql .= " WHERE active = 1 and fk_country IN (0 " . ( $country_id > 0 ? " , " . $country_id : 0 ) . " ) " ;
2019-09-09 10:27:56 +02:00
$resql = $db -> query ( $sql );
if ( $resql )
{
$num_rows = $db -> num_rows ( $resql );
2020-04-10 10:59:32 +02:00
$i = 0 ;
2019-09-09 10:27:56 +02:00
while ( $i < $num_rows )
{
$obj = $db -> fetch_object ( $resql );
2020-04-10 10:59:32 +02:00
if ( ! empty ( $obj -> dayrule ) && $obj -> dayrule != 'date' ) // For example 'easter', '...'
2019-09-09 10:27:56 +02:00
{
$specialdayrule [ $obj -> dayrule ] = $obj -> dayrule ;
2020-05-21 15:05:19 +02:00
} else {
2019-09-09 10:27:56 +02:00
$match = 1 ;
2020-04-10 10:59:32 +02:00
if ( ! empty ( $obj -> year ) && $obj -> year != $annee ) $match = 0 ;
2019-09-09 10:27:56 +02:00
if ( $obj -> month != $mois ) $match = 0 ;
if ( $obj -> day != $jour ) $match = 0 ;
if ( $match ) $ferie = true ;
}
$i ++ ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-09-09 10:27:56 +02:00
dol_syslog ( $db -> lasterror (), LOG_ERR );
return 'Error sql ' . $db -> lasterror ();
}
2008-08-29 22:18:28 +02:00
2019-09-09 10:27:56 +02:00
// Special dayrules
if ( in_array ( 'easter' , $specialdayrule ))
{
2018-04-27 09:49:15 +02:00
// Calculation for easter date
2008-08-29 22:18:28 +02:00
$date_paques = easter_date ( $annee );
$jour_paques = date ( " d " , $date_paques );
$mois_paques = date ( " m " , $date_paques );
2020-04-10 10:59:32 +02:00
if ( $jour_paques == $jour && $mois_paques == $mois ) $ferie = true ;
2019-09-09 10:27:56 +02:00
// Easter (sunday)
}
2008-08-29 22:18:28 +02:00
2019-09-09 10:27:56 +02:00
if ( in_array ( 'eastermonday' , $specialdayrule ))
{
2018-04-27 09:49:15 +02:00
// Calculation for the monday of easter date
2019-09-09 10:27:56 +02:00
$date_paques = easter_date ( $annee );
$date_lundi_paques = mktime (
2018-04-23 15:14:34 +02:00
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 )
);
$jour_lundi_ascension = date ( " d " , $date_lundi_paques );
$mois_lundi_ascension = date ( " m " , $date_lundi_paques );
2020-04-10 10:59:32 +02:00
if ( $jour_lundi_ascension == $jour && $mois_lundi_ascension == $mois ) $ferie = true ;
2019-09-09 10:27:56 +02:00
// Easter (monday)
}
2018-04-23 15:14:34 +02:00
2019-09-09 10:27:56 +02:00
if ( in_array ( 'ascension' , $specialdayrule ))
{
// Calcul du jour de l'ascension (39 days after easter day)
$date_paques = easter_date ( $annee );
$date_ascension = mktime (
2011-09-16 19:19:24 +02:00
date ( " H " , $date_paques ),
date ( " i " , $date_paques ),
date ( " s " , $date_paques ),
date ( " m " , $date_paques ),
2018-04-23 15:14:34 +02:00
date ( " d " , $date_paques ) + 39 ,
2011-09-16 19:19:24 +02:00
date ( " Y " , $date_paques )
2012-05-25 11:53:53 +02:00
);
2008-08-29 22:18:28 +02:00
$jour_ascension = date ( " d " , $date_ascension );
$mois_ascension = date ( " m " , $date_ascension );
2020-04-10 10:59:32 +02:00
if ( $jour_ascension == $jour && $mois_ascension == $mois ) $ferie = true ;
2019-09-09 10:27:56 +02:00
// Ascension (thursday)
}
2008-08-29 22:18:28 +02:00
2019-09-09 10:27:56 +02:00
if ( in_array ( 'pentecote' , $specialdayrule ))
{
// Calculation of "Pentecote" (49 days after easter day)
$date_paques = easter_date ( $annee );
$date_pentecote = mktime (
2018-04-23 15:14:34 +02:00
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 )
2012-05-25 11:53:53 +02:00
);
2008-08-29 22:18:28 +02:00
$jour_pentecote = date ( " d " , $date_pentecote );
$mois_pentecote = date ( " m " , $date_pentecote );
2020-04-10 10:59:32 +02:00
if ( $jour_pentecote == $jour && $mois_pentecote == $mois ) $ferie = true ;
2019-09-09 10:27:56 +02:00
// "Pentecote" (sunday)
2008-08-29 22:18:28 +02:00
}
2019-09-09 10:27:56 +02:00
if ( in_array ( 'pentecotemonday' , $specialdayrule ))
2011-02-11 01:00:47 +01:00
{
2019-09-09 10:27:56 +02:00
// Calculation of "Pentecote" (49 days after easter day)
2011-02-11 01:00:47 +01:00
$date_paques = easter_date ( $annee );
2019-09-09 10:27:56 +02:00
$date_pentecote = mktime (
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 )
);
$jour_pentecote = date ( " d " , $date_pentecote );
$mois_pentecote = date ( " m " , $date_pentecote );
2020-04-10 10:59:32 +02:00
if ( $jour_pentecote == $jour && $mois_pentecote == $mois ) $ferie = true ;
2019-09-09 10:27:56 +02:00
// "Pentecote" (monday)
2014-07-10 12:06:09 +02:00
}
2014-09-05 13:48:55 +02:00
2019-09-09 10:27:56 +02:00
if ( in_array ( 'viernessanto' , $specialdayrule ))
2014-07-10 12:06:09 +02:00
{
// Viernes Santo
2019-09-09 10:27:56 +02:00
$date_paques = easter_date ( $annee );
$date_viernes = mktime (
2014-07-10 12:06:09 +02:00
date ( " H " , $date_paques ),
date ( " i " , $date_paques ),
date ( " s " , $date_paques ),
date ( " m " , $date_paques ),
2020-04-10 10:59:32 +02:00
date ( " d " , $date_paques ) - 2 ,
2014-07-10 12:06:09 +02:00
date ( " Y " , $date_paques )
);
$jour_viernes = date ( " d " , $date_viernes );
$mois_viernes = date ( " m " , $date_viernes );
2020-04-10 10:59:32 +02:00
if ( $jour_viernes == $jour && $mois_viernes == $mois ) $ferie = true ;
2014-07-10 12:06:09 +02:00
//Viernes Santo
2011-02-11 01:00:47 +01:00
}
2008-08-29 22:18:28 +02:00
2019-09-09 10:27:56 +02:00
if ( in_array ( 'fronleichnam' , $specialdayrule ))
2017-12-11 10:51:58 +01:00
{
// Fronleichnam (60 days after easter sunday)
2019-09-11 23:56:53 +02:00
$date_paques = easter_date ( $annee );
$date_fronleichnam = mktime (
2017-12-11 10:51:58 +01:00
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 )
);
$jour_fronleichnam = date ( " d " , $date_fronleichnam );
$mois_fronleichnam = date ( " m " , $date_fronleichnam );
2020-04-10 10:59:32 +02:00
if ( $jour_fronleichnam == $jour && $mois_fronleichnam == $mois ) $ferie = true ;
2017-12-11 10:51:58 +01:00
// Fronleichnam
}
2008-08-29 22:18:28 +02:00
2018-10-23 12:49:48 +02:00
// If we have to include saturday and sunday
2019-09-09 10:27:56 +02:00
if ( $includesaturday || $includesunday )
2008-08-29 22:18:28 +02:00
{
$jour_julien = unixtojd ( $timestampStart );
$jour_semaine = jddayofweek ( $jour_julien , 0 );
2019-09-09 10:27:56 +02:00
if ( $includesaturday ) //Saturday (6) and Sunday (0)
{
2020-04-10 10:59:32 +02:00
if ( $jour_semaine == 6 ) $ferie = true ;
2019-09-09 10:27:56 +02:00
}
if ( $includesunday ) //Saturday (6) and Sunday (0)
{
2020-04-10 10:59:32 +02:00
if ( $jour_semaine == 0 ) $ferie = true ;
2019-09-09 10:27:56 +02:00
}
2008-08-29 22:18:28 +02:00
}
2019-09-09 10:27:56 +02:00
// We increase the counter of non working day
2008-08-29 22:18:28 +02:00
if ( $ferie ) $nbFerie ++ ;
2014-03-05 21:29:33 +01:00
// Increase number of days (on go up into loop)
2020-04-10 10:59:32 +02:00
$timestampStart = dol_time_plus_duree ( $timestampStart , 1 , 'd' );
2014-11-02 21:16:31 +01:00
//var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart);
$i ++ ;
2008-08-29 22:18:28 +02:00
}
return $nbFerie ;
}
/**
2014-03-05 20:52:27 +01:00
* Function to return number of days between two dates ( date must be UTC date ! )
2012-09-24 21:37:19 +02:00
* Example : 2012 - 01 - 01 2012 - 01 - 02 => 1 if lastday = 0 , 2 if lastday = 1
2011-09-16 19:19:24 +02:00
*
2014-04-23 15:48:20 +02:00
* @ param int $timestampStart Timestamp start UTC
* @ param int $timestampEnd Timestamp end UTC
2015-11-28 16:11:15 +01:00
* @ param int $lastday Last day is included , 0 : no , 1 : yes
2012-09-24 21:37:19 +02:00
* @ return int Number of days
2019-03-11 01:01:15 +01:00
* @ seealso num_public_holiday (), num_open_day ()
2008-08-29 22:18:28 +02:00
*/
2019-01-27 15:20:16 +01:00
function num_between_day ( $timestampStart , $timestampEnd , $lastday = 0 )
2008-08-29 22:18:28 +02:00
{
if ( $timestampStart < $timestampEnd )
{
if ( $lastday == 1 )
{
$bit = 0 ;
2020-05-21 15:05:19 +02:00
} else {
2008-08-29 22:18:28 +02:00
$bit = 1 ;
}
2020-04-10 10:59:32 +02:00
$nbjours = ( int ) floor (( $timestampEnd - $timestampStart ) / ( 60 * 60 * 24 )) + 1 - $bit ;
2008-08-29 22:18:28 +02:00
}
2012-09-24 21:37:19 +02:00
//print ($timestampEnd - $timestampStart) - $lastday;
2008-08-29 22:18:28 +02:00
return $nbjours ;
}
/**
2012-12-18 13:12:11 +01:00
* Function to return number of working days ( and text of units ) between two dates ( working days )
2011-09-16 19:19:24 +02:00
*
2014-04-23 15:48:20 +02:00
* @ param int $timestampStart Timestamp for start date ( date must be UTC to avoid calculation errors )
* @ param int $timestampEnd Timestamp for end date ( date must be UTC to avoid calculation errors )
2014-03-05 20:52:27 +01:00
* @ param int $inhour 0 : return number of days , 1 : return number of hours
2012-12-18 13:12:11 +01:00
* @ param int $lastday We include last day , 0 : no , 1 : yes
* @ param int $halfday Tag to define half day when holiday start and end
2014-11-02 22:04:01 +01:00
* @ param string $country_code Country code ( company country code if not defined )
2020-04-10 12:04:21 +02:00
* @ return int | string Number of days or hours or string if error
2019-03-11 01:01:15 +01:00
* @ seealso num_between_day (), num_public_holiday ()
2008-08-29 22:18:28 +02:00
*/
2019-01-27 15:20:16 +01:00
function num_open_day ( $timestampStart , $timestampEnd , $inhour = 0 , $lastday = 0 , $halfday = 0 , $country_code = '' )
2008-08-29 22:18:28 +02:00
{
2020-04-10 10:59:32 +02:00
global $langs , $mysoc ;
2014-11-02 21:16:31 +01:00
2020-04-10 10:59:32 +02:00
if ( empty ( $country_code )) $country_code = $mysoc -> country_code ;
2008-08-29 22:18:28 +02:00
2014-11-02 21:16:31 +01:00
dol_syslog ( 'num_open_day timestampStart=' . $timestampStart . ' timestampEnd=' . $timestampEnd . ' bit=' . $lastday . ' country_code=' . $country_code );
2013-01-18 11:28:06 +01:00
2012-11-20 13:14:16 +01:00
// Check parameters
2020-04-10 10:59:32 +02:00
if ( ! is_int ( $timestampStart ) && ! is_float ( $timestampStart )) return 'ErrorBadParameter_num_open_day' ;
if ( ! is_int ( $timestampEnd ) && ! is_float ( $timestampEnd )) return 'ErrorBadParameter_num_open_day' ;
2012-11-20 13:14:16 +01:00
2012-09-24 21:37:19 +02:00
//print 'num_open_day timestampStart='.$timestampStart.' timestampEnd='.$timestampEnd.' bit='.$lastday;
2008-08-29 22:18:28 +02:00
if ( $timestampStart < $timestampEnd )
{
2014-11-02 21:16:31 +01:00
$numdays = num_between_day ( $timestampStart , $timestampEnd , $lastday );
2020-05-07 17:21:27 +02:00
2015-11-28 16:11:15 +01:00
$numholidays = num_public_holiday ( $timestampStart , $timestampEnd , $country_code , $lastday );
2020-04-10 12:04:21 +02:00
$nbOpenDay = ( $numdays - $numholidays );
if ( $inhour == 1 && $nbOpenDay <= 3 ) $nbOpenDay = ( $nbOpenDay * 24 );
2012-12-18 13:12:11 +01:00
return $nbOpenDay - (( $inhour == 1 ? 12 : 0.5 ) * abs ( $halfday ));
2020-05-21 15:05:19 +02:00
} elseif ( $timestampStart == $timestampEnd )
2012-09-24 21:37:19 +02:00
{
2020-05-07 17:21:27 +02:00
$numholidays = 0 ;
if ( $lastday ) {
$numholidays = num_public_holiday ( $timestampStart , $timestampEnd , $country_code , $lastday );
if ( $numholidays == 1 ) return 0 ;
}
2020-05-15 13:55:31 +02:00
$nbOpenDay = $lastday ;
2020-05-07 17:21:27 +02:00
2020-05-14 16:03:31 +02:00
if ( $inhour == 1 ) $nbOpenDay = ( $nbOpenDay * 24 );
2012-12-18 13:12:11 +01:00
return $nbOpenDay - (( $inhour == 1 ? 12 : 0.5 ) * abs ( $halfday ));
2020-05-21 15:05:19 +02:00
} else {
2008-08-29 22:18:28 +02:00
return $langs -> trans ( " Error " );
}
}
2011-08-17 18:07:41 +02:00
/**
2012-03-14 23:11:49 +01:00
* Return array of translated months or selected month .
* This replace old function monthArrayOrSelected .
2011-08-17 18:07:41 +02:00
*
2012-02-04 14:39:47 +01:00
* @ param Translate $outputlangs Object langs
2018-10-01 00:20:47 +02:00
* @ param int $short 0 = Return long label , 1 = Return short label
2012-01-24 09:19:28 +01:00
* @ return array Month string or array if selected < 0
2011-08-17 18:07:41 +02:00
*/
2019-01-27 15:20:16 +01:00
function monthArray ( $outputlangs , $short = 0 )
2011-08-17 18:07:41 +02:00
{
2020-04-10 10:59:32 +02:00
$montharray = array (
2018-10-01 00:20:47 +02:00
1 => $outputlangs -> trans ( " Month01 " ),
2 => $outputlangs -> trans ( " Month02 " ),
3 => $outputlangs -> trans ( " Month03 " ),
4 => $outputlangs -> trans ( " Month04 " ),
5 => $outputlangs -> trans ( " Month05 " ),
6 => $outputlangs -> trans ( " Month06 " ),
7 => $outputlangs -> trans ( " Month07 " ),
8 => $outputlangs -> trans ( " Month08 " ),
9 => $outputlangs -> trans ( " Month09 " ),
10 => $outputlangs -> trans ( " Month10 " ),
11 => $outputlangs -> trans ( " Month11 " ),
12 => $outputlangs -> trans ( " Month12 " )
2011-08-17 18:07:41 +02:00
);
2020-04-10 10:59:32 +02:00
if ( ! empty ( $short ))
2015-03-22 18:17:25 +01:00
{
2020-04-10 10:59:32 +02:00
$montharray = array (
2018-10-01 00:20:47 +02:00
1 => $outputlangs -> trans ( " MonthShort01 " ),
2 => $outputlangs -> trans ( " MonthShort02 " ),
3 => $outputlangs -> trans ( " MonthShort03 " ),
4 => $outputlangs -> trans ( " MonthShort04 " ),
5 => $outputlangs -> trans ( " MonthShort05 " ),
6 => $outputlangs -> trans ( " MonthShort06 " ),
7 => $outputlangs -> trans ( " MonthShort07 " ),
8 => $outputlangs -> trans ( " MonthShort08 " ),
9 => $outputlangs -> trans ( " MonthShort09 " ),
10 => $outputlangs -> trans ( " MonthShort10 " ),
11 => $outputlangs -> trans ( " MonthShort11 " ),
12 => $outputlangs -> trans ( " MonthShort12 " )
2015-03-22 18:17:25 +01:00
);
}
return $montharray ;
2011-08-17 18:07:41 +02:00
}
2020-01-22 15:27:50 +01:00
/**
* Return array of week numbers .
2019-11-21 17:05:06 +01:00
2020-01-22 15:27:50 +01:00
*
* @ param int $month Month number
* @ param int $year Year number
* @ return array Week numbers
*/
2020-01-31 11:26:33 +01:00
function getWeekNumbersOfMonth ( $month , $year )
{
$nb_days = cal_days_in_month ( CAL_GREGORIAN , $month , $year );
2020-01-22 15:27:50 +01:00
$TWeek = array ();
2020-04-10 10:59:32 +02:00
for ( $day = 1 ; $day < $nb_days ; $day ++ ) {
2020-01-22 15:27:50 +01:00
$week_number = getWeekNumber ( $day , $month , $year );
$TWeek [ $week_number ] = $week_number ;
}
return $TWeek ;
}
/**
* Return array of first day of weeks .
2019-11-21 17:05:06 +01:00
2020-01-22 15:27:50 +01:00
*
* @ param array $TWeek array of week numbers
* @ param int $year Year number
* @ return array First day of week
*/
2020-01-31 11:26:33 +01:00
function getFirstDayOfEachWeek ( $TWeek , $year )
{
2020-01-22 15:27:50 +01:00
$TFirstDayOfWeek = array ();
2020-04-10 10:59:32 +02:00
foreach ( $TWeek as $weekNb ) {
if ( in_array ( '01' , $TWeek ) && in_array ( '52' , $TWeek ) && $weekNb == '01' ) $year ++ ; //Si on a la 1re semaine et la semaine 52 c'est qu'on change d'année
2020-01-31 11:26:33 +01:00
$TFirstDayOfWeek [ $weekNb ] = date ( 'd' , strtotime ( $year . 'W' . $weekNb ));
2020-01-22 15:27:50 +01:00
}
return $TFirstDayOfWeek ;
}
/**
* Return array of last day of weeks .
2019-11-21 17:05:06 +01:00
2020-01-22 15:27:50 +01:00
*
* @ param array $TWeek array of week numbers
* @ param int $year Year number
* @ return array Last day of week
*/
2020-01-31 11:26:33 +01:00
function getLastDayOfEachWeek ( $TWeek , $year )
{
2020-01-22 15:27:50 +01:00
$TLastDayOfWeek = array ();
2020-04-10 10:59:32 +02:00
foreach ( $TWeek as $weekNb ) {
2020-01-31 11:26:33 +01:00
$TLastDayOfWeek [ $weekNb ] = date ( 'd' , strtotime ( $year . 'W' . $weekNb . '+6 days' ));
2020-01-22 15:27:50 +01:00
}
return $TLastDayOfWeek ;
}
/**
* Return week number .
2019-11-21 17:05:06 +01:00
2020-01-22 15:27:50 +01:00
*
* @ param int $day Day number
* @ param int $month Month number
* @ param int $year Year number
* @ return int Week number
*/
2020-01-31 11:26:33 +01:00
function getWeekNumber ( $day , $month , $year )
{
2020-01-22 15:27:50 +01:00
$date = new DateTime ( $year . '-' . $month . '-' . $day );
$week = $date -> format ( " W " );
return $week ;
}