OSDN Git Service

Merge branch 'skinnable-master' of ssh://shizuki@git.sourceforge.jp/gitroot/nucleus...
[nucleus-jp/nucleus-next.git] / nucleus / libs / i18n.php
index b589db0..6e89097 100644 (file)
-<?php
-/**
- * i18n class for Nucleus CMS
- * written by Takashi Sakamoto as of Feb 03, 2012
- * 
- * This includes wrapper functions of iconv and mbstring
- * for multibyte processing and includes parameters related to locale.
- * 
- * 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 the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * (see nucleus/documentation/index.html#license for more info)
- *
- * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2011 The Nucleus Group
- * @version $Id: i18n.php 1673 2012-02-26 04:21:21Z sakamocchi $
- */
-class i18n
-{
-       static private $mode = FALSE;
-       
-       static private $charset = '';
-       static private $language = '';
-       static private $script = '';
-       static private $region = '';
-       static private $locale_list = array();
-       static private $timezone = 'UTC';
-       
-       /**
-        * i18n::init
-        * Initializing i18n class
-        * 
-        * @static
-        * @param       string  $charset        character set
-        * @return      boolean 
-        */
-       static public function init($charset, $dir)
-       {
-               /* i18n is already initialized */
-               if ( self::$mode )
-               {
-                       return TRUE;
-               }
-               
-               /* make locale list in this Nucleus CMS */
-               if ( ($handle = opendir($dir)) === FALSE )
-               {
-                       return FALSE;
-               }
-               while ($filename = readdir($handle))
-               {
-                       if (preg_match("#^(.+_.+_.+)\.{$charset}\.php$#", $filename, $matches) )
-                       {
-                               if ( !in_array($matches[1], self::$locale_list) )
-                               {
-                                       self::$locale_list[] = $matches[1];
-                               }
-                       }
-               }
-               closedir($handle);
-               
-               /* set i18n backend and validate character set */
-               if ( extension_loaded('iconv') )
-               {
-                       /* this is just for checking the charset. */
-                       if ( iconv_set_encoding('internal_encoding', $charset)
-                        && iconv_set_encoding('output_encoding', $charset)
-                        && iconv_set_encoding('internal_encoding', $charset) )
-                       {
-                               self::$charset = $charset;
-                               self::$mode = 'iconv';
-                       }
-               }
-               else if ( extension_loaded('mbstring') )
-               {
-                       /* this is just for checking the charset. */
-                       if ( mb_http_output($charset)
-                        && mb_internal_encoding($charset)
-                        && mb_regex_encoding($charset) )
-                       {
-                               self::$charset = $charset;
-                               self::$mode = 'mbstring';
-                       }
-               }
-               
-               return TRUE;
-       }
-       
-       /**
-        * i18n::get_available_locale_list
-        * return available locale list with current charset
-        * 
-        * @static
-        * @param       void
-        * @return      array   available locale list
-        */
-       static public function get_available_locale_list()
-       {
-               return self::$locale_list;
-       }
-       
-       /**
-        * i18n::get_current_charset
-        * return current charset
-        * 
-        * @static
-        * @param       void
-        * @return      string  $charset        current character set
-        */
-       static public function get_current_charset()
-       {
-               return self::$charset;
-       }
-       
-       /**
-        * i18n::set_locale
-        * Set current locale
-        * 
-        * NOTE:
-        * naming rule is "$language_$script_$region.$charset.php", refer to RFC 5646.
-        * @link http://www.ietf.org/rfc/rfc5646.txt
-        * @see 2.  The Language Tag
-        * 
-        * @static
-        * @param       string  $locale
-        * @return      bool    TRUE/FALSE
-        * 
-        */
-       static public function set_current_locale($locale)
-       {
-               if ( preg_match('#^(.+)_(.+)_(.+)$#', $locale, $match) )
-               {
-                       self::$language = $match[1];
-                       self::$script   = $match[2];
-                       self::$region   = $match[3];
-                       return TRUE;
-               }
-               return FALSE;
-       }
-       
-       /**
-        * i18n::get_locale
-        * Get current locale
-        * 
-        * @static
-        * @param       void
-        * @return      $locale
-        */
-       static public function get_current_locale()
-       {
-               $elements = array(self::$language, self::$script, self::$region);
-               return implode('_', $elements);
-       }
-       
-       /**
-        * i18n::confirm_default_date_timezone
-        * to avoid E_NOTICE or E_WARNING generated when every calling to a date/time function.
-        * 
-        * NOTE:
-        * Some private servers are lack of its timezone setting
-        * http://www.php.net/manual/en/function.date-default-timezone-set.php
-        * 
-        * @static
-        * @param       void
-        * @return      void
-        */
-       static public function confirm_default_date_timezone()
-       {
-               if ( function_exists('date_default_timezone_get') 
-                && FALSE !== ($timezone = @date_default_timezone_get()))
-               {
-                       self::$timezone = $timezone;
-               }
-               if (function_exists('date_default_timezone_set')) {
-                        @date_default_timezone_set(self::$timezone);
-               }
-               return;
-       }
-       
-       /**
-        * i18n::get_current_date_timezone()
-        * get current timezone
-        * 
-        * @static
-        * @param       void
-        * @return      $timezone
-        */
-       static public function get_date_timezone()
-       {
-               return self::$timezone;
-       }
-       
-       /**
-        * i18n::convert
-        * character set converter
-        * 
-        * @static
-        * @param       string  $string target string binary
-        * @param       string  $from   original character set encoding
-        * @param       string  $to     target character set encoding
-        * @return      string  converted string
-        */
-       static public function convert($string, $from, $to='')
-       {
-               if ( $to == '' )
-               {
-                       $to = self::$charset;
-               }
-               
-               if ( self::$mode == 'iconv' )
-               {
-                       $string = iconv($from, $to.'//TRANSLIT', $string);
-               }
-               else if ( self::$mode == 'mbstring' )
-               {
-                       $string = mb_convert_encoding($string, $to, $from);
-               }
-               return (string) $string;
-       }
-       
-       /**
-        * i18n::strlen
-        * strlen wrapper
-        * 
-        * @static
-        * @param       string  $string target string
-        * @return      integer the number of letters
-        */
-       static public function strlen($string)
-       {
-               $length = 0;
-               if ( self::$mode == 'iconv' )
-               {
-                       $length = iconv_strlen($string, self::$charset);
-               }
-               else if ( self::$mode == 'mbstring' )
-               {
-                       $length = mb_strlen($string, self::$charset);
-               }
-               else
-               {
-                       $length = strlen($string);
-               }
-               return (integer) $length;
-       }
-       
-       /**
-        * i18n::strpos
-        * strpos wrapper
-        * 
-        * @static
-        * @param       string  $haystack       string to search
-        * @param       string  $needle string for search
-        * @param       string  $offset the position from which the search should be performed. 
-        * @return      integer/FALSE   the numeric position of the first occurrence of needle in haystack
-        */
-       static public function strpos($haystack, $needle, $offset=0)
-       {
-               $position = 0;
-               if ( self::$mode == 'iconv' )
-               {
-                       $position = iconv_strpos($haystack, $needle, $offset, self::$charset);
-               }
-               else if ( self::$mode == 'mbstring' )
-               {
-                       $position = mb_strpos($haystack, $needle, $offset, self::$charset);
-               }
-               else
-               {
-                       $position = strpos($haystack, $needle, $offset);
-               }
-               
-               if ( $position !== FALSE)
-               {
-                       $position = (integer) $position;
-               }
-               return $position;
-       }
-       
-       /**
-        * i18n::strrpos
-        * strrpos wrapper
-        * 
-        * @static
-        * @param       string  $haystack       string to search
-        * @param       string  $needle string for search
-        * @return      integer/FALSE   the numeric position of the last occurrence of needle in haystack
-        */
-       static public function strrpos ($haystack, $needle)
-       {
-               $position = 0;
-               if ( self::$mode == 'iconv' )
-               {
-                       $position = iconv_strrpos($haystack, $needle, self::$charset);
-               }
-               else if ( self::$mode == 'mbstring' )
-               {
-                       $position = mb_strrpos($haystack, $needle, 0, self::$charset);
-               }
-               else
-               {
-                       $position = strrpos($haystack, $needle, 0);
-               }
-               
-               if ( $position !== FALSE)
-               {
-                       $position = (integer) $position;
-               }
-               return $position;
-       }
-       
-       /**
-        * i18n::substr
-        * substr wrapper
-        * 
-        * @static
-        * @param       string  $string string to be cut
-        * @param       string  $start  the position of starting
-        * @param       integer $length the length to be cut
-        * @return      string  the extracted part of string
-        */
-       static public function substr($string, $start, $length=0)
-       {
-               $return = '';
-               if ( self::$mode == 'iconv' )
-               {
-                       $return = iconv_substr($string, $start, $length, self::$charset);
-               }
-               else if ( self::$mode == 'mbstring' )
-               {
-                       $return = mb_substr($string, $start, $length, self::$charset);
-               }
-               else
-               {
-                       $return = strrpos($string, $start, $length);
-               }
-               return (string) $return;
-       }
-       
-       /**
-        * i18n::explode()
-        * explode function based on multibyte processing with non-pcre regular expressions
-        * 
-        * NOTE: we SHOULD use preg_split function instead of this,
-        *  and I hope this is obsoleted near future...
-        *  
-        *  preg_split()
-        *  http://www.php.net/manual/en/function.preg-split.php
-        * 
-        * @static
-        * @param       string  $delimiter      singlebyte or multibyte delimiter
-        * @param       string  $target target string
-        * @param       integer $limit  the number of index for returned array
-        * @return      array   array splitted by $delimiter
-        */
-       static public function explode($delimiter, $target, $limit=0)
-       {
-               $array = array();
-               $preg_delimiter = '#' . preg_quote($delimiter, '#') . '#';
-               if ( preg_match($preg_delimiter, $target) === 0 )
-               {
-                       return (array) $target;
-               }
-               for ( $count=0; $limit == 0 || $count < $limit; $count++ )
-               {
-                       $offset = self::strpos($target, $delimiter);
-                       if ( $array != array() && $offset == 0 )
-                       {
-                               $array[] = $target;
-                               break;
-                       }
-                       $array[]        = self::substr($target, 0, $offset);
-                       $length = self::strlen($target) - $offset;
-                       $target = self::substr($target, $offset+1, $length);
-                       continue;
-               }
-               return (array) $array;
-       }
-       
-       /**
-        * i18n::strftime
-        * strftime function based on multibyte processing
-        * 
-        * @static
-        * @param       string  $format format with singlebyte or multibyte
-        * @param       timestamp       $timestamp      UNIX timestamp
-        * @return      string  formatted timestamp
-        */
-       static public function strftime($format, $timestamp='')
-       {
-               $formatted = '';
-               
-               if ( $timestamp == '' )
-               {
-                       $timestamp = time();
-               }
-               
-               if ( $format == '%%' )
-               {
-                       return '%';
-               }
-               else if ( preg_match('#%[^%]#', $format) === 0 )
-               {
-                       return $format;
-               }
-               
-               $format = trim(preg_replace('#(%[^%])#', ',$1,', $format), ',');
-               $elements = preg_split('#,#', $format);
-               
-               foreach ( $elements as $element )
-               {
-                       if ( preg_match('#(%[^%])#', $element) )
-                       {
-                               $formatted .= strftime($element, $timestamp);
-                       }
-                       else if ( $element == '%%' )
-                       {
-                               $formatted .= '%';
-                       }
-                       else
-                       {
-                               $formatted .= $element;
-                       }
-               }
-               
-               return (string) $formatted;
-       }
-       
-       /**
-        * i18n::formatted_datetime()
-        * return formatted datetime string
-        * 
-        * Date and Time Formats
-        * @link        http://www.w3.org/TR/NOTE-datetime
-        * 
-        * Working with Time Zones
-        * @link        http://www.w3.org/TR/timezone/
-        * 
-        * @param       String  $format timezone format
-        * @param       String  $timestamp      UNIX timestamp
-        * @param       String  $default_format default timezone format
-        * @param       Integer $offset timestamp offset
-        * @return      String  formatted datetime
-        */
-       static public function formatted_datetime($format, $timestamp, $default_format, $offset)
-       {
-               $suffix = '';
-               $string = '';
-               
-               switch ( $format )
-               {
-                       case 'rfc822':
-                               $format = 'D, j M Y H:i:s ';
-                               if ( $offset < 0 )
-                               {
-                                       $suffix = '-';
-                                       $offset = -$offset;
-                               }
-                               else
-                               {
-                                       $suffix = '+';
-                               }
-                               
-                               $suffix .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
-                               break;
-                       case 'rfc822GMT':
-                               $format = 'D, j M Y H:i:s ';
-                               $timestamp -= $offset;
-                               $suffix = 'GMT';
-                               break;
-                       case 'utc':
-                               $timestamp -= $offset;
-                               $format = 'Y-m-d\TH:i:s\Z';
-                               $suffix = '';
-                               break;
-                       case 'iso8601':
-                               $format = 'Y-m-d\TH:i:s';
-                               if ( $offset < 0 )
-                               {
-                                       $suffix = '-';
-                                       $offset = -$offset;
-                               }
-                               else
-                               {
-                                       $suffix = '+';
-                               }
-                               $suffix .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
-                               break;
-                       case '':
-                               $format = $default_format;
-                               $suffix = '';
-                               break;
-                       default:
-                               $suffix = 0;
-                               break;
-               }
-               return i18n::strftime($format, $timestamp) . $suffix;
-       }
-       
-       /**
-        * i18n::convert_locale_to_old_language_file_name()
-        * NOTE: this should be obsoleted near future.
-        * 
-        * @static
-        * @param       string  $target_locale  locale name as language_script_region
-        * @return      string  old translation file name
-        */
-       static public function convert_locale_to_old_language_file_name($target_locale)
-       {
-               $target_language = '';
-               foreach ( self::$lang_refs as $language => $locale )
-               {
-                       if ( preg_match('#-#', $language) )
-                       {
-                               if ( $target_locale . '.' . self::$charset == $locale )
-                               {
-                                       $target_language = $language;
-                                       break;
-                               }
-                       }
-                       else if ( $target_locale == $locale )
-                       {
-                               $target_language = $language;
-                       }
-               }
-               return $target_language;
-       }
-       
-       /**
-        * i18n::convert_old_language_file_name_to_locale()
-        * NOTE: this should be obsoleted near future.
-        * 
-        * @static
-        * @param       string  $target_language        old translation file name
-        * @return      string  locale name as language_script_region
-        */
-       static public function convert_old_language_file_name_to_locale($target_language)
-       {
-               $target_locale = '';
-               foreach ( self::$lang_refs as $language => $locale )
-               {
-                       if ( $target_language == $language )
-                       {
-                               if ( preg_match('#^(.+)\.(.+)$#', $locale, $match) )
-                               {
-                                       $target_locale = $match[1];
-                               }
-                               else
-                               {
-                                       $target_locale = $locale;
-                               }
-                               break;
-                       }
-               }
-               return $target_locale;
-       }
-       
-       /**
-        * i18n::$lang_refs
-        * reference table to convert old and new way to name translation files.
-        * NOTE: this should be obsoleted as soon as possible.
-        * 
-        * @static
-        */
-       static private $lang_refs = array(
-               "english"               => "en_Latn_US",
-               "english-utf8"  => "en_Latn_US.UTF-8",
-               "bulgarian"     => "bg_Cyrl_BG",
-               "finnish"               => "fi_Latn_FU",
-               "catalan"               => "ca_Latn_ES",
-               "french"                => "fr_Latn_FR",
-               "russian"               => "ru_Cyrl_RU",
-               "chinese"               => "zh_Hans_CN",
-               "simchinese"    => "zh_Hans_CN",
-               "chineseb5"     => "zh_Hant_TW",
-               "traditional_chinese"   =>      "zh_Hant_TW",
-               "galego"                => "gl_Latn_ES",
-               "german"                => "de_Latn_DE",
-               "korean-utf"    => "ko_Kore_KR.UTF-8",
-               "korean-euc-kr" => "ko_Kore_KR.EUC-KR",
-               "slovak"                => "sk_Latn_SK",
-               "czech"         => "cs_Latn_CZ",
-               "hungarian"     => "hu_Latn_HU",
-               "latvian"               => "lv_Latn_LV",
-               "nederlands"    => "nl_Latn_NL",
-               "italiano"              => "it_Latn_IT",
-               "persian"               => "fa_Arab_IR",
-               "spanish"               => "es_Latn_ES",
-               "spanish-utf8"  => "es_Latn_ES.UTF-8",
-               "japanese-euc"  => "ja_Jpan_JP.EUC-JP",
-               "japanese-utf8" => "ja_Jpan_JP.UTF-8",
-               "portuguese_brazil"     => "pt_Latn_BR"
-       );
-}
+<?php\r
+/**\r
+ * i18n class for Nucleus CMS\r
+ * written by Takashi Sakamoto as of Feb 03, 2012\r
+ * \r
+ * This includes wrapper functions of iconv and mbstring\r
+ * for multibyte processing and includes parameters related to locale.\r
+ * \r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * (see nucleus/documentation/index.html#license for more info)\r
+ *\r
+ * @license http://nucleuscms.org/license.txt GNU General Public License\r
+ * @copyright Copyright (C) 2002-2011 The Nucleus Group\r
+ * @version $Id: i18n.php 1678 2012-02-26 07:31:36Z sakamocchi $\r
+ */\r
+class i18n\r
+{\r
+       static private $mode = FALSE;\r
+       \r
+       static private $charset = '';\r
+       static private $language = '';\r
+       static private $script = '';\r
+       static private $region = '';\r
+       static private $locale_list = array();\r
+       static private $timezone = 'UTC';\r
+       \r
+       /**\r
+        * i18n::init\r
+        * Initializing i18n class\r
+        * \r
+        * @static\r
+        * @param       string  $charset        character set\r
+        * @return      boolean \r
+        */\r
+       static public function init($charset, $dir)\r
+       {\r
+               /* i18n is already initialized */\r
+               if ( self::$mode )\r
+               {\r
+                       return TRUE;\r
+               }\r
+               \r
+               /* make locale list in this Nucleus CMS */\r
+               if ( ($handle = opendir($dir)) === FALSE )\r
+               {\r
+                       return FALSE;\r
+               }\r
+               while ($filename = readdir($handle))\r
+               {\r
+                       if (preg_match("#^(.+_.+_.+)\.{$charset}\.php$#", $filename, $matches) )\r
+                       {\r
+                               if ( !in_array($matches[1], self::$locale_list) )\r
+                               {\r
+                                       self::$locale_list[] = $matches[1];\r
+                               }\r
+                       }\r
+               }\r
+               closedir($handle);\r
+               \r
+               /* set i18n backend and validate character set */\r
+               if ( extension_loaded('iconv') )\r
+               {\r
+                       /* this is just for checking the charset. */\r
+                       if ( iconv_set_encoding('internal_encoding', $charset)\r
+                        && iconv_set_encoding('output_encoding', $charset)\r
+                        && iconv_set_encoding('internal_encoding', $charset) )\r
+                       {\r
+                               self::$charset = $charset;\r
+                               self::$mode = 'iconv';\r
+                       }\r
+               }\r
+               else if ( extension_loaded('mbstring') )\r
+               {\r
+                       /* this is just for checking the charset. */\r
+                       if ( mb_http_output($charset)\r
+                        && mb_internal_encoding($charset)\r
+                        && mb_regex_encoding($charset) )\r
+                       {\r
+                               self::$charset = $charset;\r
+                               self::$mode = 'mbstring';\r
+                       }\r
+               }\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       /**\r
+        * i18n::get_available_locale_list\r
+        * return available locale list with current charset\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      array   available locale list\r
+        */\r
+       static public function get_available_locale_list()\r
+       {\r
+               return self::$locale_list;\r
+       }\r
+       \r
+       /**\r
+        * i18n::get_current_charset\r
+        * return current charset\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      string  $charset        current character set\r
+        */\r
+       static public function get_current_charset()\r
+       {\r
+               return self::$charset;\r
+       }\r
+       \r
+       /**\r
+        * i18n::set_locale\r
+        * Set current locale\r
+        * \r
+        * NOTE:\r
+        * naming rule is "$language_$script_$region.$charset.php", refer to RFC 5646.\r
+        * @link http://www.ietf.org/rfc/rfc5646.txt\r
+        * @see 2.  The Language Tag\r
+        * \r
+        * @static\r
+        * @param       string  $locale\r
+        * @return      bool    TRUE/FALSE\r
+        * \r
+        */\r
+       static public function set_current_locale($locale)\r
+       {\r
+               if ( preg_match('#^(.+)_(.+)_(.+)$#', $locale, $match) )\r
+               {\r
+                       self::$language = $match[1];\r
+                       self::$script   = $match[2];\r
+                       self::$region   = $match[3];\r
+                       return TRUE;\r
+               }\r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+        * i18n::get_locale\r
+        * Get current locale\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      $locale\r
+        */\r
+       static public function get_current_locale()\r
+       {\r
+               $elements = array(self::$language, self::$script, self::$region);\r
+               return implode('_', $elements);\r
+       }\r
+       \r
+       /**\r
+        * i18n::confirm_default_date_timezone\r
+        * to avoid E_NOTICE or E_WARNING generated when every calling to a date/time function.\r
+        * \r
+        * NOTE:\r
+        * Some private servers are lack of its timezone setting\r
+        * http://www.php.net/manual/en/function.date-default-timezone-set.php\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      void\r
+        */\r
+       static public function confirm_default_date_timezone()\r
+       {\r
+               if ( function_exists('date_default_timezone_get') \r
+                && FALSE !== ($timezone = @date_default_timezone_get()))\r
+               {\r
+                       self::$timezone = $timezone;\r
+               }\r
+               if (function_exists('date_default_timezone_set')) {\r
+                        @date_default_timezone_set(self::$timezone);\r
+               }\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * i18n::get_current_date_timezone()\r
+        * get current timezone\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      $timezone\r
+        */\r
+       static public function get_date_timezone()\r
+       {\r
+               return self::$timezone;\r
+       }\r
+       \r
+       /**\r
+        * i18n::convert\r
+        * character set converter\r
+        * \r
+        * @static\r
+        * @param       string  $string target string binary\r
+        * @param       string  $from   original character set encoding\r
+        * @param       string  $to     target character set encoding\r
+        * @return      string  converted string\r
+        */\r
+       static public function convert($string, $from, $to='')\r
+       {\r
+               if ( $to == '' )\r
+               {\r
+                       $to = self::$charset;\r
+               }\r
+               \r
+               if ( self::$mode == 'iconv' )\r
+               {\r
+                       $string = iconv($from, $to.'//TRANSLIT', $string);\r
+               }\r
+               else if ( self::$mode == 'mbstring' )\r
+               {\r
+                       $string = mb_convert_encoding($string, $to, $from);\r
+               }\r
+               return (string) $string;\r
+       }\r
+       \r
+       /**\r
+        * i18n::strlen\r
+        * strlen wrapper\r
+        * \r
+        * @static\r
+        * @param       string  $string target string\r
+        * @return      integer the number of letters\r
+        */\r
+       static public function strlen($string)\r
+       {\r
+               $length = 0;\r
+               if ( self::$mode == 'iconv' )\r
+               {\r
+                       $length = iconv_strlen($string, self::$charset);\r
+               }\r
+               else if ( self::$mode == 'mbstring' )\r
+               {\r
+                       $length = mb_strlen($string, self::$charset);\r
+               }\r
+               else\r
+               {\r
+                       $length = strlen($string);\r
+               }\r
+               return (integer) $length;\r
+       }\r
+       \r
+       /**\r
+        * i18n::strpos\r
+        * strpos wrapper\r
+        * \r
+        * @static\r
+        * @param       string  $haystack       string to search\r
+        * @param       string  $needle string for search\r
+        * @param       integer $offset the position from which the search should be performed. \r
+        * @return      integer/FALSE   the numeric position of the first occurrence of needle in haystack\r
+        */\r
+       static public function strpos($haystack, $needle, $offset=0)\r
+       {\r
+               $position = 0;\r
+               if ( self::$mode == 'iconv' )\r
+               {\r
+                       $position = iconv_strpos($haystack, $needle, $offset, self::$charset);\r
+               }\r
+               else if ( self::$mode == 'mbstring' )\r
+               {\r
+                       $position = mb_strpos($haystack, $needle, $offset, self::$charset);\r
+               }\r
+               else\r
+               {\r
+                       $position = strpos($haystack, $needle, $offset);\r
+               }\r
+               \r
+               if ( $position !== FALSE)\r
+               {\r
+                       $position = (integer) $position;\r
+               }\r
+               return $position;\r
+       }\r
+       \r
+       /**\r
+        * i18n::strrpos\r
+        * strrpos wrapper\r
+        * \r
+        * @static\r
+        * @param       string  $haystack       string to search\r
+        * @param       string  $needle string for search\r
+        * @return      integer/FALSE   the numeric position of the last occurrence of needle in haystack\r
+        */\r
+       static public function strrpos ($haystack, $needle)\r
+       {\r
+               $position = 0;\r
+               if ( self::$mode == 'iconv' )\r
+               {\r
+                       $position = iconv_strrpos($haystack, $needle, self::$charset);\r
+               }\r
+               else if ( self::$mode == 'mbstring' )\r
+               {\r
+                       $position = mb_strrpos($haystack, $needle, 0, self::$charset);\r
+               }\r
+               else\r
+               {\r
+                       $position = strrpos($haystack, $needle, 0);\r
+               }\r
+               \r
+               if ( $position !== FALSE)\r
+               {\r
+                       $position = (integer) $position;\r
+               }\r
+               return $position;\r
+       }\r
+       \r
+       /**\r
+        * i18n::substr\r
+        * substr wrapper\r
+        * \r
+        * @static\r
+        * @param       string  $string string to be cut\r
+        * @param       string  $start  the position of starting\r
+        * @param       integer $length the length to be cut\r
+        * @return      string  the extracted part of string\r
+        */\r
+       static public function substr($string, $start, $length=0)\r
+       {\r
+               $return = '';\r
+               if ( self::$mode == 'iconv' )\r
+               {\r
+                       $return = iconv_substr($string, $start, $length, self::$charset);\r
+               }\r
+               else if ( self::$mode == 'mbstring' )\r
+               {\r
+                       $return = mb_substr($string, $start, $length, self::$charset);\r
+               }\r
+               else\r
+               {\r
+                       $return = strrpos($string, $start, $length);\r
+               }\r
+               return (string) $return;\r
+       }\r
+       \r
+       /**\r
+        * i18n::strftime\r
+        * strftime function based on multibyte processing\r
+        * \r
+        * @static\r
+        * @param       string  $format format with singlebyte or multibyte\r
+        * @param       timestamp       $timestamp      UNIX timestamp\r
+        * @return      string  formatted timestamp\r
+        */\r
+       static public function strftime($format, $timestamp='')\r
+       {\r
+               $formatted = '';\r
+               \r
+               if ( $timestamp == '' )\r
+               {\r
+                       $timestamp = time();\r
+               }\r
+               \r
+               if ( $format == '%%' )\r
+               {\r
+                       return '%';\r
+               }\r
+               else if ( preg_match('#%[^%]#', $format) === 0 )\r
+               {\r
+                       return $format;\r
+               }\r
+               \r
+               $format = trim(preg_replace('#(%[^%])#', ',$1,', $format), ',');\r
+               $elements = preg_split('#,#', $format);\r
+               \r
+               foreach ( $elements as $element )\r
+               {\r
+                       if ( preg_match('#(%[^%])#', $element) )\r
+                       {\r
+                               $formatted .= strftime($element, $timestamp);\r
+                       }\r
+                       else if ( $element == '%%' )\r
+                       {\r
+                               $formatted .= '%';\r
+                       }\r
+                       else\r
+                       {\r
+                               $formatted .= $element;\r
+                       }\r
+               }\r
+               \r
+               return (string) $formatted;\r
+       }\r
+       \r
+       /**\r
+        * i18n::formatted_datetime()\r
+        * return formatted datetime string\r
+        * \r
+        * Date and Time Formats\r
+        * @link        http://www.w3.org/TR/NOTE-datetime\r
+        * \r
+        * Working with Time Zones\r
+        * @link        http://www.w3.org/TR/timezone/\r
+        * \r
+        * @param       String  $format time expression format\r
+        * @param       String  $timestamp      UNIX timestamp\r
+        * @param       Integer $offset timestamp offset\r
+        * @return      String  formatted datetime\r
+        */\r
+       static public function formatted_datetime($format, $timestamp, $offset=0)\r
+       {\r
+               $suffix = '';\r
+               $string = '';\r
+               \r
+               switch ( $format )\r
+               {\r
+                       case 'mysql':\r
+                               /*\r
+                                * MySQL 5.0 Reference Manual\r
+                                *  10.3.1. The DATE, DATETIME, and TIMESTAMP Types\r
+                                *   http://dev.mysql.com/doc/refman/5.0/en/datetime.html\r
+                                */\r
+                               $timestamp += $offset;\r
+                               $format = '%Y-%m-%d %H:%M:%S';\r
+                               $suffix ='';\r
+                               break;\r
+                       case 'rfc822':\r
+                               /*\r
+                                * RFC 822: STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES\r
+                                *  5.  DATE AND TIME SPECIFICATION\r
+                                *   http://www.ietf.org/rfc/rfc0822.txt\r
+                                */\r
+                               $format = '%a, %d %m %y %H:%M:%S ';\r
+                               if ( $offset < 0 )\r
+                               {\r
+                                       $suffix = '-';\r
+                                       $offset = -$offset;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $suffix = '+';\r
+                               }\r
+                               \r
+                               $suffix .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );\r
+                               break;\r
+                       case 'rfc822GMT':\r
+                               /*\r
+                                * RFC 822: STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES\r
+                                *  5.  DATE AND TIME SPECIFICATION\r
+                                *   http://www.ietf.org/rfc/rfc0822.txt\r
+                                */\r
+                               $format = '%a, %d %m %y %H:%M:%S ';\r
+                               $timestamp -= $offset;\r
+                               $suffix = 'GMT';\r
+                               break;\r
+                       case 'iso8601':\r
+                       case 'rfc3339':\r
+                               /*\r
+                                * RFC3339: Date and Time on the Internet: Timestamps\r
+                                *  5. Date and Time format\r
+                                *   http://www.ietf.org/rfc/rfc3339.txt\r
+                                */\r
+                               $format = '%Y-%m-%dT%H:%M:%S';\r
+                               if ( $offset < 0 )\r
+                               {\r
+                                       $suffix = '-';\r
+                                       $offset = -$offset;\r
+                               }\r
+                               else\r
+                               {\r
+                                       $suffix = '+';\r
+                               }\r
+                               $suffix .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );\r
+                               break;\r
+                       case 'utc':\r
+                       case 'iso8601UTC':\r
+                       case 'rfc3339UTC':\r
+                               /*\r
+                                * RFC3339: Date and Time on the Internet: Timestamps\r
+                                *  5. Date and Time format\r
+                                *   http://www.ietf.org/rfc/rfc3339.txt\r
+                                */\r
+                               $timestamp -= $offset;\r
+                               $format = '%Y-%m-%dT%H:%M:%SZ';\r
+                               $suffix = '';\r
+                               break;\r
+                       case '':\r
+                               $format = '%X %x';\r
+                               $offset = '';\r
+                               break;\r
+                       default:\r
+                               $suffix = '';\r
+                               break;\r
+               }\r
+               return i18n::strftime($format, $timestamp) . $suffix;\r
+       }\r
+       \r
+       /**\r
+        * i18n::convert_locale_to_old_language_file_name()\r
+        * NOTE: this should be obsoleted near future.\r
+        * \r
+        * @static\r
+        * @param       string  $target_locale  locale name as language_script_region\r
+        * @return      string  old translation file name\r
+        */\r
+       static public function convert_locale_to_old_language_file_name($target_locale)\r
+       {\r
+               $target_language = '';\r
+               foreach ( self::$lang_refs as $language => $locale )\r
+               {\r
+                       if ( preg_match('#-#', $language) )\r
+                       {\r
+                               if ( $target_locale . '.' . self::$charset == $locale )\r
+                               {\r
+                                       $target_language = $language;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       else if ( $target_locale == $locale )\r
+                       {\r
+                               $target_language = $language;\r
+                       }\r
+               }\r
+               return $target_language;\r
+       }\r
+       \r
+       /**\r
+        * i18n::convert_old_language_file_name_to_locale()\r
+        * NOTE: this should be obsoleted near future.\r
+        * \r
+        * @static\r
+        * @param       string  $target_language        old translation file name\r
+        * @return      string  locale name as language_script_region\r
+        */\r
+       static public function convert_old_language_file_name_to_locale($target_language)\r
+       {\r
+               $target_locale = '';\r
+               foreach ( self::$lang_refs as $language => $locale )\r
+               {\r
+                       if ( $target_language == $language )\r
+                       {\r
+                               if ( preg_match('#^(.+)\.(.+)$#', $locale, $match) )\r
+                               {\r
+                                       $target_locale = $match[1];\r
+                               }\r
+                               else\r
+                               {\r
+                                       $target_locale = $locale;\r
+                               }\r
+                               break;\r
+                       }\r
+               }\r
+               return $target_locale;\r
+       }\r
+       \r
+       /**\r
+        * i18n::$lang_refs\r
+        * reference table to convert old and new way to name translation files.\r
+        * NOTE: this should be obsoleted as soon as possible.\r
+        * \r
+        * @static\r
+        */\r
+       static private $lang_refs = array(\r
+               "english"               => "en_Latn_US",\r
+               "english-utf8"  => "en_Latn_US.UTF-8",\r
+               "bulgarian"     => "bg_Cyrl_BG",\r
+               "finnish"               => "fi_Latn_FU",\r
+               "catalan"               => "ca_Latn_ES",\r
+               "french"                => "fr_Latn_FR",\r
+               "russian"               => "ru_Cyrl_RU",\r
+               "chinese"               => "zh_Hans_CN",\r
+               "simchinese"    => "zh_Hans_CN",\r
+               "chineseb5"     => "zh_Hant_TW",\r
+               "traditional_chinese"   =>      "zh_Hant_TW",\r
+               "galego"                => "gl_Latn_ES",\r
+               "german"                => "de_Latn_DE",\r
+               "korean-utf"    => "ko_Kore_KR.UTF-8",\r
+               "korean-euc-kr" => "ko_Kore_KR.EUC-KR",\r
+               "slovak"                => "sk_Latn_SK",\r
+               "czech"         => "cs_Latn_CZ",\r
+               "hungarian"     => "hu_Latn_HU",\r
+               "latvian"               => "lv_Latn_LV",\r
+               "nederlands"    => "nl_Latn_NL",\r
+               "italiano"              => "it_Latn_IT",\r
+               "persian"               => "fa_Arab_IR",\r
+               "spanish"               => "es_Latn_ES",\r
+               "spanish-utf8"  => "es_Latn_ES.UTF-8",\r
+               "japanese-euc"  => "ja_Jpan_JP.EUC-JP",\r
+               "japanese-utf8" => "ja_Jpan_JP.UTF-8",\r
+               "portuguese_brazil"     => "pt_Latn_BR"\r
+       );\r
+}\r