2008-08-29 22:18:28 +02:00
< ? php
2024-05-21 17:08:29 +02:00
/* Copyright ( C ) 2004 - 2011 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2005 - 2011 Regis Houssin < regis . houssin @ inodbox . com >
* Copyright ( C ) 2011 - 2015 Juanjo Menent < jmenent @ 2 byte . es >
* Copyright ( C ) 2017 Ferran Marcet < fmarcet @ 2 byte . es >
* Copyright ( C ) 2018 - 2024 Charlene Benke < charlene @ patas - monkey . com >
2025-02-08 21:53:48 +01:00
* Copyright ( C ) 2024 - 2025 MDW < mdeweerd @ users . noreply . github . com >
2024-05-21 17:08:29 +02:00
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2024-05-21 17:06:26 +02:00
*
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
*
2024-09-29 21:52:31 +02:00
* @ return array < int <- 11 , 13 > , string > Array with timezone values
2011-06-10 22:31:10 +02:00
*/
function get_tz_array ()
{
2020-10-31 14:32:18 +01:00
$tzarray = array (
2024-10-03 15:38:41 +02:00
- 11 => " Pacific/Pago_Pago " ,
- 10 => " Pacific/Honolulu " ,
2024-03-17 18:19:10 +01:00
- 9 => " America/Anchorage " ,
- 8 => " America/Los_Angeles " ,
- 7 => " America/Dawson_Creek " ,
- 6 => " America/Chicago " ,
- 5 => " America/Bogota " ,
2024-10-03 15:38:41 +02:00
- 4 => " America/Asuncion " ,
2024-03-17 18:19:10 +01:00
- 3 => " America/Araguaina " ,
- 2 => " America/Noronha " ,
- 1 => " Atlantic/Azores " ,
2024-10-03 15:38:41 +02:00
0 => " Europe/London " ,
2024-03-17 18:19:10 +01:00
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 " ,
2024-10-03 15:38:41 +02:00
13 => " Pacific/Fakaofo " ,
14 => " Pacific/Kiritimati "
2020-10-31 14:32:18 +01:00
);
return $tzarray ;
2011-06-10 22:31:10 +02:00
}
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
{
2020-10-31 14:32:18 +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' )
2020-11-21 16:49:54 +01:00
* @ return float An offset in hour ( + 1 for Europe / Paris on winter and + 2 for Europe / Paris on summer ) . Note some countries use half and even quarter hours .
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
{
2021-02-23 22:03:23 +01:00
if ( method_exists ( 'DateTimeZone' , 'getOffset' )) {
2020-10-31 14:32:18 +01:00
// Method 1 (include daylight)
2021-03-01 20:37:16 +01:00
$gmtnow = dol_now ( 'gmt' );
$yearref = dol_print_date ( $gmtnow , '%Y' );
$monthref = dol_print_date ( $gmtnow , '%m' );
$dayref = dol_print_date ( $gmtnow , '%d' );
2021-02-23 22:03:23 +01:00
if ( $refgmtdate == 'now' ) {
$newrefgmtdate = $yearref . '-' . $monthref . '-' . $dayref ;
} elseif ( $refgmtdate == 'summer' ) {
$newrefgmtdate = $yearref . '-08-01' ;
} else {
$newrefgmtdate = $yearref . '-01-01' ;
}
2020-10-31 14:32:18 +01:00
$newrefgmtdate .= 'T00:00:00+00:00' ;
$localtz = new DateTimeZone ( getServerTimeZoneString ());
$localdt = new DateTime ( $newrefgmtdate , $localtz );
$tmp = - 1 * $localtz -> getOffset ( $localdt );
//print $refgmtdate.'='.$tmp;
} else {
$tmp = 0 ;
2024-01-20 09:22:38 +01:00
dol_print_error ( null , 'PHP version must be 5.3+' );
2020-10-31 14:32:18 +01:00
}
$tz = round (( $tmp < 0 ? 1 : - 1 ) * abs ( $tmp / 3600 ));
return $tz ;
2011-11-01 04:57:45 +01:00
}
2010-10-02 01:37:36 +02:00
/**
* Add a delay to a date
2011-09-16 19:19:24 +02:00
*
2024-10-25 14:18:17 +02:00
* @ param int | string $time Date timestamp ( or string with format YYYY - MM - DD )
2024-10-24 14:01:30 +02:00
* @ param float $duration_value Value of delay to add
2024-02-13 08:51:46 +01:00
* @ param string $duration_unit Unit of added delay ( d , m , y , w , h , i )
2024-11-04 12:32:13 +01:00
* @ param int < 0 , 1 > $ruleforendofmonth Change the behavior of PHP over data - interval , 0 or 1
2014-09-05 13:48:55 +02:00
* @ return int New timestamp
2023-01-13 17:17:23 +01:00
* @ see convertSecondToTime (), convertTimeToSeconds ()
2010-10-02 01:37:36 +02:00
*/
2021-10-20 00:36:24 +02:00
function dol_time_plus_duree ( $time , $duration_value , $duration_unit , $ruleforendofmonth = 0 )
2010-10-02 01:37:36 +02:00
{
2023-12-28 12:42:15 +01:00
if ( empty ( $duration_value )) {
2023-12-28 10:49:45 +01:00
return $time ;
}
2022-09-15 18:02:24 +02:00
if ( $duration_unit == 's' ) {
2024-10-24 14:01:30 +02:00
return $time + ( int ) ( $duration_value );
2022-09-15 18:02:24 +02:00
}
2024-11-10 18:23:17 +01:00
if ( $duration_unit == 'i' || $duration_unit == 'mn' || $duration_unit == 'min' ) {
2024-10-24 14:01:30 +02:00
return $time + ( int ) ( 60 * $duration_value );
2021-02-23 22:03:23 +01:00
}
if ( $duration_unit == 'h' ) {
2024-10-24 14:01:30 +02:00
return $time + ( int ) ( 3600 * $duration_value );
2021-02-23 22:03:23 +01:00
}
if ( $duration_unit == 'w' ) {
2024-10-24 14:01:30 +02:00
return $time + ( int ) ( 3600 * 24 * 7 * $duration_value );
2021-02-23 22:03:23 +01:00
}
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
2024-11-04 12:32:13 +01:00
$sub = false ;
2021-02-23 22:03:23 +01:00
if ( $duration_value > 0 ) {
2021-03-01 20:37:16 +01:00
$deltastring .= abs ( $duration_value );
$sub = false ;
2021-02-23 22:03:23 +01:00
}
if ( $duration_value < 0 ) {
2021-03-01 20:37:16 +01:00
$deltastring .= abs ( $duration_value );
$sub = true ;
2021-02-23 22:03:23 +01:00
}
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 ();
2023-11-27 11:39:32 +01:00
if ( getDolGlobalString ( 'MAIN_DATE_IN_MEMORY_ARE_GMT' )) {
2021-02-23 22:03:23 +01:00
$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
2021-02-23 22:03:23 +01:00
if ( $sub ) {
$date -> sub ( $interval );
} else {
$date -> add ( $interval );
}
2022-10-18 19:49:02 +02:00
//Change the behavior of PHP over data-interval when the result of this function is Feb 29 (non-leap years), 30 or Feb 31 (so php returns March 1, 2 or 3 respectively)
2021-10-20 00:36:24 +02:00
if ( $ruleforendofmonth == 1 && $duration_unit == 'm' ) {
2024-03-22 00:53:38 +01:00
$timeyear = ( int ) dol_print_date ( $time , '%Y' );
$timemonth = ( int ) dol_print_date ( $time , '%m' );
2021-09-22 18:07:36 +02:00
$timetotalmonths = (( $timeyear * 12 ) + $timemonth );
2017-09-11 02:09:48 +02:00
2021-09-22 18:07:36 +02:00
$monthsexpected = ( $timetotalmonths + $duration_value );
$newtime = $date -> getTimestamp ();
2024-03-22 00:53:38 +01:00
$newtimeyear = ( int ) dol_print_date ( $newtime , '%Y' );
$newtimemonth = ( int ) dol_print_date ( $newtime , '%m' );
$newtimetotalmonths = (( $newtimeyear * 12 ) + $newtimemonth );
2021-09-22 18:07:36 +02:00
if ( $monthsexpected < $newtimetotalmonths ) {
2024-03-22 00:53:38 +01:00
$newtimehours = ( int ) dol_print_date ( $newtime , '%H' );
$newtimemins = ( int ) dol_print_date ( $newtime , '%M' );
$newtimesecs = ( int ) dol_print_date ( $newtime , '%S' );
2021-09-22 18:07:36 +02:00
$datelim = dol_mktime ( $newtimehours , $newtimemins , $newtimesecs , $newtimemonth , 1 , $newtimeyear );
$datelim -= ( 3600 * 24 );
$date -> setTimestamp ( $datelim );
}
2021-09-22 17:56:31 +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
{
2022-08-12 17:25:15 +02:00
$iResult = (( int ) $iHours * 3600 ) + (( int ) $iMinutes * 60 ) + ( int ) $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
2024-11-04 12:32:13 +01:00
* @ param 'all' | 'allwithouthour' | 'allhourmin' | 'allhourminsec' | 'allhour' | 'fullhour' | 'hour' | 'min' | 'sec' | 'month' | 'year' $format Output format
* - 'all' : total delay days hour : min like " 2 days 12:30 " ,
* - 'allwithouthour' : total delay days without hour part like " 2 days " ,
* - 'allhourmin' : total delay with format hours : min like " 60:30 " ,
* - 'allhourminsec' : total delay with format hours : min : sec like " 60:30:10 " ,
* - '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 );
* @ param int < 1 , 86400 > $lengthOfDay Length of day ( default 86400 seconds for 1 day , 28800 for 8 hour )
* @ param int < 1 , 7 > $lengthOfWeek Length of week ( default 7 )
2024-01-13 19:48:20 +01:00
* @ return string Formatted 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
2021-02-23 22:03:23 +01:00
if ( empty ( $lengthOfDay )) {
$lengthOfDay = 86400 ; // 1 day = 24 hours
}
if ( empty ( $lengthOfWeek )) {
$lengthOfWeek = 7 ; // 1 week = 7 days
}
2022-08-12 17:23:41 +02:00
$nbHbyDay = $lengthOfDay / 3600 ;
2008-11-05 20:46:09 +01:00
2024-11-04 12:32:13 +01:00
$sTime = '' ;
2021-02-23 22:03:23 +01:00
if ( $format == 'all' || $format == 'allwithouthour' || $format == 'allhour' || $format == 'allhourmin' || $format == 'allhourminsec' ) {
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-10-31 14:32:18 +01:00
$sDay = 0 ;
$sWeek = 0 ;
2011-02-19 15:14:05 +01:00
2021-02-23 22:03:23 +01:00
if ( $iSecond >= $lengthOfDay ) {
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 " );
2021-02-23 22:03:23 +01: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
2021-02-23 22:03:23 +01:00
if ( $lengthOfWeek < 7 ) {
if ( $sDay ) {
if ( $sDay >= $lengthOfWeek ) {
2020-10-31 14:32:18 +01:00
$sWeek = ( int ) (( $sDay - $sDay % $lengthOfWeek ) / $lengthOfWeek );
2024-08-07 02:53:45 +02:00
$sDay %= $lengthOfWeek ;
2020-10-31 14:32:18 +01:00
$weekTranslate = $langs -> trans ( " DurationWeek " );
2021-02-23 22:03:23 +01:00
if ( $sWeek >= 2 ) {
$weekTranslate = $langs -> trans ( " DurationWeeks " );
}
2020-10-31 14:32:18 +01:00
$sTime .= $sWeek . ' ' . $weekTranslate . ' ' ;
}
}
2011-02-19 15:14:05 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $sDay > 0 ) {
2012-06-10 12:42:19 +02:00
$dayTranslate = $langs -> trans ( " Day " );
2021-02-23 22:03:23 +01:00
if ( $sDay > 1 ) {
$dayTranslate = $langs -> trans ( " Days " );
}
2023-02-16 22:11:41 +01:00
$sTime .= $sDay . ' ' . $langs -> trans ( " d " ) . ' ' ;
2012-06-10 12:42:19 +02:00
}
2011-02-19 15:14:05 +01:00
2021-02-23 22:03:23 +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
}
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'allhourminsec' ) {
2024-03-17 18:19:10 +01:00
return sprintf ( " %02d " , ( $sWeek * $lengthOfWeek * $nbHbyDay + $sDay * $nbHbyDay + ( int ) floor ( $iSecond / 3600 ))) . ':' . sprintf ( " %02d " , (( int ) floor (( $iSecond % 3600 ) / 60 ))) . ':' . sprintf ( " %02d " , (( int ) ( $iSecond % 60 )));
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'allhourmin' ) {
2024-03-17 18:19:10 +01:00
return sprintf ( " %02d " , ( $sWeek * $lengthOfWeek * $nbHbyDay + $sDay * $nbHbyDay + ( int ) floor ( $iSecond / 3600 ))) . ':' . sprintf ( " %02d " , (( int ) floor (( $iSecond % 3600 ) / 60 )));
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'allhour' ) {
2024-03-17 18:19:10 +01:00
return sprintf ( " %02d " , ( $sWeek * $lengthOfWeek * $nbHbyDay + $sDay * $nbHbyDay + ( int ) floor ( $iSecond / 3600 )));
2009-10-29 08:53:33 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'hour' ) { // only hour part
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%H' , true );
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'fullhour' ) {
2013-05-15 14:19:16 +02:00
if ( ! empty ( $iSecond )) {
2024-08-07 02:53:45 +02:00
$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 ;
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'min' ) { // only min part
2020-04-10 10:59:32 +02:00
$sTime = dol_print_date ( $iSecond , '%M' , true );
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'sec' ) { // only sec part
2020-10-31 14:32:18 +01:00
$sTime = dol_print_date ( $iSecond , '%S' , true );
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'month' ) { // only month part
2020-10-31 14:32:18 +01:00
$sTime = dol_print_date ( $iSecond , '%m' , true );
2021-02-23 22:03:23 +01:00
} elseif ( $format == 'year' ) { // only year part
2020-10-31 14:32:18 +01:00
$sTime = dol_print_date ( $iSecond , '%Y' , true );
}
2024-11-04 12:32:13 +01:00
return trim (( string ) $sTime );
2008-08-29 22:18:28 +02:00
}
2022-07-12 10:03:31 +02:00
/** Convert duration to hour
*
2024-10-24 14:01:30 +02:00
* @ param float $duration_value Duration value
2024-02-13 08:51:46 +01:00
* @ param string $duration_unit Duration unit
2024-10-24 14:01:30 +02:00
* @ return float $result
2024-11-11 14:36:19 +01:00
* @ see measuringUnitString ()
2022-07-12 10:03:31 +02:00
*/
function convertDurationtoHour ( $duration_value , $duration_unit )
{
$result = 0 ;
2023-12-04 12:05:28 +01:00
if ( $duration_unit == 's' ) {
$result = $duration_value / 3600 ;
}
2024-11-10 18:23:17 +01:00
if ( $duration_unit == 'i' || $duration_unit == 'mn' || $duration_unit == 'min' ) {
2023-12-04 12:05:28 +01:00
$result = $duration_value / 60 ;
}
if ( $duration_unit == 'h' ) {
$result = $duration_value ;
}
if ( $duration_unit == 'd' ) {
$result = $duration_value * 24 ;
}
if ( $duration_unit == 'w' ) {
$result = $duration_value * 24 * 7 ;
}
if ( $duration_unit == 'm' ) {
$result = $duration_value * 730.484 ;
}
if ( $duration_unit == 'y' ) {
$result = $duration_value * 365 * 24 ;
}
2022-07-12 10:03:31 +02:00
return $result ;
}
2018-12-01 00:41:46 +01:00
/**
2021-06-20 16:55:22 +02:00
* Generate a SQL string to make a filter into a range ( for second of date until last second of date ) .
* This method allows to maje SQL request that will deal correctly the timezone of server .
2018-12-01 00:41:46 +01:00
*
2022-06-14 14:39:32 +02:00
* @ param string $datefield Name of SQL field where apply sql date filter
* @ param int | string $day_date Day date ( Can be 0 or '' for filter on a month )
* @ param int | string $month_date Month date ( Can be 0 or '' for filter on a year )
* @ param int | string $year_date Year date
* @ param int $excludefirstand Exclude first and
2025-02-08 21:53:48 +01:00
* @ param bool | int < 0 , 1 >| 'gmt' | 'tzserver' | 'tzref' | 'tzuser' | 'tzuserrel' $gm False or 0 or 'tzserver' = Input date fields are date info in the server TZ . True or 1 or 'gmt' = Input are date info in GMT TZ .
* Note : In database , dates are always for the server TZ .
2022-06-14 14:39:32 +02:00
* @ return string $sqldate String with SQL filter
2024-01-15 11:28:25 +01:00
* @ see forgeSQLFromUniversalSearchCriteria ()
2024-02-17 04:07:34 +01:00
* @ see natural_search ()
2018-12-01 00:41:46 +01:00
*/
2021-06-20 16:55:22 +02:00
function dolSqlDateFilter ( $datefield , $day_date , $month_date , $year_date , $excludefirstand = 0 , $gm = false )
2018-12-14 19:21:19 +01:00
{
2018-12-01 00:41:46 +01:00
global $db ;
2022-06-14 14:39:32 +02:00
$sqldate = '' ;
$day_date = intval ( $day_date );
$month_date = intval ( $month_date );
$year_date = intval ( $year_date );
2018-12-01 00:41:46 +01:00
if ( $month_date > 0 ) {
2022-06-14 14:39:32 +02:00
if ( $month_date > 12 ) { // protection for bad value of month
return " AND 1 = 2 " ;
}
2018-12-01 00:41:46 +01:00
if ( $year_date > 0 && empty ( $day_date )) {
2021-06-20 16:55:22 +02:00
$sqldate .= ( $excludefirstand ? " " : " AND " ) . $datefield . " BETWEEN ' " . $db -> idate ( dol_get_first_day ( $year_date , $month_date , $gm ));
$sqldate .= " ' AND ' " . $db -> idate ( dol_get_last_day ( $year_date , $month_date , $gm )) . " ' " ;
2020-04-10 10:59:32 +02:00
} elseif ( $year_date > 0 && ! empty ( $day_date )) {
2021-06-20 16:55:22 +02:00
$sqldate .= ( $excludefirstand ? " " : " AND " ) . $datefield . " BETWEEN ' " . $db -> idate ( dol_mktime ( 0 , 0 , 0 , $month_date , $day_date , $year_date , $gm ));
$sqldate .= " ' AND ' " . $db -> idate ( dol_mktime ( 23 , 59 , 59 , $month_date , $day_date , $year_date , $gm )) . " ' " ;
2021-02-23 22:03:23 +01:00
} else {
2021-06-20 16:55:22 +02:00
// This case is not reliable on TZ, but we should not need it.
2021-02-23 22:03:23 +01:00
$sqldate .= ( $excludefirstand ? " " : " AND " ) . " date_format( " . $datefield . " , '%c') = ' " . $db -> escape ( $month_date ) . " ' " ;
}
2020-04-10 10:59:32 +02:00
} elseif ( $year_date > 0 ) {
2021-06-20 16:55:22 +02:00
$sqldate .= ( $excludefirstand ? " " : " AND " ) . $datefield . " BETWEEN ' " . $db -> idate ( dol_get_first_day ( $year_date , 1 , $gm ));
$sqldate .= " ' AND ' " . $db -> idate ( dol_get_last_day ( $year_date , 12 , $gm )) . " ' " ;
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
*
2022-02-11 14:07:10 +01:00
* @ param string $string Date in a string
* YYYYMMDD
* YYYYMMDDHHMMSS
* YYYYMMDDTHHMMSSZ
* YYYY - MM - DDTHH : MM : SSZ ( RFC3339 )
* DD / MM / YY or DD / MM / YYYY ( deprecated )
* DD / MM / YY HH : MM : SS or DD / MM / YYYY HH : MM : SS ( deprecated )
2025-02-08 21:53:48 +01:00
* @ param int < 0 , 1 >| 'gmt' | 'tzserver' | 'tzref' | 'tzuser' | 'tzuserrel' | 'dayrfc' $gm 'gmt' or 1 = Input date is GM date ,
* 'tzserver' or 0 = Input date is date using PHP server timezone
2022-02-11 14:07:10 +01:00
* @ return int Date as a timestamp
* 19700101020000 -> 7200 with gm = 1
* 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 ();
2020-10-31 14:32:18 +01:00
// Convert date with format DD/MM/YYY HH:MM:SS. This part of code should not be used.
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/^([0-9]+)\/([0-9]+)\/([0-9]+)\s?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i' , $string , $reg )) {
2020-10-31 14:32:18 +01:00
dol_syslog ( " dol_stringtotime call to function with deprecated parameter format " , LOG_WARNING );
// 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'
2024-03-17 18:19:10 +01:00
$sday = ( int ) $reg [ 1 ];
$smonth = ( int ) $reg [ 2 ];
$syear = ( int ) $reg [ 3 ];
$shour = ( int ) $reg [ 4 ];
$smin = ( int ) $reg [ 5 ];
$ssec = ( int ) $reg [ 6 ];
2021-02-23 22:03:23 +01:00
if ( $syear < 50 ) {
$syear += 1900 ;
}
if ( $syear >= 50 && $syear < 100 ) {
$syear += 2000 ;
}
2020-10-31 14:32:18 +01:00
$string = sprintf ( " %04d%02d%02d%02d%02d%02d " , $syear , $smonth , $sday , $shour , $smin , $ssec );
2021-02-23 22:03:23 +01:00
} elseif ( 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)
2020-10-31 14:32:18 +01:00
|| 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
2021-02-23 22:03:23 +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 YYYYMMDDTHHMMSSZ
) {
2024-03-17 18:19:10 +01:00
$syear = ( int ) $reg [ 1 ];
$smonth = ( int ) $reg [ 2 ];
$sday = ( int ) $reg [ 3 ];
$shour = ( int ) $reg [ 4 ];
$smin = ( int ) $reg [ 5 ];
$ssec = ( int ) $reg [ 6 ];
2020-10-31 14:32:18 +01:00
$string = sprintf ( " %04d%02d%02d%02d%02d%02d " , $syear , $smonth , $sday , $shour , $smin , $ssec );
}
$string = preg_replace ( '/([^0-9])/i' , '' , $string );
$tmp = $string . '000000' ;
2022-02-11 14:07:10 +01:00
// Clean $gm
if ( $gm === 1 ) {
$gm = 'gmt' ;
} elseif ( empty ( $gm ) || $gm === 'tzserver' ) {
$gm = 'tzserver' ;
}
2024-08-16 20:13:02 +02:00
$date = dol_mktime (( int ) substr ( $tmp , 8 , 2 ), ( int ) substr ( $tmp , 10 , 2 ), ( int ) substr ( $tmp , 12 , 2 ), ( int ) substr ( $tmp , 4 , 2 ), ( int ) substr ( $tmp , 6 , 2 ), ( int ) substr ( $tmp , 0 , 4 ), $gm );
2020-10-31 14:32:18 +01:00
return $date ;
2012-01-21 14:10:22 +01:00
}
2021-01-28 09:59:13 +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
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int , day : int } 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
}
2021-01-28 09:59:13 +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
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int , day : int } 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
}
2021-01-28 09:59:13 +01:00
/**
* Return previous month
2011-09-16 19:19:24 +02:00
*
* @ param int $month Month
* @ param int $year Year
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int } Previous year , month
2008-08-29 22:18:28 +02:00
*/
function dol_get_prev_month ( $month , $year )
{
2021-02-23 22:03:23 +01:00
if ( $month == 1 ) {
2008-08-29 22:18:28 +02:00
$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 );
}
2021-01-28 09:59:13 +01:00
/**
* Return next month
2011-09-16 19:19:24 +02:00
*
* @ param int $month Month
* @ param int $year Year
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int } 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
{
2021-02-23 22:03:23 +01:00
if ( $month == 12 ) {
2008-08-29 22:18:28 +02:00
$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 );
}
2021-01-28 09:59:13 +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
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int , day : int } 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
2021-01-28 09:59:13 +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
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int , day : int } 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
2021-01-28 09:59:13 +01:00
/**
* Return GMT time for first day of a month or year
2011-09-16 19:19:24 +02:00
*
2025-02-08 21:53:48 +01:00
* @ param int $year Year
* @ param int $month Month
* @ param bool | int < 0 , 1 >| 'gmt' | 'tzserver' | 'tzref' | 'tzuser' | 'tzuserrel' $gm False or 0 or 'tzserver' = Return date to compare with server TZ ,
* True or 1 or 'gmt' to compare with GMT date .
* Example : 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
* Example : 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
2024-01-15 20:56:59 +01:00
* @ return int | string Date as a timestamp , '' 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
{
2021-02-23 22:03:23 +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
}
2021-01-28 09:59:13 +01:00
/**
* Return GMT time for last day of a month or year .
* Note : The timestamp contains last day and last hours ( 23 : 59 : 59 )
2011-09-16 19:19:24 +02:00
*
* @ param int $year Year
* @ param int $month Month
2025-02-08 21:53:48 +01:00
* @ param bool | int < 0 , 1 >| 'gmt' | 'tzserver' | 'tzref' | 'tzuser' | 'tzuserrel' $gm False or 0 or 'tzserver' = Return date to compare with server TZ ,
* True or 1 or 'gmt' to compare with GMT date .
2024-01-15 20:56:59 +01:00
* @ return int | string Date as a timestamp , '' 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
{
2021-02-23 22:03:23 +01:00
if ( $year > 9999 ) {
return '' ;
}
if ( $month == 12 ) {
2009-12-03 20:25:35 +01:00
$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
}
2021-01-28 09:59:13 +01:00
/**
2021-01-31 12:48:40 +01:00
* Return GMT time for last hour of a given GMT date ( it replaces hours , min and second part to 23 : 59 : 59 )
2020-09-22 14:45:19 +02:00
*
2021-01-31 12:48:40 +01:00
* @ param int $date Date GMT
2024-02-13 08:51:46 +01:00
* @ param bool | int | string $gm False or 0 or 'tzserver' = Return date to compare with server TZ ,
2021-04-19 12:48:08 +02:00
* 'gmt' to compare with GMT date .
2020-09-22 14:45:19 +02:00
* @ return int Date for last hour of a given date
*/
2021-03-04 10:31:31 +01:00
function dol_get_last_hour ( $date , $gm = 'tzserver' )
2020-09-22 14:45:19 +02:00
{
2021-04-19 12:48:08 +02:00
$tmparray = dol_getdate ( $date , false , ( $gm == 'gmt' ? 'gmt' : '' ));
2021-03-04 10:31:31 +01:00
return dol_mktime ( 23 , 59 , 59 , $tmparray [ 'mon' ], $tmparray [ 'mday' ], $tmparray [ 'year' ], $gm );
2020-09-22 14:45:19 +02:00
}
2021-01-28 09:59:13 +01:00
/**
* Return GMT time for first hour of a given GMT date ( it removes hours , min and second part )
2020-09-22 14:45:19 +02:00
*
2021-03-05 19:29:09 +01:00
* @ param int $date Date GMT
2024-02-13 08:51:46 +01:00
* @ param bool | int | string $gm False or 0 or 'tzserver' = Return date to compare with server TZ ,
2021-04-19 12:48:08 +02:00
* 'gmt' to compare with GMT date .
2024-01-26 10:35:25 +01:00
* @ return int Date for first hour of a given date
2020-09-22 14:45:19 +02:00
*/
2021-03-04 10:31:31 +01:00
function dol_get_first_hour ( $date , $gm = 'tzserver' )
2020-09-22 14:45:19 +02:00
{
2021-04-19 12:48:08 +02:00
$tmparray = dol_getdate ( $date , false , ( $gm == 'gmt' ? 'gmt' : '' ));
2021-03-04 10:31:31 +01:00
return dol_mktime ( 0 , 0 , 0 , $tmparray [ 'mon' ], $tmparray [ 'mday' ], $tmparray [ 'year' ], $gm );
2020-09-22 14:45:19 +02:00
}
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
*
2025-02-08 21:53:48 +01:00
* @ param int $day Day
* @ param int $month Month
* @ param int $year Year
* @ param bool | int < 0 , 1 >| 'gmt' | 'tzserver' | 'tzref' | 'tzuser' | 'tzuserrel' $gm False or 0 or 'tzserver' = Return date to compare with server TZ ,
* True or 1 or 'gmt' to compare with GMT date .
2024-09-29 21:52:31 +02:00
* @ return array { year : int , month : int , week : string , first_day : int , first_month : int , first_year : int , prev_year : int , prev_month : int , prev_day : int }
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' ];
2021-02-23 22:03:23 +01:00
if ( $days >= 1 ) {
$days = 7 - $days ;
}
$days = abs ( $days );
2020-10-31 14:32:18 +01: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
2020-10-31 14:32:18 +01:00
//Get first day of week
2024-03-25 22:15:57 +01:00
$tmpdaytms = ( int ) date (( string ) $tmparray [ '0' ]) - $seconds ; // $tmparray[0] is day of parameters
$tmpday = idate ( " 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
2021-02-23 22:03:23 +01:00
if ( $tmpday > $day ) {
2020-10-31 14:32:18 +01:00
$prev_month = $month - 1 ;
2020-04-10 10:59:32 +02:00
$prev_year = $year ;
2011-05-25 15:27:07 +02:00
2021-02-23 22:03:23 +01:00
if ( $prev_month == 0 ) {
2020-10-31 14:32:18 +01:00
$prev_month = 12 ;
$prev_year = $year - 1 ;
}
} else {
$prev_month = $month ;
2020-04-10 10:59:32 +02:00
$prev_year = $year ;
2020-10-31 14:32:18 +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 );
2020-10-31 14:32:18 +01:00
$prev_day = $tmparray [ 'mday' ];
2011-05-25 15:27:07 +02:00
2020-10-31 14:32:18 +01:00
//Check prev day of week is in same month than first day or not
2021-02-23 22:03:23 +01:00
if ( $prev_day > $tmpday ) {
2020-10-31 14:32:18 +01:00
$prev_month = $month - 1 ;
2020-04-10 10:59:32 +02:00
$prev_year = $year ;
2011-05-25 15:27:07 +02:00
2021-02-23 22:03:23 +01:00
if ( $prev_month == 0 ) {
2020-10-31 14:32:18 +01:00
$prev_month = 12 ;
$prev_year = $year - 1 ;
}
}
2011-05-25 15:27:07 +02:00
2020-10-31 14:32:18 +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
2020-12-05 17:41:05 +01:00
/**
2020-12-06 18:01:23 +01:00
* Return the easter day in GMT time .
2020-12-05 17:41:05 +01:00
* This function replaces easter_date () that returns a date in local TZ .
*
* @ param int $year Year
2020-12-06 18:01:23 +01:00
* @ return int GMT Date of easter day
2020-12-05 17:41:05 +01:00
*/
2020-12-06 18:01:23 +01:00
function getGMTEasterDatetime ( $year )
{
2021-02-28 22:44:11 +01:00
$base = new DateTime ( " $year -03-21 " , new DateTimeZone ( " UTC " ));
2021-10-25 22:07:31 +02:00
$days = easter_days ( $year ); // Return number of days between 21 march and easter day.
2020-12-05 17:41:05 +01:00
$tmp = $base -> add ( new DateInterval ( " P { $days } D " ));
return $tmp -> getTimestamp ();
}
2008-08-29 22:18:28 +02:00
/**
2021-04-05 21:05:22 +02:00
* Return the number of non working days including Friday , Saturday and Sunday ( or not ) between 2 dates in timestamp .
2021-02-28 22:44:11 +01:00
* Dates must be UTC with hour , min , sec to 0.
2021-04-05 18:57:33 +02:00
* Called by function num_open_day ()
2011-09-16 19:19:24 +02:00
*
2021-04-05 18:57:33 +02:00
* @ param int $timestampStart Timestamp start ( UTC with hour , min , sec = 0 )
* @ param int $timestampEnd Timestamp end ( UTC with hour , min , sec = 0 )
2021-08-05 14:42:28 +02:00
* @ param string $country_code Country code
* @ param int $lastday Last day is included , 0 : no , 1 : yes
2021-04-05 18:57:33 +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 )
2021-04-09 20:16:24 +02:00
* @ param int $includefriday Include friday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
2021-08-05 14:42:28 +02:00
* @ param int $includemonday Include monday 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
*/
2021-08-05 14:42:28 +02:00
function num_public_holiday ( $timestampStart , $timestampEnd , $country_code = '' , $lastday = 0 , $includesaturday = - 1 , $includesunday = - 1 , $includefriday = - 1 , $includemonday = - 1 )
2008-08-29 22:18:28 +02:00
{
2024-09-23 13:02:43 +02:00
global $conf , $db , $mysoc ;
2018-10-11 13:12:13 +02:00
2008-08-29 22:18:28 +02:00
$nbFerie = 0 ;
2014-03-05 21:29:33 +01:00
// Check to ensure we use correct parameters
2023-12-27 12:12:20 +01:00
if (( $timestampEnd - $timestampStart ) % 86400 != 0 ) {
2021-02-23 22:03:23 +01:00
return 'Error Dates must use same hours and must be GMT dates' ;
}
2014-03-05 21:29:33 +01:00
2021-02-23 22:03:23 +01:00
if ( empty ( $country_code )) {
$country_code = $mysoc -> country_code ;
}
2021-08-05 14:42:28 +02:00
if ( $includemonday < 0 ) {
2024-05-21 17:06:26 +02:00
$includemonday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY' , 0 );
2021-08-05 14:42:28 +02:00
}
2021-04-05 18:57:33 +02:00
if ( $includefriday < 0 ) {
2024-05-21 17:06:26 +02:00
$includefriday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY' , 0 );
2021-04-05 19:09:25 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $includesaturday < 0 ) {
2024-05-21 17:06:26 +02:00
$includesaturday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY' , 1 );
2021-02-23 22:03:23 +01:00
}
if ( $includesunday < 0 ) {
2024-05-21 17:06:26 +02:00
$includesunday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY' , 1 );
2021-02-23 22:03:23 +01:00
}
2019-09-09 10:27:56 +02:00
2020-12-05 17:41:05 +01:00
$country_id = dol_getIdFromCode ( $db , $country_code , 'c_country' , 'code' , 'rowid' );
2019-09-09 10:27:56 +02:00
2024-09-23 13:02:43 +02:00
if ( empty ( $conf -> cache [ 'arrayOfActivePublicHolidays_' . $country_id ])) {
2020-12-05 17:41:05 +01:00
// Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed
2024-09-23 13:02:43 +02:00
$tmpArrayOfPublicHolidays = array ();
$sql = " SELECT id, 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 ) . " ) " ;
2023-11-16 23:27:20 +01:00
$sql .= " AND entity IN (0, " . getEntity ( 'holiday' ) . " ) " ;
2019-09-09 10:27:56 +02:00
$resql = $db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2019-09-09 10:27:56 +02:00
$num_rows = $db -> num_rows ( $resql );
2020-04-10 10:59:32 +02:00
$i = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num_rows ) {
2019-09-09 10:27:56 +02:00
$obj = $db -> fetch_object ( $resql );
2024-09-23 13:02:43 +02:00
$tmpArrayOfPublicHolidays [ $obj -> id ] = array ( 'dayrule' => $obj -> dayrule , 'year' => $obj -> year , 'month' => $obj -> month , 'day' => $obj -> day );
2019-09-09 10:27:56 +02:00
$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 ();
}
2024-09-23 13:02:43 +02:00
//var_dump($tmpArrayOfPublicHolidays);
$conf -> cache [ 'arrayOfActivePublicHolidays_' . $country_id ] = $tmpArrayOfPublicHolidays ;
}
$arrayOfPublicHolidays = $conf -> cache [ 'arrayOfActivePublicHolidays_' . $country_id ];
$i = 0 ;
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)
$ferie = false ;
$specialdayrule = array ();
$jour = ( int ) gmdate ( " d " , $timestampStart );
$mois = ( int ) gmdate ( " m " , $timestampStart );
$annee = ( int ) gmdate ( " Y " , $timestampStart );
//print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$includesaturday." includesunday=".$includesunday."\n";
foreach ( $arrayOfPublicHolidays as $entrypublicholiday ) {
if ( ! empty ( $entrypublicholiday [ 'dayrule' ]) && $entrypublicholiday [ 'dayrule' ] != 'date' ) { // For example 'easter', '...'
$specialdayrule [ $entrypublicholiday [ 'dayrule' ]] = $entrypublicholiday [ 'dayrule' ];
} else {
$match = 1 ;
if ( ! empty ( $entrypublicholiday [ 'year' ]) && $entrypublicholiday [ 'year' ] != $annee ) {
$match = 0 ;
}
if ( $entrypublicholiday [ 'month' ] != $mois ) {
$match = 0 ;
}
if ( $entrypublicholiday [ 'day' ] != $jour ) {
$match = 0 ;
}
if ( $match ) {
$ferie = true ;
}
}
$i ++ ;
}
2020-12-05 17:41:05 +01:00
//var_dump($specialdayrule)."\n";
//print "ferie=".$ferie."\n";
2008-08-29 22:18:28 +02:00
2020-12-05 17:41:05 +01:00
if ( ! $ferie ) {
// Special dayrules
2021-02-23 22:03:23 +01:00
if ( in_array ( 'easter' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Calculation for easter date
$date_paques = getGMTEasterDatetime ( $annee );
$jour_paques = gmdate ( " d " , $date_paques );
$mois_paques = gmdate ( " m " , $date_paques );
2021-02-23 22:03:23 +01:00
if ( $jour_paques == $jour && $mois_paques == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
// Easter (sunday)
}
2018-04-23 15:14:34 +02:00
2021-02-23 22:03:23 +01:00
if ( in_array ( 'eastermonday' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Calculation for the monday of easter date
$date_paques = getGMTEasterDatetime ( $annee );
2021-02-28 22:44:11 +01:00
//print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." ";
$date_lundi_paques = $date_paques + ( 3600 * 24 );
2020-12-05 17:41:05 +01:00
$jour_lundi_paques = gmdate ( " d " , $date_lundi_paques );
$mois_lundi_paques = gmdate ( " m " , $date_lundi_paques );
2021-02-23 22:03:23 +01:00
if ( $jour_lundi_paques == $jour && $mois_lundi_paques == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
// Easter (monday)
2021-02-28 22:44:11 +01:00
//print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n";
2020-12-05 17:41:05 +01:00
}
2008-08-29 22:18:28 +02:00
2021-04-10 11:22:32 +02:00
//Good Friday
if ( in_array ( 'goodfriday' , $specialdayrule )) {
// Pulls the date of Easter
$easter = getGMTEasterDatetime ( $annee );
// Calculates the date of Good Friday based on Easter
$date_good_friday = $easter - ( 2 * 3600 * 24 );
$dom_good_friday = gmdate ( " d " , $date_good_friday );
$month_good_friday = gmdate ( " m " , $date_good_friday );
if ( $dom_good_friday == $jour && $month_good_friday == $mois ) {
$ferie = true ;
}
}
2021-02-23 22:03:23 +01:00
if ( in_array ( 'ascension' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Calcul du jour de l'ascension (39 days after easter day)
$date_paques = getGMTEasterDatetime ( $annee );
2021-02-28 22:44:11 +01:00
$date_ascension = $date_paques + ( 3600 * 24 * 39 );
2020-12-05 17:41:05 +01:00
$jour_ascension = gmdate ( " d " , $date_ascension );
$mois_ascension = gmdate ( " m " , $date_ascension );
2021-02-23 22:03:23 +01:00
if ( $jour_ascension == $jour && $mois_ascension == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
// Ascension (thursday)
}
2014-09-05 13:48:55 +02:00
2024-05-21 17:08:29 +02:00
if ( in_array ( 'pentecost' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Calculation of "Pentecote" (49 days after easter day)
$date_paques = getGMTEasterDatetime ( $annee );
2021-02-28 22:44:11 +01:00
$date_pentecote = $date_paques + ( 3600 * 24 * 49 );
2020-12-05 17:41:05 +01:00
$jour_pentecote = gmdate ( " d " , $date_pentecote );
$mois_pentecote = gmdate ( " m " , $date_pentecote );
2021-02-23 22:03:23 +01:00
if ( $jour_pentecote == $jour && $mois_pentecote == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
// "Pentecote" (sunday)
}
2021-02-23 22:03:23 +01:00
if ( in_array ( 'pentecotemonday' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Calculation of "Pentecote" (49 days after easter day)
$date_paques = getGMTEasterDatetime ( $annee );
2021-02-28 22:44:11 +01:00
$date_pentecote = $date_paques + ( 3600 * 24 * 50 );
2020-12-05 17:41:05 +01:00
$jour_pentecote = gmdate ( " d " , $date_pentecote );
$mois_pentecote = gmdate ( " m " , $date_pentecote );
2021-02-23 22:03:23 +01:00
if ( $jour_pentecote == $jour && $mois_pentecote == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
// "Pentecote" (monday)
}
2008-08-29 22:18:28 +02:00
2021-02-23 22:03:23 +01:00
if ( in_array ( 'viernessanto' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Viernes Santo
$date_paques = getGMTEasterDatetime ( $annee );
2021-02-28 22:44:11 +01:00
$date_viernes = $date_paques - ( 3600 * 24 * 2 );
2020-12-05 17:41:05 +01:00
$jour_viernes = gmdate ( " d " , $date_viernes );
$mois_viernes = gmdate ( " m " , $date_viernes );
2021-02-23 22:03:23 +01:00
if ( $jour_viernes == $jour && $mois_viernes == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
//Viernes Santo
}
2008-08-29 22:18:28 +02:00
2021-02-23 22:03:23 +01:00
if ( in_array ( 'fronleichnam' , $specialdayrule )) {
2020-12-05 17:41:05 +01:00
// Fronleichnam (60 days after easter sunday)
$date_paques = getGMTEasterDatetime ( $annee );
2021-02-28 22:44:11 +01:00
$date_fronleichnam = $date_paques + ( 3600 * 24 * 60 );
2020-12-05 17:41:05 +01:00
$jour_fronleichnam = gmdate ( " d " , $date_fronleichnam );
$mois_fronleichnam = gmdate ( " m " , $date_fronleichnam );
2021-02-23 22:03:23 +01:00
if ( $jour_fronleichnam == $jour && $mois_fronleichnam == $mois ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
// Fronleichnam
2019-09-09 10:27:56 +02:00
}
2022-08-12 17:23:41 +02:00
if ( in_array ( 'genevafast' , $specialdayrule )) {
// Geneva fast in Switzerland (Thursday after the first sunday in September)
$date_1sunsept = strtotime ( 'next thursday' , strtotime ( 'next sunday' , mktime ( 0 , 0 , 0 , 9 , 1 , $annee )));
$jour_1sunsept = date ( " d " , $date_1sunsept );
$mois_1sunsept = date ( " m " , $date_1sunsept );
2023-12-04 12:05:28 +01:00
if ( $jour_1sunsept == $jour && $mois_1sunsept == $mois ) {
2024-03-17 18:19:10 +01:00
$ferie = true ;
2023-12-04 12:05:28 +01:00
}
2022-08-12 17:23:41 +02:00
// Geneva fast in Switzerland
}
2020-12-05 17:41:05 +01:00
}
//print "ferie=".$ferie."\n";
2021-04-05 21:05:22 +02:00
// If we have to include Friday, Saturday and Sunday
2020-12-05 17:41:05 +01:00
if ( ! $ferie ) {
2021-04-05 18:57:33 +02:00
if ( $includefriday || $includesaturday || $includesunday ) {
2020-12-05 17:41:05 +01:00
$jour_julien = unixtojd ( $timestampStart );
$jour_semaine = jddayofweek ( $jour_julien , 0 );
2021-04-05 18:57:33 +02:00
if ( $includefriday ) { //Friday (5), Saturday (6) and Sunday (0)
2021-04-05 19:09:25 +02:00
if ( $jour_semaine == 5 ) {
2023-12-04 12:05:28 +01:00
$ferie = true ;
2021-04-05 19:09:25 +02:00
}
}
2021-04-05 18:57:33 +02:00
if ( $includesaturday ) { //Friday (5), Saturday (6) and Sunday (0)
2021-02-23 22:03:23 +01:00
if ( $jour_semaine == 6 ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
}
2021-04-05 18:57:33 +02:00
if ( $includesunday ) { //Friday (5), Saturday (6) and Sunday (0)
2021-02-23 22:03:23 +01:00
if ( $jour_semaine == 0 ) {
$ferie = true ;
}
2020-12-05 17:41:05 +01:00
}
2019-09-09 10:27:56 +02:00
}
2008-08-29 22:18:28 +02:00
}
2020-12-05 17:41:05 +01:00
//print "ferie=".$ferie."\n";
2008-08-29 22:18:28 +02:00
2019-09-09 10:27:56 +02:00
// We increase the counter of non working day
2021-02-23 22:03:23 +01:00
if ( $ferie ) {
$nbFerie ++ ;
}
2008-08-29 22:18:28 +02:00
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
}
2020-12-05 17:41:05 +01:00
//print "nbFerie=".$nbFerie."\n";
2008-08-29 22:18:28 +02:00
return $nbFerie ;
}
2024-12-24 10:36:53 +01:00
/**
* Return the list of public holidays including Friday , Saturday and Sunday ( or not ) between 2 dates in timestamp .
* Dates must be UTC with hour , min , sec to 0.
2025-02-02 01:08:40 +01:00
* TODO Not used yet . Must be shared with num_public_holiday ()
2024-12-24 10:36:53 +01:00
*
2025-02-02 01:08:40 +01:00
* @ param int $timestampStart Timestamp start ( UTC with hour , min , sec = 0 )
* @ param int $timestampEnd Timestamp end ( UTC with hour , min , sec = 0 )
* @ param string $country_code Country code
* @ param int $lastday Last day is included , 0 : no , 1 : yes
* @ param int $excludesaturday Exclude saturday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
* @ param int $excludesunday Exclude sunday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
* @ param int $excludefriday Exclude friday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
* @ param int $excludemonday Exclude monday as non working day ( - 1 = use setup , 0 = no , 1 = yes )
* @ return string | int [] List of public holidays timestamps or error message string if error
* @ see num_public_holiday (), num_open_day ()
2024-12-24 10:36:53 +01:00
*/
2025-02-02 01:08:40 +01:00
function listPublicHoliday ( $timestampStart , $timestampEnd , $country_code = '' , $lastday = 0 , $excludesaturday = - 1 , $excludesunday = - 1 , $excludefriday = - 1 , $excludemonday = - 1 )
2024-12-24 10:36:53 +01:00
{
global $conf , $db , $mysoc ;
// Check to ensure we use correct parameters
if (( $timestampEnd - $timestampStart ) % 86400 != 0 ) {
return 'Error Dates must use same hours and must be GMT dates' ;
}
if ( empty ( $country_code )) {
$country_code = $mysoc -> country_code ;
}
if ( $excludemonday < 0 ) {
$excludemonday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY' , 0 );
}
if ( $excludefriday < 0 ) {
$excludefriday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY' , 0 );
}
if ( $excludesaturday < 0 ) {
$excludesaturday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY' , 1 );
}
if ( $excludesunday < 0 ) {
$excludesunday = getDolGlobalInt ( 'MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY' , 1 );
}
$country_id = dol_getIdFromCode ( $db , $country_code , 'c_country' , 'code' , 'rowid' );
if ( empty ( $conf -> cache [ 'arrayOfActivePublicHolidays_' . $country_id ])) {
// Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed
$tmpArrayOfPublicHolidays = array ();
$sql = " SELECT id, code, entity, fk_country, dayrule, year, month, day, active " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " c_hrm_public_holiday " ;
$sql .= " WHERE active = 1 and fk_country IN (0 " . ( $country_id > 0 ? " , " . $country_id : 0 ) . " ) " ;
$sql .= " AND entity IN (0, " . getEntity ( 'holiday' ) . " ) " ;
$resql = $db -> query ( $sql );
if ( $resql ) {
$num_rows = $db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num_rows ) {
$obj = $db -> fetch_object ( $resql );
$tmpArrayOfPublicHolidays [ $obj -> id ] = array ( 'dayrule' => $obj -> dayrule , 'year' => $obj -> year , 'month' => $obj -> month , 'day' => $obj -> day );
$i ++ ;
}
} else {
dol_syslog ( $db -> lasterror (), LOG_ERR );
return 'Error sql ' . $db -> lasterror ();
}
//var_dump($tmpArrayOfPublicHolidays);
$conf -> cache [ 'arrayOfActivePublicHolidays_' . $country_id ] = $tmpArrayOfPublicHolidays ;
}
$arrayOfPublicHolidays = $conf -> cache [ 'arrayOfActivePublicHolidays_' . $country_id ];
$listFeries = [];
$i = 0 ;
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)
$nonWorkingDay = false ;
$ferie = false ;
$specialdayrule = array ();
$jour = ( int ) gmdate ( " d " , $timestampStart );
$mois = ( int ) gmdate ( " m " , $timestampStart );
$annee = ( int ) gmdate ( " Y " , $timestampStart );
// If we have to exclude Friday, Saturday and Sunday
if ( $excludefriday || $excludesaturday || $excludesunday ) {
$jour_julien = unixtojd ( $timestampStart );
$jour_semaine = jddayofweek ( $jour_julien , 0 );
if ( $excludefriday ) { //Friday (5), Saturday (6) and Sunday (0)
if ( $jour_semaine == 5 ) {
$nonWorkingDay = true ;
}
}
if ( $excludesaturday ) { //Friday (5), Saturday (6) and Sunday (0)
if ( $jour_semaine == 6 ) {
$nonWorkingDay = true ;
}
}
if ( $excludesunday ) { //Friday (5), Saturday (6) and Sunday (0)
if ( $jour_semaine == 0 ) {
$nonWorkingDay = true ;
}
}
}
//print "ferie=".$nonWorkingDay."\n";
if ( ! $nonWorkingDay ) {
//print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$excludesaturday." includesunday=".$excludesunday."\n";
foreach ( $arrayOfPublicHolidays as $entrypublicholiday ) {
if ( ! empty ( $entrypublicholiday [ 'dayrule' ]) && $entrypublicholiday [ 'dayrule' ] != 'date' ) { // For example 'easter', '...'
$specialdayrule [ $entrypublicholiday [ 'dayrule' ]] = $entrypublicholiday [ 'dayrule' ];
} else {
$match = 1 ;
if ( ! empty ( $entrypublicholiday [ 'year' ]) && $entrypublicholiday [ 'year' ] != $annee ) {
$match = 0 ;
}
if ( $entrypublicholiday [ 'month' ] != $mois ) {
$match = 0 ;
}
if ( $entrypublicholiday [ 'day' ] != $jour ) {
$match = 0 ;
}
if ( $match ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
}
$i ++ ;
}
//var_dump($specialdayrule)."\n";
//print "ferie=".$nonWorkingDay."\n";
}
if ( ! $nonWorkingDay && ! $ferie ) {
// Special dayrules
if ( in_array ( 'easter' , $specialdayrule )) {
// Calculation for easter date
$date_paques = getGMTEasterDatetime ( $annee );
$jour_paques = gmdate ( " d " , $date_paques );
$mois_paques = gmdate ( " m " , $date_paques );
if ( $jour_paques == $jour && $mois_paques == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// Easter (sunday)
}
if ( in_array ( 'eastermonday' , $specialdayrule )) {
// Calculation for the monday of easter date
$date_paques = getGMTEasterDatetime ( $annee );
//print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." ";
$date_lundi_paques = $date_paques + ( 3600 * 24 );
$jour_lundi_paques = gmdate ( " d " , $date_lundi_paques );
$mois_lundi_paques = gmdate ( " m " , $date_lundi_paques );
if ( $jour_lundi_paques == $jour && $mois_lundi_paques == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// Easter (monday)
//print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n";
}
//Good Friday
if ( in_array ( 'goodfriday' , $specialdayrule )) {
// Pulls the date of Easter
$easter = getGMTEasterDatetime ( $annee );
// Calculates the date of Good Friday based on Easter
$date_good_friday = $easter - ( 2 * 3600 * 24 );
$dom_good_friday = gmdate ( " d " , $date_good_friday );
$month_good_friday = gmdate ( " m " , $date_good_friday );
if ( $dom_good_friday == $jour && $month_good_friday == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
}
if ( in_array ( 'ascension' , $specialdayrule )) {
// Calcul du jour de l'ascension (39 days after easter day)
$date_paques = getGMTEasterDatetime ( $annee );
$date_ascension = $date_paques + ( 3600 * 24 * 39 );
$jour_ascension = gmdate ( " d " , $date_ascension );
$mois_ascension = gmdate ( " m " , $date_ascension );
if ( $jour_ascension == $jour && $mois_ascension == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// Ascension (thursday)
}
if ( in_array ( 'pentecost' , $specialdayrule )) {
// Calculation of "Pentecote" (49 days after easter day)
$date_paques = getGMTEasterDatetime ( $annee );
$date_pentecote = $date_paques + ( 3600 * 24 * 49 );
$jour_pentecote = gmdate ( " d " , $date_pentecote );
$mois_pentecote = gmdate ( " m " , $date_pentecote );
if ( $jour_pentecote == $jour && $mois_pentecote == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// "Pentecote" (sunday)
}
if ( in_array ( 'pentecotemonday' , $specialdayrule )) {
// Calculation of "Pentecote" (49 days after easter day)
$date_paques = getGMTEasterDatetime ( $annee );
$date_pentecote = $date_paques + ( 3600 * 24 * 50 );
$jour_pentecote = gmdate ( " d " , $date_pentecote );
$mois_pentecote = gmdate ( " m " , $date_pentecote );
if ( $jour_pentecote == $jour && $mois_pentecote == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// "Pentecote" (monday)
}
if ( in_array ( 'viernessanto' , $specialdayrule )) {
// Viernes Santo
$date_paques = getGMTEasterDatetime ( $annee );
$date_viernes = $date_paques - ( 3600 * 24 * 2 );
$jour_viernes = gmdate ( " d " , $date_viernes );
$mois_viernes = gmdate ( " m " , $date_viernes );
if ( $jour_viernes == $jour && $mois_viernes == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
//Viernes Santo
}
if ( in_array ( 'fronleichnam' , $specialdayrule )) {
// Fronleichnam (60 days after easter sunday)
$date_paques = getGMTEasterDatetime ( $annee );
$date_fronleichnam = $date_paques + ( 3600 * 24 * 60 );
$jour_fronleichnam = gmdate ( " d " , $date_fronleichnam );
$mois_fronleichnam = gmdate ( " m " , $date_fronleichnam );
if ( $jour_fronleichnam == $jour && $mois_fronleichnam == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// Fronleichnam
}
if ( in_array ( 'genevafast' , $specialdayrule )) {
// Geneva fast in Switzerland (Thursday after the first sunday in September)
$date_1sunsept = strtotime ( 'next thursday' , strtotime ( 'next sunday' , mktime ( 0 , 0 , 0 , 9 , 1 , $annee )));
$jour_1sunsept = date ( " d " , $date_1sunsept );
$mois_1sunsept = date ( " m " , $date_1sunsept );
if ( $jour_1sunsept == $jour && $mois_1sunsept == $mois ) {
$ferie = true ;
$listFeries [] = $timestampStart ;
}
// Geneva fast in Switzerland
}
}
//print "ferie=".$nonWorkingDay."\n";
// Increase number of days (on go up into loop)
$timestampStart = dol_time_plus_duree ( $timestampStart , 1 , 'd' );
//var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart);
$i ++ ;
}
//print "nbFerie=".$nbFerie."\n";
return $listFeries ;
}
2008-08-29 22:18:28 +02:00
/**
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
2024-06-12 00:41:00 +02:00
* @ see 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
{
2024-11-08 14:46:44 +01:00
if ( $timestampStart <= $timestampEnd ) {
2021-02-23 22:03:23 +01:00
if ( $lastday == 1 ) {
2008-08-29 22:18:28 +02:00
$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 ;
2024-03-20 19:57:41 +01:00
} else {
$nbjours = 0 ;
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
2021-02-23 22:03:23 +01: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
2021-02-23 22:03:23 +01: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;
2021-02-23 22:03:23 +01: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 );
2021-02-23 22:03:23 +01:00
if ( $inhour == 1 && $nbOpenDay <= 3 ) {
2024-08-07 02:53:45 +02:00
$nbOpenDay *= 24 ;
2021-02-23 22:03:23 +01:00
}
2012-12-18 13:12:11 +01:00
return $nbOpenDay - (( $inhour == 1 ? 12 : 0.5 ) * abs ( $halfday ));
2021-02-23 22:03:23 +01:00
} elseif ( $timestampStart == $timestampEnd ) {
2020-05-07 17:21:27 +02:00
$numholidays = 0 ;
if ( $lastday ) {
$numholidays = num_public_holiday ( $timestampStart , $timestampEnd , $country_code , $lastday );
2021-02-23 22:03:23 +01:00
if ( $numholidays == 1 ) {
return 0 ;
}
2020-05-07 17:21:27 +02:00
}
2020-05-15 13:55:31 +02:00
$nbOpenDay = $lastday ;
2020-05-07 17:21:27 +02:00
2021-02-23 22:03:23 +01:00
if ( $inhour == 1 ) {
2024-08-07 02:53:45 +02:00
$nbOpenDay *= 24 ;
2021-02-23 22:03:23 +01:00
}
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
2024-03-18 22:48:47 +01:00
* @ return array < int < 1 , 12 > , string > String of months in normal or short string format
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 (
2020-10-31 14:32:18 +01: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
2021-02-23 22:03:23 +01:00
if ( ! empty ( $short )) {
2020-04-10 10:59:32 +02:00
$montharray = array (
2020-10-31 14:32:18 +01: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
}
2024-06-12 00:41:00 +02:00
2020-01-22 15:27:50 +01:00
/**
* Return array of week numbers .
*
* @ param int $month Month number
* @ param int $year Year number
2024-03-18 22:48:47 +01:00
* @ return string [] Week numbers ( week 1 is '01' )
2020-01-22 15:27:50 +01:00
*/
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 ;
}
2024-06-12 00:41:00 +02:00
2020-01-22 15:27:50 +01:00
/**
* Return array of first day of weeks .
*
2024-06-12 00:41:00 +02:00
* @ param string [] $TWeek array of week numbers we want ( week 1 must be '01' )
2020-01-22 15:27:50 +01:00
* @ param int $year Year number
2024-06-12 00:41:00 +02:00
* @ return string [] First day of each week in entry ( day 1 is '01' )
2020-01-22 15:27:50 +01:00
*/
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 ) {
2021-02-23 22:03:23 +01:00
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 ;
}
2024-06-12 00:41:00 +02:00
2020-01-22 15:27:50 +01:00
/**
* Return array of last day of weeks .
*
2024-03-18 22:48:47 +01:00
* @ param string [] $TWeek array of week numbers
2020-01-22 15:27:50 +01:00
* @ param int $year Year number
2024-03-18 22:48:47 +01:00
* @ return string [] Last day of week ( day 1 is '01' )
2020-01-22 15:27:50 +01:00
*/
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 ;
}
2024-06-12 00:41:00 +02:00
2020-01-22 15:27:50 +01:00
/**
* Return week number .
*
* @ param int $day Day number
* @ param int $month Month number
* @ param int $year Year number
2024-03-18 22:48:47 +01:00
* @ return string Week number as two digits ( week 1 is '01' )
2020-01-22 15:27:50 +01:00
*/
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 " );
2024-03-18 22:48:47 +01:00
return $week ;
2020-01-22 15:27:50 +01:00
}