OSDN Git Service

Merge branch 'skinnable-master'
[nucleus-jp/nucleus-next.git] / nucleus / libs / i18n.php
index 6e89097..9f846df 100644 (file)
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php\r
 /**\r
  * i18n class for Nucleus CMS\r
@@ -20,13 +21,19 @@ class i18n
 {\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 $current_charset = '';\r
+       static private $current_language = '';\r
+       static private $current_script = '';\r
+       static private $current_region = '';\r
+       \r
        static private $locale_list = array();\r
        static private $timezone = 'UTC';\r
        \r
+       static private $forced_charset = '';\r
+       static private $forced_language = '';\r
+       static private $forced_script = '';\r
+       static private $forced_region = '';\r
+       \r
        /**\r
         * i18n::init\r
         * Initializing i18n class\r
@@ -68,7 +75,7 @@ class i18n
                         && iconv_set_encoding('output_encoding', $charset)\r
                         && iconv_set_encoding('internal_encoding', $charset) )\r
                        {\r
-                               self::$charset = $charset;\r
+                               self::$current_charset = $charset;\r
                                self::$mode = 'iconv';\r
                        }\r
                }\r
@@ -79,7 +86,7 @@ class i18n
                         && mb_internal_encoding($charset)\r
                         && mb_regex_encoding($charset) )\r
                        {\r
-                               self::$charset = $charset;\r
+                               self::$current_charset = $charset;\r
                                self::$mode = 'mbstring';\r
                        }\r
                }\r
@@ -110,7 +117,7 @@ class i18n
         */\r
        static public function get_current_charset()\r
        {\r
-               return self::$charset;\r
+               return self::$current_charset;\r
        }\r
        \r
        /**\r
@@ -131,9 +138,9 @@ class i18n
        {\r
                if ( preg_match('#^(.+)_(.+)_(.+)$#', $locale, $match) )\r
                {\r
-                       self::$language = $match[1];\r
-                       self::$script   = $match[2];\r
-                       self::$region   = $match[3];\r
+                       self::$current_language = $match[1];\r
+                       self::$current_script   = $match[2];\r
+                       self::$current_region   = $match[3];\r
                        return TRUE;\r
                }\r
                return FALSE;\r
@@ -149,11 +156,78 @@ class i18n
         */\r
        static public function get_current_locale()\r
        {\r
-               $elements = array(self::$language, self::$script, self::$region);\r
+               $elements = array(self::$current_language, self::$current_script, self::$current_region);\r
+               return implode('_', $elements);\r
+       }\r
+       \r
+       /**\r
+        * i18n::set_forced_locale()\r
+        * Set forced locale\r
+        * \r
+        * @static\r
+        * @param       string  $forced_locale\r
+        * @return      bool    TRUE/FALSE\r
+        * \r
+        */\r
+       static public function set_forced_locale($forced_locale)\r
+       {\r
+               if ( preg_match('#^(.+)_(.+)_(.+)$#', $forced_locale, $match) )\r
+               {\r
+                       self::$forced_language  = $match[1];\r
+                       self::$forced_script    = $match[2];\r
+                       self::$forced_region    = $match[3];\r
+                       return TRUE;\r
+               }\r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+        * i18n::get_forced_locale\r
+        * Get forced locale\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      $forced_locale\r
+        */\r
+       static public function get_forced_locale()\r
+       {\r
+               if ( !self::$forced_language )\r
+               {\r
+                       return '';\r
+               }\r
+               \r
+               $elements = array(self::$forced_language, self::$forced_script, self::$forced_region);\r
                return implode('_', $elements);\r
        }\r
        \r
        /**\r
+        * i18n::set_forced_charset\r
+        * return forced charset\r
+        * \r
+        * @static\r
+        * @param       void    $charset        forced character set\r
+        * @return      void\r
+        */\r
+       static public function set_forced_charset($forced_charset)\r
+       {\r
+               self::$forced_charset = $forced_charset;\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * i18n::get_forced_charset\r
+        * return forced charset\r
+        * \r
+        * @static\r
+        * @param       void\r
+        * @return      string  $charset        forced character set\r
+        */\r
+       static public function get_forced_charset()\r
+       {\r
+               return self::$forced_charset;\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
@@ -205,10 +279,14 @@ class i18n
        {\r
                if ( $to == '' )\r
                {\r
-                       $to = self::$charset;\r
+                       $to = self::$current_charset;\r
                }\r
                \r
-               if ( self::$mode == 'iconv' )\r
+               if ( $from == $to )\r
+               {\r
+                       /* do nothing */\r
+               }\r
+               else if ( self::$mode == 'iconv' )\r
                {\r
                        $string = iconv($from, $to.'//TRANSLIT', $string);\r
                }\r
@@ -220,6 +298,51 @@ class i18n
        }\r
        \r
        /**\r
+        * i18n::convert_handler\r
+        * callable handler for character set converter\r
+        * \r
+        * @static\r
+        * @param       string  $string target string binary\r
+        * @return      void\r
+        */\r
+       static public function convert_handler($string)\r
+       {\r
+               return self::convert($string, self::$current_charset, self::$forced_charset);\r
+       }\r
+       \r
+       /**\r
+        * i18n::convert_array\r
+        * recursively converting array\r
+        * \r
+        * @static\r
+        * @param       array   $array  array to convert\r
+        * @return      void\r
+        */\r
+       static public function convert_array($array, $from, $to='')\r
+       {\r
+               if ( !is_array($array) )\r
+               {\r
+                       $array = self::convert($array, $from, $to);\r
+               }\r
+               else\r
+               {\r
+                       foreach ( $array as $key => $value )\r
+                       {\r
+                               if ( !is_array($value) )\r
+                               {\r
+                                       $array[$key] = self::convert($value, $from, $to);\r
+                               }\r
+                               else\r
+                               {\r
+                                       self::convert_array($array[$key]);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return $array;\r
+       }\r
+       \r
+       /**\r
         * i18n::strlen\r
         * strlen wrapper\r
         * \r
@@ -232,11 +355,11 @@ class i18n
                $length = 0;\r
                if ( self::$mode == 'iconv' )\r
                {\r
-                       $length = iconv_strlen($string, self::$charset);\r
+                       $length = iconv_strlen($string, self::$current_charset);\r
                }\r
                else if ( self::$mode == 'mbstring' )\r
                {\r
-                       $length = mb_strlen($string, self::$charset);\r
+                       $length = mb_strlen($string, self::$current_charset);\r
                }\r
                else\r
                {\r
@@ -260,11 +383,11 @@ class i18n
                $position = 0;\r
                if ( self::$mode == 'iconv' )\r
                {\r
-                       $position = iconv_strpos($haystack, $needle, $offset, self::$charset);\r
+                       $position = iconv_strpos($haystack, $needle, $offset, self::$current_charset);\r
                }\r
                else if ( self::$mode == 'mbstring' )\r
                {\r
-                       $position = mb_strpos($haystack, $needle, $offset, self::$charset);\r
+                       $position = mb_strpos($haystack, $needle, $offset, self::$current_charset);\r
                }\r
                else\r
                {\r
@@ -292,11 +415,11 @@ class i18n
                $position = 0;\r
                if ( self::$mode == 'iconv' )\r
                {\r
-                       $position = iconv_strrpos($haystack, $needle, self::$charset);\r
+                       $position = iconv_strrpos($haystack, $needle, self::$current_charset);\r
                }\r
                else if ( self::$mode == 'mbstring' )\r
                {\r
-                       $position = mb_strrpos($haystack, $needle, 0, self::$charset);\r
+                       $position = mb_strrpos($haystack, $needle, 0, self::$current_charset);\r
                }\r
                else\r
                {\r
@@ -323,13 +446,19 @@ class i18n
        static public function substr($string, $start, $length=0)\r
        {\r
                $return = '';\r
+               \r
+               if ( $length == 0 )\r
+               {\r
+                       $length = self::strlen($string) - $start;\r
+               }\r
+               \r
                if ( self::$mode == 'iconv' )\r
                {\r
-                       $return = iconv_substr($string, $start, $length, self::$charset);\r
+                       $return = iconv_substr($string, $start, $length, self::$current_charset);\r
                }\r
                else if ( self::$mode == 'mbstring' )\r
                {\r
-                       $return = mb_substr($string, $start, $length, self::$charset);\r
+                       $return = mb_substr($string, $start, $length, self::$current_charset);\r
                }\r
                else\r
                {\r
@@ -349,42 +478,10 @@ class i18n
         */\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
+               return preg_replace_callback('/(%[a-z%])/i',\r
+                       create_function('$matches', 'return strftime($matches[1], ' . intval($timestamp) . ');'),\r
+                       $format\r
+               );\r
        }\r
        \r
        /**\r
@@ -505,7 +602,7 @@ class i18n
                {\r
                        if ( preg_match('#-#', $language) )\r
                        {\r
-                               if ( $target_locale . '.' . self::$charset == $locale )\r
+                               if ( $target_locale . '.' . self::$current_charset == $locale )\r
                                {\r
                                        $target_language = $language;\r
                                        break;\r
@@ -585,3 +682,689 @@ class i18n
                "portuguese_brazil"     => "pt_Latn_BR"\r
        );\r
 }\r
+=======
+<?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 1876 2012-06-17 07:33:00Z sakamocchi $
+ */
+class i18n
+{
+       static private $mode = FALSE;
+       
+       static private $current_charset = '';
+       static private $current_language = '';
+       static private $current_script = '';
+       static private $current_region = '';
+       
+       static private $locale_list = array();
+       static private $timezone = 'UTC';
+       
+       static private $forced_charset = '';
+       static private $forced_language = '';
+       static private $forced_script = '';
+       static private $forced_region = '';
+       
+       /**
+        * 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::$current_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::$current_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::$current_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::$current_language = $match[1];
+                       self::$current_script   = $match[2];
+                       self::$current_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::$current_language, self::$current_script, self::$current_region);
+               return implode('_', $elements);
+       }
+       
+       /**
+        * i18n::set_forced_locale()
+        * Set forced locale
+        * 
+        * @static
+        * @param       string  $forced_locale
+        * @return      bool    TRUE/FALSE
+        * 
+        */
+       static public function set_forced_locale($forced_locale)
+       {
+               if ( preg_match('#^(.+)_(.+)_(.+)$#', $forced_locale, $match) )
+               {
+                       self::$forced_language  = $match[1];
+                       self::$forced_script    = $match[2];
+                       self::$forced_region    = $match[3];
+                       return TRUE;
+               }
+               return FALSE;
+       }
+       
+       /**
+        * i18n::get_forced_locale
+        * Get forced locale
+        * 
+        * @static
+        * @param       void
+        * @return      $forced_locale
+        */
+       static public function get_forced_locale()
+       {
+               if ( !self::$forced_language )
+               {
+                       return '';
+               }
+               
+               $elements = array(self::$forced_language, self::$forced_script, self::$forced_region);
+               return implode('_', $elements);
+       }
+       
+       /**
+        * i18n::set_forced_charset
+        * return forced charset
+        * 
+        * @static
+        * @param       void    $charset        forced character set
+        * @return      void
+        */
+       static public function set_forced_charset($forced_charset)
+       {
+               self::$forced_charset = $forced_charset;
+               return;
+       }
+       
+       /**
+        * i18n::get_forced_charset
+        * return forced charset
+        * 
+        * @static
+        * @param       void
+        * @return      string  $charset        forced character set
+        */
+       static public function get_forced_charset()
+       {
+               return self::$forced_charset;
+       }
+       
+       /**
+        * 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::$current_charset;
+               }
+               
+               if ( $from == $to )
+               {
+                       /* do nothing */
+               }
+               else 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::convert_handler
+        * callable handler for character set converter
+        * 
+        * @static
+        * @param       string  $string target string binary
+        * @return      void
+        */
+       static public function convert_handler($string)
+       {
+               return self::convert($string, self::$current_charset, self::$forced_charset);
+       }
+       
+       /**
+        * i18n::convert_array
+        * recursively converting array
+        * 
+        * @static
+        * @param       array   $array  array to convert
+        * @return      void
+        */
+       static public function convert_array($array, $from, $to='')
+       {
+               if ( !is_array($array) )
+               {
+                       $array = self::convert($array, $from, $to);
+               }
+               else
+               {
+                       foreach ( $array as $key => $value )
+                       {
+                               if ( !is_array($value) )
+                               {
+                                       $array[$key] = self::convert($value, $from, $to);
+                               }
+                               else
+                               {
+                                       self::convert_array($array[$key]);
+                               }
+                       }
+               }
+               
+               return $array;
+       }
+       
+       /**
+        * 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::$current_charset);
+               }
+               else if ( self::$mode == 'mbstring' )
+               {
+                       $length = mb_strlen($string, self::$current_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       integer $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::$current_charset);
+               }
+               else if ( self::$mode == 'mbstring' )
+               {
+                       $position = mb_strpos($haystack, $needle, $offset, self::$current_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::$current_charset);
+               }
+               else if ( self::$mode == 'mbstring' )
+               {
+                       $position = mb_strrpos($haystack, $needle, 0, self::$current_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 ( $length == 0 )
+               {
+                       $length = self::strlen($string) - $start;
+               }
+               
+               if ( self::$mode == 'iconv' )
+               {
+                       $return = iconv_substr($string, $start, $length, self::$current_charset);
+               }
+               else if ( self::$mode == 'mbstring' )
+               {
+                       $return = mb_substr($string, $start, $length, self::$current_charset);
+               }
+               else
+               {
+                       $return = strrpos($string, $start, $length);
+               }
+               return (string) $return;
+       }
+       
+       /**
+        * 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='')
+       {
+               return preg_replace_callback('/(%[a-z%])/i',
+                       create_function('$matches', 'return strftime($matches[1], ' . intval($timestamp) . ');'),
+                       $format
+               );
+               }
+               
+       /**
+        * 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 time expression format
+        * @param       String  $timestamp      UNIX timestamp
+        * @param       Integer $offset timestamp offset
+        * @return      String  formatted datetime
+        */
+       static public function formatted_datetime($format, $timestamp, $offset=0)
+       {
+               $suffix = '';
+               $string = '';
+               
+               switch ( $format )
+               {
+                       case 'mysql':
+                               /*
+                                * MySQL 5.0 Reference Manual
+                                *  10.3.1. The DATE, DATETIME, and TIMESTAMP Types
+                                *   http://dev.mysql.com/doc/refman/5.0/en/datetime.html
+                                */
+                               $timestamp += $offset;
+                               $format = '%Y-%m-%d %H:%M:%S';
+                               $suffix ='';
+                               break;
+                       
+                       case 'rfc822':
+                               /*
+                                * RFC 822: STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES
+                                *  5.  DATE AND TIME SPECIFICATION
+                                *   http://www.ietf.org/rfc/rfc0822.txt
+                                */
+                               $format = '%a, %d %m %y %H:%M:%S ';
+                               if ( $offset < 0 )
+                               {
+                                       $suffix = '-';
+                                       $offset = -$offset;
+                               }
+                               else
+                               {
+                                       $suffix = '+';
+                               }
+                               
+                               $suffix .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
+                               break;
+                       case 'rfc822GMT':
+                               /*
+                                * RFC 822: STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES
+                                *  5.  DATE AND TIME SPECIFICATION
+                                *   http://www.ietf.org/rfc/rfc0822.txt
+                                */
+                               $format = '%a, %d %m %y %H:%M:%S ';
+                               $timestamp -= $offset;
+                               $suffix = 'GMT';
+                               break;
+                       case 'iso8601':
+                       case 'rfc3339':
+                               /*
+                                * RFC3339: Date and Time on the Internet: Timestamps
+                                *  5. Date and Time format
+                                *   http://www.ietf.org/rfc/rfc3339.txt
+                                */
+                               $format = '%Y-%m-%dT%H:%M:%S';
+                               if ( $offset < 0 )
+                               {
+                                       $suffix = '-';
+                                       $offset = -$offset;
+                               }
+                               else
+                               {
+                                       $suffix = '+';
+                               }
+                               $suffix .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
+                               break;
+                       case 'utc':
+                       case 'iso8601UTC':
+                       case 'rfc3339UTC':
+                               /*
+                                * RFC3339: Date and Time on the Internet: Timestamps
+                                *  5. Date and Time format
+                                *   http://www.ietf.org/rfc/rfc3339.txt
+                                */
+                               $timestamp -= $offset;
+                               $format = '%Y-%m-%dT%H:%M:%SZ';
+                               $suffix = '';
+                               break;
+                       case '':
+                               $format = '%X %x';
+                               $offset = '';
+                               break;
+                       default:
+                               $suffix = '';
+                               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::$current_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_FI",
+               "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"
+       );
+}
+>>>>>>> skinnable-master