oxutilsdate.php

Go to the documentation of this file.
00001 <?php
00002 
00006 class oxUtilsDate extends oxSuperCfg
00007 {
00013     private static $_instance = null;
00014 
00022     public static function getInstance()
00023     {
00024         return oxRegistry::get("oxUtilsDate");
00025     }
00026 
00035     public function formatDBDate( $sDBDateIn, $blForceEnglishRet = false )
00036     {
00037         // convert english format to output format
00038         if ( !$sDBDateIn ) {
00039             return null;
00040         }
00041 
00042         $oStr = getStr();
00043         if ( $blForceEnglishRet && $oStr->strstr( $sDBDateIn, '-' ) ) {
00044             return $sDBDateIn;
00045         }
00046 
00047         if ( $this->isEmptyDate( $sDBDateIn ) && $sDBDateIn != '-' ) {
00048             return '-';
00049         } elseif ( $sDBDateIn == '-' ) {
00050             return '0000-00-00 00:00:00';
00051         }
00052 
00053         // is it a timestamp ?
00054         if ( is_numeric( $sDBDateIn ) ) {
00055             // db timestamp : 20030322100409
00056             $sNew  = substr( $sDBDateIn, 0, 4 ).'-'.substr( $sDBDateIn, 4, 2 ).'-'.substr( $sDBDateIn, 6, 2 ).' ';
00057             // check if it is a timestamp or wrong data: 20030322
00058             if ( strlen($sDBDateIn) > 8 ) {
00059                 $sNew .= substr( $sDBDateIn, 8, 2 ).':'.substr( $sDBDateIn, 10, 2 ).':'.substr( $sDBDateIn, 12, 2 );
00060             }
00061             // convert it to english format
00062             $sDBDateIn = $sNew;
00063         }
00064 
00065         // remove time as it is same in english as in german
00066         $aData = explode( ' ', trim( $sDBDateIn ) );
00067 
00068         // preparing time array
00069         $sTime = ( isset( $aData[1] ) && $oStr->strstr( $aData[1], ':' ) )?$aData[1]:'';
00070         $aTime = $sTime?explode( ':', $sTime ):array( 0, 0, 0 );
00071 
00072         // preparing date array
00073         $sDate = isset( $aData[0] )?$aData[0]:'';
00074         $aDate = preg_split( '/[\/.-]/', $sDate );
00075 
00076         // choosing format..
00077         if ( $sTime ) {
00078             $sFormat = $blForceEnglishRet ? 'Y-m-d H:i:s' : oxRegistry::getLang()->translateString( 'fullDateFormat' );
00079         } else {
00080             $sFormat = $blForceEnglishRet ? 'Y-m-d' : oxRegistry::getLang()->translateString( 'simpleDateFormat' );
00081         }
00082 
00083         if ( count( $aDate ) != 3 ) {
00084             return date( $sFormat );
00085         } else {
00086             return $this->_processDate( $aTime, $aDate, $oStr->strstr( $sDate, '.' ), $sFormat );
00087         }
00088     }
00089 
00099     public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
00100     {
00101         $sDate = $oObject->value;
00102 
00103         // defining time format
00104         $sLocalDateFormat = $this->_defineAndCheckDefaultDateValues( $blToTimeStamp );
00105         $sLocalTimeFormat = $this->_defineAndCheckDefaultTimeValues( $blToTimeStamp );
00106 
00107         // default date/time patterns
00108         $aDefDatePatterns = $this->_defaultDatePattern();
00109 
00110         // regexps to validate input
00111         $aDatePatterns = $this->_regexp2ValidateDateInput();
00112         $aTimePatterns = $this->_regexp2ValidateTimeInput();
00113 
00114         // date/time formatting rules
00115         $aDFormats  = $this->_defineDateFormattingRules();
00116         $aTFormats  = $this->_defineTimeFormattingRules();
00117 
00118         // empty date field value ? setting default value
00119         if ( !$sDate) {
00120             $this->_setDefaultDateTimeValue($oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00121             return $oObject->value;
00122         }
00123 
00124         $blDefDateFound = false;
00125         $oStr = getStr();
00126 
00127         // looking for default values that are formatted by MySQL
00128         foreach ( array_keys( $aDefDatePatterns ) as $sDefDatePattern ) {
00129             if ( $oStr->preg_match( $sDefDatePattern, $sDate)) {
00130                 $blDefDateFound = true;
00131                 break;
00132             }
00133         }
00134 
00135         // default value is set ?
00136         if ( $blDefDateFound) {
00137             $this->_setDefaultFormatedValue($oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
00138             return $oObject->value;
00139         }
00140 
00141         $blDateFound = false;
00142         $blTimeFound = false;
00143         $aDateMatches = array();
00144         $aTimeMatches = array();
00145 
00146         // looking for date field
00147         foreach ( $aDatePatterns as $sPattern => $sType) {
00148             if ( $oStr->preg_match( $sPattern, $sDate, $aDateMatches)) {
00149                 $blDateFound = true;
00150 
00151                 // now we know the type of passed date
00152                 $sDateFormat = $aDFormats[$sLocalDateFormat][0];
00153                 $aDFields    = $aDFormats[$sType][1];
00154                 break;
00155             }
00156         }
00157 
00158         // no such date field available ?
00159         if ( !$blDateFound) {
00160             return $sDate;
00161         }
00162 
00163         if ( $blOnlyDate) {
00164             $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00165             return $oObject->value;
00166         }
00167 
00168         // looking for time field
00169         foreach ( $aTimePatterns as $sPattern => $sType) {
00170             if ( $oStr->preg_match( $sPattern, $sDate, $aTimeMatches)) {
00171                 $blTimeFound = true;
00172 
00173                 // now we know the type of passed time
00174                 $sTimeFormat = $aTFormats[$sLocalTimeFormat][0];
00175                 $aTFields    = $aTFormats[$sType][1];
00176 
00177                 //
00178                 if ( $sType == "USA" && isset($aTimeMatches[4])) {
00179                     $iIntVal = (int) $aTimeMatches[1];
00180                     if ( $aTimeMatches[4] == "PM") {
00181                         if ( $iIntVal < 13) {
00182                             $iIntVal += 12;
00183                         }
00184                     } elseif ( $aTimeMatches[4] == "AM" && $aTimeMatches[1] == "12") {
00185                         $iIntVal = 0;
00186                     }
00187 
00188                     $aTimeMatches[1] = sprintf("%02d", $iIntVal);
00189                 }
00190 
00191                 break;
00192             }
00193         }
00194 
00195         if ( !$blTimeFound) {
00196             //return $sDate;
00197             // #871A. trying to keep date as possible correct
00198             $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
00199             return $oObject->value;
00200         }
00201 
00202         $this->_formatCorrectTimeValue($oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields);
00203 
00204         // on some cases we get empty value
00205         if ( !$oObject->fldmax_length) {
00206             return $this->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate);
00207         }
00208         return $oObject->value;
00209     }
00219     public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
00220     {
00221         // on this case usually means that we gonna save value, and value is formatted, not plain
00222         $sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
00223         $sISOTimeStampPattern = "/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/";
00224         $aMatches = array();
00225         $oStr = getStr();
00226 
00227         // preparing value to save
00228         if ( $blToTimeStamp) {
00229             // reformatting value to ISO
00230             $this->convertDBDateTime( $oObject, $blToTimeStamp );
00231 
00232             if ( $oStr->preg_match( $sISOTimeStampPattern, $oObject->value, $aMatches)) {
00233                 // changing layout
00234                 $oObject->setValue($aMatches[1].$aMatches[2].$aMatches[3].$aMatches[4].$aMatches[5].$aMatches[6]);
00235                 $oObject->fldmax_length = strlen( $oObject->value);
00236                 return $oObject->value;
00237             }
00238         } else {
00239             // loading and formatting value
00240             // checking and parsing SQL timestamp value
00241             //$sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
00242             if ( $oStr->preg_match( $sSQLTimeStampPattern, $oObject->value, $aMatches ) ) {
00243                 $iTimestamp = mktime( $aMatches[4], //h
00244                     $aMatches[5], //m
00245                     $aMatches[6], //s
00246                     $aMatches[2], //M
00247                     $aMatches[3], //d
00248                     $aMatches[1]); //y
00249                 if ( !$iTimestamp ) {
00250                     $iTimestamp = "0";
00251                 }
00252 
00253                 $oObject->setValue(trim( date( "Y-m-d H:i:s", $iTimestamp)));
00254                 $oObject->fldmax_length = strlen( $oObject->value);
00255                 $this->convertDBDateTime( $oObject, $blToTimeStamp );
00256                 return $oObject->value;
00257             }
00258         }
00259     }
00260 
00269     public function convertDBDate( $oObject, $blToTimeStamp = false )
00270     {
00271         return $this->convertDBDateTime( $oObject, $blToTimeStamp, true );
00272     }
00273 
00285     protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00286     {
00287         $aDefTimePatterns = $this->_defaultTimePattern();
00288         $aDFormats  = $this->_defineDateFormattingRules();
00289         $aTFormats  = $this->_defineTimeFormattingRules();
00290         $oStr = getStr();
00291 
00292         foreach ( array_keys( $aDefTimePatterns ) as $sDefTimePattern ) {
00293             if ( $oStr->preg_match( $sDefTimePattern, $sDate ) ) {
00294                 $blDefTimeFound = true;
00295                 break;
00296             }
00297         }
00298 
00299         // setting and returning default formatted value
00300         if ( $blOnlyDate) {
00301             $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] ));// . " " . @$aTFormats[$sLocalTimeFormat][2]);
00302             // increasing(decreasing) field length
00303             $oObject->fldmax_length = strlen( $oObject->value );
00304             return ;
00305         } elseif ( $blDefTimeFound ) {
00306             // setting value
00307             $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] . " " . $aTFormats[$sLocalTimeFormat][2] ));
00308             // increasing(decreasing) field length
00309             $oObject->fldmax_length = strlen( $oObject->value );
00310             return ;
00311         }
00312     }
00313 
00321     protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
00322     {
00323         // defining time format
00324         // checking for default values
00325         $sLocalTimeFormat = oxRegistry::getConfig()->getConfigParam( 'sLocalTimeFormat' );
00326         if ( !$sLocalTimeFormat || $blToTimeStamp) {
00327             $sLocalTimeFormat = "ISO";
00328         }
00329         return $sLocalTimeFormat;
00330     }
00331 
00339     protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
00340     {
00341         // defining time format
00342         // checking for default values
00343         $sLocalDateFormat = oxRegistry::getConfig()->getConfigParam( 'sLocalDateFormat' );
00344         if ( !$sLocalDateFormat || $blToTimeStamp) {
00345             $sLocalDateFormat = "ISO";
00346         }
00347         return $sLocalDateFormat;
00348     }
00349 
00355     protected function _defaultDatePattern()
00356     {
00357         // default date patterns
00358         $aDefDatePatterns = array("/^0000-00-00/"   => "ISO",
00359                                   "/^00\.00\.0000/" => "EUR",
00360                                   "/^00\/00\/0000/" => "USA"
00361         );
00362         return $aDefDatePatterns;
00363     }
00364 
00370     protected function _defaultTimePattern()
00371     {
00372         // default time patterns
00373         $aDefTimePatterns = array("/00:00:00$/"    => "ISO",
00374                                   "/00\.00\.00$/"  => "EUR",
00375                                   "/00:00:00 AM$/" => "USA"
00376         );
00377         return $aDefTimePatterns;
00378     }
00379 
00385     protected function _regexp2ValidateDateInput()
00386     {
00387         // regexps to validate input
00388         $aDatePatterns = array("/^([0-9]{4})-([0-9]{2})-([0-9]{2})/"   => "ISO",
00389                                "/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})/" => "EUR",
00390                                "/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})/" => "USA"
00391         );
00392         return $aDatePatterns;
00393     }
00394 
00400     protected function _regexp2ValidateTimeInput()
00401     {
00402         // regexps to validate input
00403         $aTimePatterns = array("/([0-9]{2}):([0-9]{2}):([0-9]{2})$/"   => "ISO",
00404                                "/([0-9]{2})\.([0-9]{2})\.([0-9]{2})$/" => "EUR",
00405                                "/([0-9]{2}):([0-9]{2}):([0-9]{2}) ([AP]{1}[M]{1})$/" => "USA"
00406         );
00407         return $aTimePatterns;
00408     }
00409 
00415     protected function _defineDateFormattingRules()
00416     {
00417         // date formatting rules
00418         $aDFormats  = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
00419                             "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
00420                             "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
00421         );
00422         return $aDFormats;
00423     }
00424 
00430     protected function _defineTimeFormattingRules()
00431     {
00432         // time formatting rules
00433         $aTFormats  = array("ISO" => array("H:i:s",   array(1, 2, 3 ), "00:00:00"),
00434                             "EUR" => array("H.i.s",   array(1, 2, 3 ), "00.00.00"),
00435                             "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
00436         );
00437         return $aTFormats;
00438     }
00439 
00450     protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
00451     {
00452         $aDFormats  = $this->_defineDateFormattingRules();
00453         $aTFormats  = $this->_defineTimeFormattingRules();
00454 
00455         $sReturn = $aDFormats[$sLocalDateFormat][2];
00456         if ( !$blOnlyDate) {
00457             $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
00458         }
00459 
00460         if ($oObject instanceof oxField) {
00461             $oObject->setValue(trim($sReturn));
00462         } else {
00463             $oObject->value = trim($sReturn);
00464         }
00465         // increasing(decreasing) field lenght
00466         $oObject->fldmax_length = strlen( $oObject->value);
00467     }
00468 
00479     protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
00480     {
00481         // formatting correct time value
00482         $iTimestamp = mktime( 0, 0, 0, $aDateMatches[$aDFields[0]],
00483             $aDateMatches[$aDFields[1]],
00484             $aDateMatches[$aDFields[2]]);
00485 
00486         if ($oObject instanceof oxField) {
00487             $oObject->setValue(@date( $sDateFormat, $iTimestamp ));
00488         } else {
00489             $oObject->value = @date( $sDateFormat, $iTimestamp );
00490         }
00491         // we should increase (decrease) field lenght
00492         $oObject->fldmax_length = strlen( $oObject->value );
00493     }
00494 
00508     protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
00509     {
00510         // formatting correct time value
00511         $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
00512             (int) $aTimeMatches[$aTFields[1]],
00513             (int) $aTimeMatches[$aTFields[2]],
00514             (int) $aDateMatches[$aDFields[0]],
00515             (int) $aDateMatches[$aDFields[1]],
00516             (int) $aDateMatches[$aDFields[2]] );
00517 
00518         if ($oObject instanceof oxField) {
00519             $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
00520         } else {
00521             $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
00522         }
00523 
00524         // we should increase (decrease) field lenght
00525         $oObject->fldmax_length = strlen( $oObject->value );
00526     }
00527 
00534     public function getTime()
00535     {
00536         $iServerTimeShift = $this->getConfig()->getConfigParam( 'iServerTimeShift' );
00537         if ( !$iServerTimeShift ) {
00538             return time();
00539         }
00540 
00541         return ( time() + ( (int) $iServerTimeShift * 3600 ) );
00542     }
00543 
00555     public function getWeekNumber( $iFirstWeekDay,  $sTimestamp = null, $sFormat = null )
00556     {
00557         if ( $sTimestamp == null ) {
00558             $sTimestamp = time();
00559         }
00560         if ( $sFormat == null ) {
00561             $sFormat = '%W';
00562             if ( $iFirstWeekDay ) {
00563                 $sFormat = '%U';
00564             }
00565         }
00566         return (int) strftime( $sFormat, $sTimestamp );
00567     }
00568 
00576     public function german2English( $sDate )
00577     {
00578         $aDate = explode( ".", $sDate);
00579 
00580         if ( isset( $aDate ) && count( $aDate) > 1) {
00581             if ( count( $aDate) == 2) {
00582                 $sDate = $aDate[1]."-".$aDate[0];
00583             } else {
00584                 $sDate = $aDate[2]."-".$aDate[1]."-".$aDate[0];
00585             }
00586         }
00587 
00588         return $sDate;
00589     }
00590 
00601     protected function _processDate( $aTime, $aDate, $blGerman, $sFormat )
00602     {
00603         if ( $blGerman ) {
00604             return date( $sFormat, mktime( $aTime[0], $aTime[1], $aTime[2], $aDate[1], $aDate[0], $aDate[2] ) );
00605         } else {
00606             return date( $sFormat, mktime( $aTime[0], $aTime[1], $aTime[2], $aDate[1], $aDate[2], $aDate[0] ) );
00607         }
00608     }
00609 
00618     public function isEmptyDate( $sDate )
00619     {
00620         $blIsEmpty = true;
00621 
00622         if ( !empty( $sDate ) ) {
00623             $sDate = preg_replace("/[^0-9a-z]/i", "", $sDate);
00624             if ( is_numeric( $sDate ) && $sDate == 0 ) {
00625                 $blIsEmpty = true;
00626             } else {
00627                 $blIsEmpty = false;
00628             }
00629         }
00630 
00631         return $blIsEmpty;
00632     }
00633 
00634 }
00635