Permalink
Browse files

MDL-35171 Forms: Date selector always gets UTF-8 strings

  • Loading branch information...
1 parent 6738413 commit 98268916ff989b76c268e11566aae044899d1d20 @FMCorz FMCorz committed Sep 20, 2012
Showing with 95 additions and 33 deletions.
  1. +19 −19 lib/formslib.php
  2. +40 −14 lib/moodlelib.php
  3. +36 −0 lib/tests/moodlelib_test.php
View
@@ -81,25 +81,25 @@ function form_init_date_js() {
$function = 'M.form.dateselector.init_date_selectors';
$config = array(array(
'firstdayofweek' => get_string('firstdayofweek', 'langconfig'),
- 'mon' => strftime('%a', strtotime("Monday")),
- 'tue' => strftime('%a', strtotime("Tuesday")),
- 'wed' => strftime('%a', strtotime("Wednesday")),
- 'thu' => strftime('%a', strtotime("Thursday")),
- 'fri' => strftime('%a', strtotime("Friday")),
- 'sat' => strftime('%a', strtotime("Saturday")),
- 'sun' => strftime('%a', strtotime("Sunday")),
- 'january' => strftime('%B', strtotime("January 1")),
- 'february' => strftime('%B', strtotime("February 1")),
- 'march' => strftime('%B', strtotime("March 1")),
- 'april' => strftime('%B', strtotime("April 1")),
- 'may' => strftime('%B', strtotime("May 1")),
- 'june' => strftime('%B', strtotime("June 1")),
- 'july' => strftime('%B', strtotime("July 1")),
- 'august' => strftime('%B', strtotime("August 1")),
- 'september' => strftime('%B', strtotime("September 1")),
- 'october' => strftime('%B', strtotime("October 1")),
- 'november' => strftime('%B', strtotime("November 1")),
- 'december' => strftime('%B', strtotime("December 1"))
+ 'mon' => date_format_string(strtotime("Monday"), '%a', 99),
+ 'tue' => date_format_string(strtotime("Tuesday"), '%a', 99),
+ 'wed' => date_format_string(strtotime("Wednesday"), '%a', 99),
+ 'thu' => date_format_string(strtotime("Thursday"), '%a', 99),
+ 'fri' => date_format_string(strtotime("Friday"), '%a', 99),
+ 'sat' => date_format_string(strtotime("Saturday"), '%a', 99),
+ 'sun' => date_format_string(strtotime("Sunday"), '%a', 99),
+ 'january' => date_format_string(strtotime("January 1"), '%B', 99),
+ 'february' => date_format_string(strtotime("February 1"), '%B', 99),
+ 'march' => date_format_string(strtotime("March 1"), '%B', 99),
+ 'april' => date_format_string(strtotime("April 1"), '%B', 99),
+ 'may' => date_format_string(strtotime("May 1"), '%B', 99),
+ 'june' => date_format_string(strtotime("June 1"), '%B', 99),
+ 'july' => date_format_string(strtotime("July 1"), '%B', 99),
+ 'august' => date_format_string(strtotime("August 1"), '%B', 99),
+ 'september' => date_format_string(strtotime("September 1"), '%B', 99),
+ 'october' => date_format_string(strtotime("October 1"), '%B', 99),
+ 'november' => date_format_string(strtotime("November 1"), '%B', 99),
+ 'december' => date_format_string(strtotime("December 1"), '%B', 99)
));
$PAGE->requires->yui_module($module, $function, $config);
$done = true;
View
@@ -2071,13 +2071,7 @@ function userdate($date, $format = '', $timezone = 99, $fixday = true, $fixhour
// (because it's impossible to specify UTF-8 to fetch locale info in Win32)
if (abs($timezone) > 13) { /// Server time
- if ($CFG->ostype == 'WINDOWS' and ($localewincharset = get_string('localewincharset', 'langconfig'))) {
- $format = textlib::convert($format, 'utf-8', $localewincharset);
- $datestring = strftime($format, $date);
- $datestring = textlib::convert($datestring, $localewincharset, 'utf-8');
- } else {
- $datestring = strftime($format, $date);
- }
+ $datestring = date_format_string($date, $format, $timezone);
if ($fixday) {
$daystring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %d', $date)));
$datestring = str_replace('DD', $daystring, $datestring);
@@ -2089,13 +2083,7 @@ function userdate($date, $format = '', $timezone = 99, $fixday = true, $fixhour
} else {
$date += (int)($timezone * 3600);
- if ($CFG->ostype == 'WINDOWS' and ($localewincharset = get_string('localewincharset', 'langconfig'))) {
- $format = textlib::convert($format, 'utf-8', $localewincharset);
- $datestring = gmstrftime($format, $date);
- $datestring = textlib::convert($datestring, $localewincharset, 'utf-8');
- } else {
- $datestring = gmstrftime($format, $date);
- }
+ $datestring = date_format_string($date, $format, $timezone);
if ($fixday) {
$daystring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %d', $date)));
$datestring = str_replace('DD', $daystring, $datestring);
@@ -2110,6 +2098,44 @@ function userdate($date, $format = '', $timezone = 99, $fixday = true, $fixhour
}
/**
+ * Returns a formatted date ensuring it is UTF-8.
+ *
+ * If we are running under Windows convert to Windows encoding and then back to UTF-8
+ * (because it's impossible to specify UTF-8 to fetch locale info in Win32).
+ *
+ * This function does not do any calculation regarding the user preferences and should
+ * therefore receive the final date timestamp, format and timezone. Timezone being only used
+ * to differenciate the use of server time or not (strftime() against gmstrftime()).
+ *
+ * @param int $date the timestamp.
+ * @param string $format strftime format.
+ * @param int|float $timezone the numerical timezone, typically returned by {@link get_user_timezone_offset()}.
+ * @return string the formatted date/time.
+ * @since 2.3.3
+ */
+function date_format_string($date, $format, $tz = 99) {
+ global $CFG;
+ if (abs($tz) > 13) {
+ if ($CFG->ostype == 'WINDOWS' and ($localewincharset = get_string('localewincharset', 'langconfig'))) {
+ $format = textlib::convert($format, 'utf-8', $localewincharset);
+ $datestring = strftime($format, $date);
+ $datestring = textlib::convert($datestring, $localewincharset, 'utf-8');
+ } else {
+ $datestring = strftime($format, $date);
+ }
+ } else {
+ if ($CFG->ostype == 'WINDOWS' and ($localewincharset = get_string('localewincharset', 'langconfig'))) {
+ $format = textlib::convert($format, 'utf-8', $localewincharset);
+ $datestring = gmstrftime($format, $date);
+ $datestring = textlib::convert($datestring, $localewincharset, 'utf-8');
+ } else {
+ $datestring = gmstrftime($format, $date);
+ }
+ }
+ return $datestring;
+}
+
+/**
* Given a $time timestamp in GMT (seconds since epoch),
* returns an array that represents the date in user time
*
@@ -1993,4 +1993,40 @@ public function test_convert_to_array() {
);
$this->assertEquals(convert_to_array($obj), $ar);
}
+
+ /**
+ * Test the function date_format_string().
+ */
+ function test_date_format_string() {
+ // Forcing locale and timezone.
+ $oldlocale = setlocale(LC_TIME, '0');
+ setlocale(LC_TIME, 'en_AU.UTF-8');
+ $systemdefaulttimezone = date_default_timezone_get();
+ date_default_timezone_set('Australia/Perth');
+
+ // Note: date_format_string() uses the timezone only to differenciate
+ // the server time from the UTC time. It does not modify the timestamp.
+ // Hence similar results for timezones <= 13.
+ $str = date_format_string(1293876000, '%A, %d %B %Y, %I:%M %p', 99);
+ $this->assertEquals($str, 'Saturday, 01 January 2011, 06:00 PM');
+
+ $str = date_format_string(1293876000, '%A, %d %B %Y, %I:%M %p', 0);
+ $this->assertEquals($str, 'Saturday, 01 January 2011, 10:00 AM');
+
+ $str = date_format_string(1293876000, '%A, %d %B %Y, %I:%M %p', -12);
+ $this->assertEquals($str, 'Saturday, 01 January 2011, 10:00 AM');
+
+ $str = date_format_string(1293876000, 'Žluťoučký koníček %A', 99);
+ $this->assertEquals($str, 'Žluťoučký koníček Saturday');
+
+ $str = date_format_string(1293876000, '言語設定言語 %A', 99);
+ $this->assertEquals($str, '言語設定言語 Saturday');
+
+ $str = date_format_string(1293876000, '简体中文简体 %A', 99);
+ $this->assertEquals($str, '简体中文简体 Saturday');
+
+ // Restore system default values.
+ date_default_timezone_set($systemdefaulttimezone);
+ setlocale(LC_TIME, $oldlocale);
+ }
}

0 comments on commit 9826891

Please sign in to comment.