Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsgiehl <stefan@piwik.org>2015-07-04 22:28:26 +0300
committersgiehl <stefan@piwik.org>2015-09-25 21:07:47 +0300
commit4e6f8349ac42dd26917687d873e935a6afb34642 (patch)
tree79f4ee5c0e56a74d8d5124dc13c49b42024890bc /core/Date.php
parent7f375924db9328f20a0b7cb1e41397f2309b60a7 (diff)
prepare date class to handle cldr date/time formats
Diffstat (limited to 'core/Date.php')
-rw-r--r--core/Date.php210
1 files changed, 190 insertions, 20 deletions
diff --git a/core/Date.php b/core/Date.php
index 1448c23826..4fac9d8595 100644
--- a/core/Date.php
+++ b/core/Date.php
@@ -29,7 +29,7 @@ use Piwik\Container\StaticContainer;
*
* $date = Date::factory('2007-07-24 14:04:24', 'EST');
* $date->addHour(5);
- * echo $date->getLocalized("%longDay% the %day% of %longMonth% at %time%");
+ * echo $date->getLocalized("EEE, d. MMM y 'at' HH:mm:ss");
*
* @api
*/
@@ -604,8 +604,33 @@ class Date
/**
* Returns a localized date string using the given template.
* The template should contain tags that will be replaced with localized date strings.
+ *
+ * @param string $template eg. `"MMM y"`
+ * @return string eg. `"Aug 2009"`
+ */
+ public function getLocalized($template)
+ {
+ $template = $this->replaceLegacyPlaceholders($template);
+
+ $tokens = self::parseFormat($template);
+
+ $out = '';
+
+ foreach ($tokens AS $token) {
+ if (is_array($token)) {
+ $out .= $this->formatToken(array_shift($token));
+
+ } else {
+ $out .= $token;
+ }
+ }
+
+ return $out;
+ }
+ /**
+ * Replaces legacy placeholders
*
- * Allowed tags include:
+ * @deprecated should be removed in Piwik 3.0.0 or later
*
* - **%day%**: replaced with the day of the month without leading zeros, eg, **1** or **20**.
* - **%shortMonth%**: the short month in the current language, eg, **Jan**, **Feb**.
@@ -615,28 +640,173 @@ class Date
* - **%longYear%**: the four digit year, eg, **2007**, **2013**.
* - **%shortYear%**: the two digit year, eg, **07**, **13**.
* - **%time%**: the time of day, eg, **07:35:00**, or **15:45:00**.
- *
- * @param string $template eg. `"%shortMonth% %longYear%"`
- * @return string eg. `"Aug 2009"`
*/
- public function getLocalized($template)
+ protected function replaceLegacyPlaceholders($template)
+ {
+ $mapping = array(
+ '%day%' => 'd',
+ '%shortMonth%' => 'MMM',
+ '%longMonth%' => 'MMMM',
+ '%shortDay%' => 'EEE',
+ '%longDay%' => 'EEEE',
+ '%longYear%' => 'y',
+ '%shortYear%' => 'yy',
+ '%time%' => 'HH:mm:ss'
+ );
+
+ return str_replace(array_keys($mapping), array_values($mapping), $template);
+ }
+
+ protected function formatToken($token)
{
- $translator = StaticContainer::get('Piwik\Translation\Translator');
- $day = $this->toString('j');
$dayOfWeek = $this->toString('N');
$monthOfYear = $this->toString('n');
- $patternToValue = array(
- "%day%" => $day,
- "%shortMonth%" => $translator->translate('Intl_ShortMonth_' . $monthOfYear),
- "%longMonth%" => $translator->translate('Intl_LongMonth_' . $monthOfYear),
- "%shortDay%" => $translator->translate('Intl_ShortDay_' . $dayOfWeek),
- "%longDay%" => $translator->translate('Intl_LongDay_' . $dayOfWeek),
- "%longYear%" => $this->toString('Y'),
- "%shortYear%" => $this->toString('y'),
- "%time%" => $this->toString('H:i:s')
- );
- $out = str_replace(array_keys($patternToValue), array_values($patternToValue), $template);
- return $out;
+ $translator = StaticContainer::get('Piwik\Translation\Translator');
+
+ switch ($token) {
+ // year
+ case "yyyy":
+ case "y":
+ return $this->toString('Y');
+ case "yy":
+ return $this->toString('y');
+ // month
+ case "MMMM":
+ return $translator->translate('Intl_Month_Long_' . $monthOfYear);
+ case "MMM":
+ return $translator->translate('Intl_Month_Short_' . $monthOfYear);
+ case "MM":
+ return $this->toString('n');
+ case "M":
+ return $this->toString('m');
+ case "LLLL":
+ return $translator->translate('Intl_Month_Long_StandAlone_' . $monthOfYear);
+ case "LLL":
+ return $translator->translate('Intl_Month_Short_StandAlone_' . $monthOfYear);
+ case "LL":
+ return $this->toString('n');
+ case "L":
+ return $this->toString('m');
+ // day
+ case "dd":
+ return $this->toString('d');
+ case "d":
+ return $this->toString('j');
+ case "EEEE":
+ return $translator->translate('Intl_Day_Long_' . $dayOfWeek);
+ case "EEE":
+ case "EE":
+ case "E":
+ return $translator->translate('Intl_Day_Short_' . $dayOfWeek);
+ case "CCCC":
+ return $translator->translate('Intl_Day_Long_StandAlone_' . $dayOfWeek);
+ case "CCC":
+ case "CC":
+ case "C":
+ return $translator->translate('Intl_Day_Short_StandAlone_' . $dayOfWeek);
+ case "D":
+ return 1 + (int)$this->toString('z'); // 1 - 366
+ case "F":
+ return (int)(((int)$this->toString('j')+6)/7);
+ // week in month
+ case "w":
+ $weekDay=date('N',mktime(0,0,0,$this->toString('m'),1,$this->toString('y')));
+ return floor(($weekDay+(int)$this->toString('m')-2)/7)+1;
+ // week in year
+ case "W":
+ return $this->toString('N');
+ // hour
+ case "HH":
+ return $this->toString('H');
+ case "H":
+ return $this->toString('G');
+ case "hh":
+ return $this->toString('h');
+ case "h":
+ return $this->toString('g');
+ // minute
+ case "mm":
+ case "m":
+ return $this->toString('i');
+ // second
+ case "ss":
+ case "s":
+ return $this->toString('s');
+ // am / pm
+ case "a":
+ return $this->toString('a') == 'am' ? $translator->translate('Intl_Time_AM') : $translator->translate('Intl_Time_PM');
+
+ // currently not implemented:
+ case "G":
+ case "GG":
+ case "GGG":
+ case "GGGG":
+ case "GGGGG":
+ return ''; // era
+ case "z":
+ case "Z":
+ case "v":
+ return ''; // time zone
+
+ }
+
+ return '';
+ }
+
+ protected static $tokens = array(
+ 'G', 'y', 'M', 'L', 'd', 'h', 'H', 'm', 's', 'E', 'c', 'e', 'D', 'F', 'w', 'W', 'a', 'z', 'Z', 'v',
+ );
+
+ /**
+ * Parses the datetime format pattern.
+ * @param string $pattern the pattern to be parsed
+ * @return array tokenized parsing result
+ */
+ protected static function parseFormat($pattern)
+ {
+ static $formats = array(); // cache
+ if (isset($formats[$pattern])) {
+ return $formats[$pattern];
+ }
+ $tokens = array();
+ $n = strlen($pattern);
+ $isLiteral = false;
+ $literal = '';
+ for ($i = 0; $i < $n; ++$i) {
+ $c = $pattern[$i];
+ if ($c === "'") {
+ if ($i < $n - 1 && $pattern[$i + 1] === "'") {
+ $tokens[] = "'";
+ $i++;
+ } elseif ($isLiteral) {
+ $tokens[] = $literal;
+ $literal = '';
+ $isLiteral = false;
+ } else {
+ $isLiteral = true;
+ $literal = '';
+ }
+ } elseif ($isLiteral) {
+ $literal .= $c;
+ } else {
+ for ($j = $i + 1; $j < $n; ++$j) {
+ if ($pattern[$j] !== $c) {
+ break;
+ }
+ }
+ $p = str_repeat($c, $j - $i);
+ if (in_array($c, self::$tokens)) {
+ $tokens[] = array($p);
+ } else {
+ $tokens[] = $p;
+ }
+ $i = $j - 1;
+ }
+ }
+ if ($literal !== '') {
+ $tokens[] = $literal;
+ }
+ return $formats[$pattern] = $tokens;
}
/**