[wp-trac] [WordPress Trac] #7753: Use of localized calendar system
and translating digits in entire WordPress
WordPress Trac
wp-trac at lists.automattic.com
Tue Sep 16 11:31:54 GMT 2008
#7753: Use of localized calendar system and translating digits in entire WordPress
-------------------------+--------------------------------------------------
Reporter: kambiz.k | Owner: anonymous
Type: enhancement | Status: new
Priority: normal | Milestone: 2.7
Component: i18n | Version: 2.6.1
Severity: normal | Keywords: has-patch, tested
-------------------------+--------------------------------------------------
Current implementation of WordPress (v2.6.2) do not offer a mechanism to
globally convert '''Gregorian Calendar System to Localized Calendar
System''', and to translate '''Latin Digits to Localized Digits'''.
== Localization of Calendar System ==
To convert Gregorian Calendar System to Localized Calendar System (like
Jewish, Hijri, Jalali, and so on) some users use the_post and
get_comment_date filters. However this is just a workaround and has some
problems:
1. These filters have to ignore output of their respective WordPress
functions, and recompute the new output from scratch. This is not only a
performance drawback, but also breaks consistency of code.
2. Every single filter should have its own callback function because each
callback can manage only one object (e.g. post or comment). If user needs
to localize dates in other places, should write new callback functions.
5. In some cases, there is no way to use filters for changing calendar
syste (for example dates shown by plugins or dates shown in admin area).
The solution is quite simple. WordPress as well as plugins use either
mysql2date or date_i18n to format date and time. What we need is a filter
in these functions to apply on the unixtimestamp and return the converted
date/time.
Actually, we need the filter only in date_i18n function. When translate
parameter of mysql2date function is true, it should call date_i18n but in
the current implementation has duplicated code).
== Localization of Numbers ==
As same as the calendar system, some users get benefit of available
filters in conjunction with heavy regular expressions to translate digits
of numbers to their language locale. Of course there is no filter for
every single item and users have to leave some numbers as Latin.
WordPress has already a function named number_format_i18n that eveybody
calls it to format numbers. If we apply a filter to output of this
function, we can translate digits of numbers all in one place, and of
course with a better performance.
By applying a filter on output of date_i18n function, we can translate
digits in date and time too.
== RECOMMENDED CODE ==
Here is the code that I suggest for mysql2date, date_i18n, and
number_format_i18n functions (attached as a patch and tested with v2.6.2).
{{{
function mysql2date( $dateformatstring, $mysqlstring, $translate = true )
{
global $wp_locale;
$m = $mysqlstring;
if ( empty( $m ) )
return false;
if( 'G' == $dateformatstring ) {
return gmmktime(
(int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2
), (int) substr( $m, 17, 2 ),
(int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2
), (int) substr( $m, 0, 4 )
);
}
$i = mktime(
(int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2 ),
(int) substr( $m, 17, 2 ),
(int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2 ), (int)
substr( $m, 0, 4 )
);
if( 'U' == $dateformatstring )
return $i;
if ( -1 == $i || false == $i )
$i = 0;
if ( $translate ) // localizing names or calendar system
$j = date_i18n( $dateformatstring, $i );
else
$j = @date( $dateformatstring, $i );
/*
if ( !$j ) // for debug purposes
echo $i." ".$mysqlstring;
*/
return $j;
}
}}}
{{{
function date_i18n( $dateformatstring, $unixtimestamp ) {
global $wp_locale;
$i = $unixtimestamp;
// Sanity check for PHP 5.1.0-
if ( -1 == $i )
$i = false;
// Let the user convert date from Gregorian to localized calendar
system
$j = apply_filters( 'pre_date_i18n', $dateformatstring, $i );
if ($j !== $dateformatstring)
return $j;
if ( ( !empty( $wp_locale->month ) ) && ( !empty(
$wp_locale->weekday ) ) ) {
$datemonth = $wp_locale->get_month( date( 'm', $i ) );
$datemonth_abbrev = $wp_locale->get_month_abbrev(
$datemonth );
$dateweekday = $wp_locale->get_weekday( date( 'w', $i ) );
$dateweekday_abbrev = $wp_locale->get_weekday_abbrev(
$dateweekday );
$datemeridiem = $wp_locale->get_meridiem( date( 'a', $i )
);
$datemeridiem_capital = $wp_locale->get_meridiem( date(
'A', $i ) );
$dateformatstring = ' '.$dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])D/", "\\1" .
backslashit( $dateweekday_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" .
backslashit( $datemonth ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" .
backslashit( $dateweekday ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" .
backslashit( $datemonth_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" .
backslashit( $datemeridiem ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" .
backslashit( $datemeridiem_capital ), $dateformatstring );
$dateformatstring = substr( $dateformatstring, 1, strlen(
$dateformatstring ) -1 );
}
$j = @date( $dateformatstring, $i );
// Let the user translate digits from latin to localized language
return apply_filters( 'date_i18n', $j);
}
}}}
{{{
function number_format_i18n( $number, $decimals = null ) {
global $wp_locale;
// let the user override the precision only
$decimals = ( is_null( $decimals ) ) ?
$wp_locale->number_format['decimals'] : intval( $decimals );
$num = number_format( $number, $decimals,
$wp_locale->number_format['decimal_point'],
$wp_locale->number_format['thousands_sep'] );
// let the user translate digits from latin to localized language
return apply_filters( 'number_format_i18n', $num );
}
}}}
== Example of Usage ==
We need two functions as core of our localization.
{{{
// Converts Latin digits to Persian ones
function latin_to_persian($number) {
$latin = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
$persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
return str_replace($latin, $persian, $number);
}
// Represents a Unix timestamp as Jalali date/time
function gregorian_to_jalali($formatstring, $unixtimestamp) {
// do the work and calculate $the_jalali_date
return latin_to_persian($the_jalali_date);
}
}}}
By use of the new filters we localize date and numbers in entire WordPress
with no pain.
{{{
// Changes date to the new calendar system
add_filter('pre_date_i18n', 'gregorian_to_jalali', 10, 2);
// Translates digits of numbers
add_filter('number_format_i18n', 'latin_to_persian', 10, 1);
}}}
That's all!
--
Ticket URL: <http://trac.wordpress.org/ticket/7753>
WordPress Trac <http://trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list