PHP date() alternitive

espfutbol98

New Member
Messages
200
Reaction score
2
Points
0
I have been working on a site in a different language and because of that, I have to work my way around the date() function. I found this script in php.net but when I run it, it returns all of the numbers but not the words. They appear as a dimond with a question mark in it. I have already made sure everything on the page is UFT-8 and it still is giving me problems. Are some of the functions outdated or what?
PHP:
<?php
/*
  these are the russian additional format characters
  д: full textual representation of the day of the week
  Д: full textual representation of the day of the week (first character is uppercase),
  к: short textual representation of the day of the week,
  К: short textual representation of the day of the week (first character is uppercase),
  м: full textual representation of a month
  М: full textual representation of a month (first character is uppercase),
  л: short textual representation of a month
  Л: short textual representation of a month (first character is uppercase),
*/
function date_ru($formatum, $timestamp=0) {
  if (($timestamp <= -1) || !is_numeric($timestamp)) return '';
  $q['д'] = array(-1 => 'w', 'воскресенье','понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота');
  $q['Д'] = array(-1 => 'w', 'Воскресенье','Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота');
  $q['к'] = array(-1 => 'w', 'вс','пн', 'вт', 'ср', 'чт', 'пт', 'сб');
  $q['К'] = array(-1 => 'w',  'Вс','Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб');
  $q['м'] = array(-1 => 'n', '', 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря');
  $q['М'] = array(-1 => 'n', '', 'Января', 'Февраля', 'Март', 'Апреля', 'Май', 'Июня', 'Июля', 'Август', 'Сентября', 'Октября', 'Ноября', 'Декабря');
  $q['л'] = array(-1 => 'n', '', 'янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек');
  $q['Л'] = array(-1 => 'n', '',  'Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек');

  if ($timestamp == 0)
    $timestamp = time();
  $temp = '';
  $i = 0;
  while ( (strpos($formatum, 'д', $i) !== FALSE) || (strpos($formatum, 'Д', $i) !== FALSE) || 
          (strpos($formatum, 'к', $i) !== FALSE) || (strpos($formatum, 'К', $i) !== FALSE) || 
          (strpos($formatum, 'м', $i) !== FALSE) || (strpos($formatum, 'М', $i) !== FALSE) || 
          (strpos($formatum, 'л', $i) !== FALSE) || (strpos($formatum, 'Л', $i) !== FALSE)) {
    $ch['д']=strpos($formatum, 'д', $i);
    $ch['Д']=strpos($formatum, 'Д', $i);
    $ch['к']=strpos($formatum, 'к', $i);
    $ch['К']=strpos($formatum, 'К', $i);
    $ch['м']=strpos($formatum, 'м', $i);
    $ch['М']=strpos($formatum, 'М', $i);
    $ch['л']=strpos($formatum, 'л', $i);
    $ch['Л']=strpos($formatum, 'Л', $i);
    foreach ($ch as $k=>$v)
      if ($v === FALSE)
        unset($ch[$k]);
    $a = min($ch);
    $temp .= date(substr($formatum, $i, $a-$i), $timestamp) . $q[$formatum[$a]][date($q[$formatum[$a]][-1], $timestamp)];
    $i = $a+1;
  }
  $temp .= date(substr($formatum, $i), $timestamp);
  return $temp;
}

echo 'Сегодня '.date_ru('Д, d л Y');
?>
 

xav0989

Community Public Relation
Community Support
Messages
4,467
Reaction score
95
Points
0
There is an incompability in the charset used in the php file, the one parsed and the one displayed by the browser. Try adding a htmlentities in your echo function:
PHP:
echo htmlentities('Сегодня '.date_ru('Д, d л Y'));

However, use the utf8_encode function if the results are not sent to a browser.
 
Last edited:

espfutbol98

New Member
Messages
200
Reaction score
2
Points
0
PHP:
//I tried:
echo  htmlentities('Сегодня '.date_ru('Д, d л Y'));
//and
echo utf8_encode(htmlentities('Сегодня '.date_ru('Д, d л Y')));
//but i still got random characters. the code you see above is
//the only thing I have in the file so charsets can't really be 
//getting confused
 

xav0989

Community Public Relation
Community Support
Messages
4,467
Reaction score
95
Points
0
check the charset in which the file is saved and the charset that the server is receiving. Try setting it to ISO-8859-1.
 

espfutbol98

New Member
Messages
200
Reaction score
2
Points
0
In ISO-8859-1, the code returns: СегоднÑ￾ ”, 04. » 2009
In UTF-8, it returns Сегодня �, 04. � 2009 (When both the browser and file are in UTF-8)

Are you guys sure it is a charset problem? I think it might be something wrong with the code. Could any of it have an error or be outdated?
 

garrettroyce

Community Support
Community Support
Messages
5,609
Reaction score
250
Points
63
I'm pretty sure it's an encoding error. It looks like the UTF-8 is pretty close, there's probably use some minor tweak you have to do yet.

UTF-8 is supposed to be able to encode any character in any language.
 

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
PHP does not handle Unicode well.

For example:

PHP:
$test = 'Д, d л Y' ;

echo strlen( $test ) ;

Yields 20.

I was going to suggest adding

PHP:
declare(encoding="utf-8");

at the top of the script, but that feature did not come in until PHP 5.3
 
Last edited:

espfutbol98

New Member
Messages
200
Reaction score
2
Points
0
Thanks for the tip descalzo but I have PHP 5.2.9. I also tried putting the utf8_encode() in front of the arrays but it didn't change anything either.
 

garrettroyce

Community Support
Community Support
Messages
5,609
Reaction score
250
Points
63
Last edited:

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
This is theoretically correct since the characters used are multibyte characters and can take up to four bytes each, though logically it makes less sense.

And that is exactly why this code is broken.

PHP:
$temp .= date(substr($formatum, $i, $a-$i), $timestamp) . 
     $q[$formatum[$a]][date($q[$formatum[$a]][-1], $timestamp)];

Specifically (there may be other places, this is one I found), where he uses

PHP:
$formatum[$a]

He is expecting this to be a multibyte character, so he can use it as a key to the $q hash.
But PHP only gives him one byte.
 

garrettroyce

Community Support
Community Support
Messages
5,609
Reaction score
250
Points
63
Theoretically, this code worked on someone else's computer, otherwise I don't think the original author would have pasted it all over the internet. So either a) it's from a version of PHP that is different than X10's version and has some subtle difference, or b) you're missing something.

I don't know if PHP compiled in different languages changes how it behaves. Maybe in the original language PHP didn't treat the chars as multibytes.
 
Last edited:

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
Theoretically, this code worked on someone else's computer, otherwise I don't think the original author would have pasted it all over the internet. So either a) it's from a version of PHP that is different than X10's version and has some subtle difference, or b) you're missing something.

I don't know if PHP compiled in different languages changes how it behaves. Maybe in the original language PHP didn't treat the chars as multibytes.

Well, as I said, PHP 5.3 does have allow a
declare(encoding='utf-8');
statement. Perhaps that is what the other guy used (the only posting for the above code was July of this year).

From their website, PHP has always treated chars as single bytes and will do so until PHP 6.

But there is a hack....

PHP:
/*
  these are the russian additional format characters
  д: full textual representation of the day of the week
  Д: full textual representation of the day of the week (first character is uppercase),
  к: short textual representation of the day of the week,
  К: short textual representation of the day of the week (first character is uppercase),
  м: full textual representation of a month
  М: full textual representation of a month (first character is uppercase),
  л: short textual representation of a month
  Л: short textual representation of a month (first character is uppercase),
*/
function date_ru($formatum, $timestamp=0) {
  if (($timestamp <= -1) || !is_numeric($timestamp)) return '';
  $q['д'] = array(-1 => 'w', 'воскресенье','понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота');
  $q['Д'] = array(-1 => 'w', 'Воскресенье','Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота');
  $q['к'] = array(-1 => 'w', 'вс','пн', 'вт', 'ср', 'чт', 'пт', 'сб');
  $q['К'] = array(-1 => 'w',  'Вс','Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб');
  $q['м'] = array(-1 => 'n', '', 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря');
  $q['М'] = array(-1 => 'n', '', 'Января', 'Февраля', 'Март', 'Апреля', 'Май', 'Июня', 'Июля', 'Август', 'Сентября', 'Октября', 'Ноября', 'Декабря');
  $q['л'] = array(-1 => 'n', '', 'янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек');
  $q['Л'] = array(-1 => 'n', '',  'Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек');
  if ($timestamp == 0)
    $timestamp = time();
  $temp = '';
  $i = 0;
  while ( (strpos($formatum, 'д', $i) !== FALSE) || (strpos($formatum, 'Д', $i) !== FALSE) || 
          (strpos($formatum, 'к', $i) !== FALSE) || (strpos($formatum, 'К', $i) !== FALSE) || 
          (strpos($formatum, 'м', $i) !== FALSE) || (strpos($formatum, 'М', $i) !== FALSE) || 
          (strpos($formatum, 'л', $i) !== FALSE) || (strpos($formatum, 'Л', $i) !== FALSE)) {
 

    $ch['д']=strpos($formatum, 'д', $i);
    $ch['Д']=strpos($formatum, 'Д', $i);
    $ch['к']=strpos($formatum, 'к', $i);
    $ch['К']=strpos($formatum, 'К', $i);
    $ch['м']=strpos($formatum, 'м', $i);
    $ch['М']=strpos($formatum, 'М', $i);
    $ch['л']=strpos($formatum, 'л', $i);
    $ch['Л']=strpos($formatum, 'Л', $i);
    $min = 2000000 ;
    $char = '' ;
    foreach ($ch as $k=>$v){
      if ($v === FALSE){
        unset($ch[$k]);
      } else {
        if( $ch[ $k ] < $min ){
            $min = $ch[ $k ] ;
            $char = $k ;
       }
      }
    }
    $a = $min ; 
    $temp .= date(substr($formatum, $i, $a-$i), $timestamp)  . $q[$char][date($q[$char][-1], $timestamp)]  ;
    $i = $a+ strlen( $char );
  }
  $temp .= date(substr($formatum, $i), $timestamp);
  return $temp;
}
echo 'Сегодня -->'.date_ru('Д, d л Y');
Edit:
,or b) you're missing something.

Turns out I missed the most obvious.

Take the code and save the page using koi8-r. (or any single byte encoding that covers latin and cyrillic)
Add the metatag:

HTML:
<meta http-equiv="content-type" content="text-html; charset=koi8-r">

And it works without changing the code.
 
Last edited:

espfutbol98

New Member
Messages
200
Reaction score
2
Points
0
Alright it works great! thanks everybody. is there by chance a way to change the encoding to koi8-r in something like Notepad2?
 
Top