OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxutilsdate.php
Go to the documentation of this file.
1 <?php
2 
6 class oxUtilsDate extends oxSuperCfg
7 {
13  private static $_instance = null;
14 
22  public static function getInstance()
23  {
24  return oxRegistry::get("oxUtilsDate");
25  }
26 
35  public function formatDBDate( $sDBDateIn, $blForceEnglishRet = false )
36  {
37  // convert english format to output format
38  if ( !$sDBDateIn ) {
39  return null;
40  }
41 
42  $oStr = getStr();
43  if ( $blForceEnglishRet && $oStr->strstr( $sDBDateIn, '-' ) ) {
44  return $sDBDateIn;
45  }
46 
47  if ( $this->isEmptyDate( $sDBDateIn ) && $sDBDateIn != '-' ) {
48  return '-';
49  } elseif ( $sDBDateIn == '-' ) {
50  return '0000-00-00 00:00:00';
51  }
52 
53  // is it a timestamp ?
54  if ( is_numeric( $sDBDateIn ) ) {
55  // db timestamp : 20030322100409
56  $sNew = substr( $sDBDateIn, 0, 4 ).'-'.substr( $sDBDateIn, 4, 2 ).'-'.substr( $sDBDateIn, 6, 2 ).' ';
57  // check if it is a timestamp or wrong data: 20030322
58  if ( strlen($sDBDateIn) > 8 ) {
59  $sNew .= substr( $sDBDateIn, 8, 2 ).':'.substr( $sDBDateIn, 10, 2 ).':'.substr( $sDBDateIn, 12, 2 );
60  }
61  // convert it to english format
62  $sDBDateIn = $sNew;
63  }
64 
65  // remove time as it is same in english as in german
66  $aData = explode( ' ', trim( $sDBDateIn ) );
67 
68  // preparing time array
69  $sTime = ( isset( $aData[1] ) && $oStr->strstr( $aData[1], ':' ) )?$aData[1]:'';
70  $aTime = $sTime?explode( ':', $sTime ):array( 0, 0, 0 );
71 
72  // preparing date array
73  $sDate = isset( $aData[0] )?$aData[0]:'';
74  $aDate = preg_split( '/[\/.-]/', $sDate );
75 
76  // choosing format..
77  if ( $sTime ) {
78  $sFormat = $blForceEnglishRet ? 'Y-m-d H:i:s' : oxRegistry::getLang()->translateString( 'fullDateFormat' );
79  } else {
80  $sFormat = $blForceEnglishRet ? 'Y-m-d' : oxRegistry::getLang()->translateString( 'simpleDateFormat' );
81  }
82 
83  if ( count( $aDate ) != 3 ) {
84  return date( $sFormat );
85  } else {
86  return $this->_processDate( $aTime, $aDate, $oStr->strstr( $sDate, '.' ), $sFormat );
87  }
88  }
89 
99  public function convertDBDateTime( $oObject, $blToTimeStamp = false, $blOnlyDate = false )
100  {
101  $sDate = $oObject->value;
102 
103  // defining time format
104  $sLocalDateFormat = $this->_defineAndCheckDefaultDateValues( $blToTimeStamp );
105  $sLocalTimeFormat = $this->_defineAndCheckDefaultTimeValues( $blToTimeStamp );
106 
107  // default date/time patterns
108  $aDefDatePatterns = $this->_defaultDatePattern();
109 
110  // regexps to validate input
111  $aDatePatterns = $this->_regexp2ValidateDateInput();
112  $aTimePatterns = $this->_regexp2ValidateTimeInput();
113 
114  // date/time formatting rules
115  $aDFormats = $this->_defineDateFormattingRules();
116  $aTFormats = $this->_defineTimeFormattingRules();
117 
118  // empty date field value ? setting default value
119  if ( !$sDate) {
120  $this->_setDefaultDateTimeValue($oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
121  return $oObject->value;
122  }
123 
124  $blDefDateFound = false;
125  $oStr = getStr();
126 
127  // looking for default values that are formatted by MySQL
128  foreach ( array_keys( $aDefDatePatterns ) as $sDefDatePattern ) {
129  if ( $oStr->preg_match( $sDefDatePattern, $sDate)) {
130  $blDefDateFound = true;
131  break;
132  }
133  }
134 
135  // default value is set ?
136  if ( $blDefDateFound) {
137  $this->_setDefaultFormatedValue($oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate);
138  return $oObject->value;
139  }
140 
141  $blDateFound = false;
142  $blTimeFound = false;
143  $aDateMatches = array();
144  $aTimeMatches = array();
145 
146  // looking for date field
147  foreach ( $aDatePatterns as $sPattern => $sType) {
148  if ( $oStr->preg_match( $sPattern, $sDate, $aDateMatches)) {
149  $blDateFound = true;
150 
151  // now we know the type of passed date
152  $sDateFormat = $aDFormats[$sLocalDateFormat][0];
153  $aDFields = $aDFormats[$sType][1];
154  break;
155  }
156  }
157 
158  // no such date field available ?
159  if ( !$blDateFound) {
160  return $sDate;
161  }
162 
163  if ( $blOnlyDate) {
164  $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
165  return $oObject->value;
166  }
167 
168  // looking for time field
169  foreach ( $aTimePatterns as $sPattern => $sType) {
170  if ( $oStr->preg_match( $sPattern, $sDate, $aTimeMatches)) {
171  $blTimeFound = true;
172 
173  // now we know the type of passed time
174  $sTimeFormat = $aTFormats[$sLocalTimeFormat][0];
175  $aTFields = $aTFormats[$sType][1];
176 
177  //
178  if ( $sType == "USA" && isset($aTimeMatches[4])) {
179  $iIntVal = (int) $aTimeMatches[1];
180  if ( $aTimeMatches[4] == "PM") {
181  if ( $iIntVal < 13) {
182  $iIntVal += 12;
183  }
184  } elseif ( $aTimeMatches[4] == "AM" && $aTimeMatches[1] == "12") {
185  $iIntVal = 0;
186  }
187 
188  $aTimeMatches[1] = sprintf("%02d", $iIntVal);
189  }
190 
191  break;
192  }
193  }
194 
195  if ( !$blTimeFound) {
196  //return $sDate;
197  // #871A. trying to keep date as possible correct
198  $this->_setDate($oObject, $sDateFormat, $aDFields, $aDateMatches);
199  return $oObject->value;
200  }
201 
202  $this->_formatCorrectTimeValue($oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields);
203 
204  // on some cases we get empty value
205  if ( !$oObject->fldmax_length) {
206  return $this->convertDBDateTime( $oObject, $blToTimeStamp, $blOnlyDate);
207  }
208  return $oObject->value;
209  }
219  public function convertDBTimestamp( $oObject, $blToTimeStamp = false )
220  {
221  // on this case usually means that we gonna save value, and value is formatted, not plain
222  $sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
223  $sISOTimeStampPattern = "/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/";
224  $aMatches = array();
225  $oStr = getStr();
226 
227  // preparing value to save
228  if ( $blToTimeStamp) {
229  // reformatting value to ISO
230  $this->convertDBDateTime( $oObject, $blToTimeStamp );
231 
232  if ( $oStr->preg_match( $sISOTimeStampPattern, $oObject->value, $aMatches)) {
233  // changing layout
234  $oObject->setValue($aMatches[1].$aMatches[2].$aMatches[3].$aMatches[4].$aMatches[5].$aMatches[6]);
235  $oObject->fldmax_length = strlen( $oObject->value);
236  return $oObject->value;
237  }
238  } else {
239  // loading and formatting value
240  // checking and parsing SQL timestamp value
241  //$sSQLTimeStampPattern = "/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/";
242  if ( $oStr->preg_match( $sSQLTimeStampPattern, $oObject->value, $aMatches ) ) {
243  $iTimestamp = mktime( $aMatches[4], //h
244  $aMatches[5], //m
245  $aMatches[6], //s
246  $aMatches[2], //M
247  $aMatches[3], //d
248  $aMatches[1]); //y
249  if ( !$iTimestamp ) {
250  $iTimestamp = "0";
251  }
252 
253  $oObject->setValue(trim( date( "Y-m-d H:i:s", $iTimestamp)));
254  $oObject->fldmax_length = strlen( $oObject->value);
255  $this->convertDBDateTime( $oObject, $blToTimeStamp );
256  return $oObject->value;
257  }
258  }
259  }
260 
269  public function convertDBDate( $oObject, $blToTimeStamp = false )
270  {
271  return $this->convertDBDateTime( $oObject, $blToTimeStamp, true );
272  }
273 
285  protected function _setDefaultFormatedValue( $oObject, $sDate, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
286  {
287  $aDefTimePatterns = $this->_defaultTimePattern();
288  $aDFormats = $this->_defineDateFormattingRules();
289  $aTFormats = $this->_defineTimeFormattingRules();
290  $oStr = getStr();
291 
292  foreach ( array_keys( $aDefTimePatterns ) as $sDefTimePattern ) {
293  if ( $oStr->preg_match( $sDefTimePattern, $sDate ) ) {
294  $blDefTimeFound = true;
295  break;
296  }
297  }
298 
299  // setting and returning default formatted value
300  if ( $blOnlyDate) {
301  $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] ));// . " " . @$aTFormats[$sLocalTimeFormat][2]);
302  // increasing(decreasing) field length
303  $oObject->fldmax_length = strlen( $oObject->value );
304  return ;
305  } elseif ( $blDefTimeFound ) {
306  // setting value
307  $oObject->setValue(trim( $aDFormats[$sLocalDateFormat][2] . " " . $aTFormats[$sLocalTimeFormat][2] ));
308  // increasing(decreasing) field length
309  $oObject->fldmax_length = strlen( $oObject->value );
310  return ;
311  }
312  }
313 
321  protected function _defineAndCheckDefaultTimeValues( $blToTimeStamp )
322  {
323  // defining time format
324  // checking for default values
325  $sLocalTimeFormat = oxRegistry::getConfig()->getConfigParam( 'sLocalTimeFormat' );
326  if ( !$sLocalTimeFormat || $blToTimeStamp) {
327  $sLocalTimeFormat = "ISO";
328  }
329  return $sLocalTimeFormat;
330  }
331 
339  protected function _defineAndCheckDefaultDateValues( $blToTimeStamp )
340  {
341  // defining time format
342  // checking for default values
343  $sLocalDateFormat = oxRegistry::getConfig()->getConfigParam( 'sLocalDateFormat' );
344  if ( !$sLocalDateFormat || $blToTimeStamp) {
345  $sLocalDateFormat = "ISO";
346  }
347  return $sLocalDateFormat;
348  }
349 
355  protected function _defaultDatePattern()
356  {
357  // default date patterns
358  $aDefDatePatterns = array("/^0000-00-00/" => "ISO",
359  "/^00\.00\.0000/" => "EUR",
360  "/^00\/00\/0000/" => "USA"
361  );
362  return $aDefDatePatterns;
363  }
364 
370  protected function _defaultTimePattern()
371  {
372  // default time patterns
373  $aDefTimePatterns = array("/00:00:00$/" => "ISO",
374  "/00\.00\.00$/" => "EUR",
375  "/00:00:00 AM$/" => "USA"
376  );
377  return $aDefTimePatterns;
378  }
379 
385  protected function _regexp2ValidateDateInput()
386  {
387  // regexps to validate input
388  $aDatePatterns = array("/^([0-9]{4})-([0-9]{2})-([0-9]{2})/" => "ISO",
389  "/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})/" => "EUR",
390  "/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})/" => "USA"
391  );
392  return $aDatePatterns;
393  }
394 
400  protected function _regexp2ValidateTimeInput()
401  {
402  // regexps to validate input
403  $aTimePatterns = array("/([0-9]{2}):([0-9]{2}):([0-9]{2})$/" => "ISO",
404  "/([0-9]{2})\.([0-9]{2})\.([0-9]{2})$/" => "EUR",
405  "/([0-9]{2}):([0-9]{2}):([0-9]{2}) ([AP]{1}[M]{1})$/" => "USA"
406  );
407  return $aTimePatterns;
408  }
409 
415  protected function _defineDateFormattingRules()
416  {
417  // date formatting rules
418  $aDFormats = array("ISO" => array("Y-m-d", array(2, 3, 1), "0000-00-00"),
419  "EUR" => array("d.m.Y", array(2, 1, 3), "00.00.0000"),
420  "USA" => array("m/d/Y", array(1, 2, 3), "00/00/0000")
421  );
422  return $aDFormats;
423  }
424 
430  protected function _defineTimeFormattingRules()
431  {
432  // time formatting rules
433  $aTFormats = array("ISO" => array("H:i:s", array(1, 2, 3 ), "00:00:00"),
434  "EUR" => array("H.i.s", array(1, 2, 3 ), "00.00.00"),
435  "USA" => array("h:i:s A", array(1, 2, 3 ), "00:00:00 AM")
436  );
437  return $aTFormats;
438  }
439 
450  protected function _setDefaultDateTimeValue( $oObject, $sLocalDateFormat, $sLocalTimeFormat, $blOnlyDate )
451  {
452  $aDFormats = $this->_defineDateFormattingRules();
453  $aTFormats = $this->_defineTimeFormattingRules();
454 
455  $sReturn = $aDFormats[$sLocalDateFormat][2];
456  if ( !$blOnlyDate) {
457  $sReturn .= " ".$aTFormats[$sLocalTimeFormat][2];
458  }
459 
460  if ($oObject instanceof oxField) {
461  $oObject->setValue(trim($sReturn));
462  } else {
463  $oObject->value = trim($sReturn);
464  }
465  // increasing(decreasing) field lenght
466  $oObject->fldmax_length = strlen( $oObject->value);
467  }
468 
479  protected function _setDate( $oObject, $sDateFormat, $aDFields, $aDateMatches )
480  {
481  // formatting correct time value
482  $iTimestamp = mktime( 0, 0, 0, $aDateMatches[$aDFields[0]],
483  $aDateMatches[$aDFields[1]],
484  $aDateMatches[$aDFields[2]]);
485 
486  if ($oObject instanceof oxField) {
487  $oObject->setValue(@date( $sDateFormat, $iTimestamp ));
488  } else {
489  $oObject->value = @date( $sDateFormat, $iTimestamp );
490  }
491  // we should increase (decrease) field lenght
492  $oObject->fldmax_length = strlen( $oObject->value );
493  }
494 
508  protected function _formatCorrectTimeValue( $oObject, $sDateFormat, $sTimeFormat, $aDateMatches, $aTimeMatches, $aTFields, $aDFields )
509  {
510  // formatting correct time value
511  $iTimestamp = @mktime( (int) $aTimeMatches[$aTFields[0]],
512  (int) $aTimeMatches[$aTFields[1]],
513  (int) $aTimeMatches[$aTFields[2]],
514  (int) $aDateMatches[$aDFields[0]],
515  (int) $aDateMatches[$aDFields[1]],
516  (int) $aDateMatches[$aDFields[2]] );
517 
518  if ($oObject instanceof oxField) {
519  $oObject->setValue(trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) ));
520  } else {
521  $oObject->value = trim( @date( $sDateFormat." ".$sTimeFormat, $iTimestamp ) );
522  }
523 
524  // we should increase (decrease) field lenght
525  $oObject->fldmax_length = strlen( $oObject->value );
526  }
527 
534  public function getTime()
535  {
536  $iServerTimeShift = $this->getConfig()->getConfigParam( 'iServerTimeShift' );
537  if ( !$iServerTimeShift ) {
538  return time();
539  }
540 
541  return ( time() + ( (int) $iServerTimeShift * 3600 ) );
542  }
543 
555  public function getWeekNumber( $iFirstWeekDay, $sTimestamp = null, $sFormat = null )
556  {
557  if ( $sTimestamp == null ) {
558  $sTimestamp = time();
559  }
560  if ( $sFormat == null ) {
561  $sFormat = '%W';
562  if ( $iFirstWeekDay ) {
563  $sFormat = '%U';
564  }
565  }
566  return (int) strftime( $sFormat, $sTimestamp );
567  }
568 
576  public function german2English( $sDate )
577  {
578  $aDate = explode( ".", $sDate);
579 
580  if ( isset( $aDate ) && count( $aDate) > 1) {
581  if ( count( $aDate) == 2) {
582  $sDate = $aDate[1]."-".$aDate[0];
583  } else {
584  $sDate = $aDate[2]."-".$aDate[1]."-".$aDate[0];
585  }
586  }
587 
588  return $sDate;
589  }
590 
601  protected function _processDate( $aTime, $aDate, $blGerman, $sFormat )
602  {
603  if ( $blGerman ) {
604  return date( $sFormat, mktime( $aTime[0], $aTime[1], $aTime[2], $aDate[1], $aDate[0], $aDate[2] ) );
605  } else {
606  return date( $sFormat, mktime( $aTime[0], $aTime[1], $aTime[2], $aDate[1], $aDate[2], $aDate[0] ) );
607  }
608  }
609 
618  public function isEmptyDate( $sDate )
619  {
620  $blIsEmpty = true;
621 
622  if ( !empty( $sDate ) ) {
623  $sDate = preg_replace("/[^0-9a-z]/i", "", $sDate);
624  if ( is_numeric( $sDate ) && $sDate == 0 ) {
625  $blIsEmpty = true;
626  } else {
627  $blIsEmpty = false;
628  }
629  }
630 
631  return $blIsEmpty;
632  }
633 
634 }
635