Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to change time formats (12/24-hour clock) #9093

Merged
merged 10 commits into from Oct 29, 2015
27 changes: 14 additions & 13 deletions core/Date.php
Expand Up @@ -11,6 +11,8 @@

use Exception;
use Piwik\Container\StaticContainer;
use Piwik\Intl\Data\Provider\DateTimeFormatProvider;
use Piwik\Plugins\LanguagesManager\LanguagesManager;

/**
* Utility class that wraps date/time related PHP functions. Using this class can
Expand Down Expand Up @@ -41,15 +43,15 @@ class Date
/** The default date time string format. */
const DATE_TIME_FORMAT = 'Y-m-d H:i:s';

const DATETIME_FORMAT_LONG = 'Intl_Format_DateTime_Long';
const DATETIME_FORMAT_SHORT = 'Intl_Format_DateTime_Short';
const DATE_FORMAT_LONG = 'Intl_Format_Date_Long';
const DATE_FORMAT_DAY_MONTH = 'Intl_Format_Date_Day_Month';
const DATE_FORMAT_SHORT = 'Intl_Format_Date_Short';
const DATE_FORMAT_MONTH_SHORT = 'Intl_Format_Month_Short';
const DATE_FORMAT_MONTH_LONG = 'Intl_Format_Month_Long';
const DATE_FORMAT_YEAR = 'Intl_Format_Year';
const TIME_FORMAT = 'Intl_Format_Time';
const DATETIME_FORMAT_LONG = DateTimeFormatProvider::DATE_FORMAT_LONG;
const DATETIME_FORMAT_SHORT = DateTimeFormatProvider::DATETIME_FORMAT_SHORT;
const DATE_FORMAT_LONG = DateTimeFormatProvider::DATE_FORMAT_LONG;
const DATE_FORMAT_DAY_MONTH = DateTimeFormatProvider::DATE_FORMAT_DAY_MONTH;
const DATE_FORMAT_SHORT = DateTimeFormatProvider::DATE_FORMAT_SHORT;
const DATE_FORMAT_MONTH_SHORT = DateTimeFormatProvider::DATE_FORMAT_MONTH_SHORT;
const DATE_FORMAT_MONTH_LONG = DateTimeFormatProvider::DATE_FORMAT_MONTH_LONG;
const DATE_FORMAT_YEAR = DateTimeFormatProvider::DATE_FORMAT_YEAR;
const TIME_FORMAT = DateTimeFormatProvider::TIME_FORMAT;

/**
* Max days for months (non-leap-year). See {@link addPeriod()} implementation.
Expand Down Expand Up @@ -622,10 +624,9 @@ public function getLocalized($template)
{
$template = $this->replaceLegacyPlaceholders($template);

if (substr($template, 0, 5) == 'Intl_') {
$translator = StaticContainer::get('Piwik\Translation\Translator');
$template = $translator->translate($template);
}
$dateTimeFormatProvider = StaticContainer::get('Piwik\Intl\Data\Provider\DateTimeFormatProvider');

$template = $dateTimeFormatProvider->getFormatPattern($template);

$tokens = self::parseFormat($template);

Expand Down
83 changes: 83 additions & 0 deletions core/Intl/Data/Provider/DateTimeFormatProvider.php
@@ -0,0 +1,83 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/

namespace Piwik\Intl\Data\Provider;

/**
* Provides date and time formats.
*/
class DateTimeFormatProvider
{
const DATETIME_FORMAT_LONG = 1;
const DATETIME_FORMAT_SHORT = 2;
const DATE_FORMAT_LONG = 10;
const DATE_FORMAT_DAY_MONTH = 11;
const DATE_FORMAT_SHORT = 12;
const DATE_FORMAT_MONTH_SHORT = 13;
const DATE_FORMAT_MONTH_LONG = 14;
const DATE_FORMAT_YEAR = 15;
const TIME_FORMAT = 20;

/**
* Returns the format pattern for the given format type
*
* @param int $format one of the format constants
*
* @return string
*/
public function getFormatPattern($format)
{
switch ($format) {
case self::DATETIME_FORMAT_LONG:
return 'EEEE, MMMM d, y HH:mm:ss';

case self::DATETIME_FORMAT_SHORT:
return 'MMM d, y HH:mm:ss';

case self::DATE_FORMAT_LONG:
return 'EEEE, MMMM d, y';

case self::DATE_FORMAT_DAY_MONTH:
return 'E, MMM d';

case self::DATE_FORMAT_SHORT:
return 'MMM d, y';

case self::DATE_FORMAT_MONTH_SHORT:
return 'MMM y';

case self::DATE_FORMAT_MONTH_LONG:
return 'MMMM y';

case self::DATE_FORMAT_YEAR:
return 'y';

case self::TIME_FORMAT:
return 'HH:mm:ss';
}

return $format;
}

/**
* Returns interval format pattern for the given format type
*
* @param bool $short whether to return short or long format pattern
* @param string $maxDifference maximal difference in interval dates (Y, M or D)
*
* @return string
*/
public function getRangeFormatPattern($short=false, $maxDifference='Y')
{
if ($short) {
return 'MMM d, y – MMM d, y';
}

return 'MMMM d, y – MMMM d, y';
}
}
9 changes: 3 additions & 6 deletions core/Period.php
Expand Up @@ -371,12 +371,9 @@ protected function getRangeFormat($short = false)
$maxDifference = 'M';
}

return $this->translator->translate(
sprintf(
'Intl_Format_Interval_%s_%s',
$short ? 'Short' : 'Long',
$maxDifference
));
$dateTimeFormatProvider = StaticContainer::get('Piwik\Intl\Data\Provider\DateTimeFormatProvider');

return $dateTimeFormatProvider->getRangeFormatPattern($short, $maxDifference);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion core/Version.php
Expand Up @@ -20,7 +20,7 @@ final class Version
* The current Piwik version.
* @var string
*/
const VERSION = '2.15.0';
const VERSION = '2.15.1-b1';

public function isStableVersion($version)
{
Expand Down
3 changes: 3 additions & 0 deletions lang/en.json
@@ -1,5 +1,7 @@
{
"General": {
"12HourClock": "12-hour clock",
"24HourClock": "24-hour clock",
"AbandonedCarts": "Abandoned Carts",
"AboutPiwikX": "About Piwik %s",
"Action": "Action",
Expand Down Expand Up @@ -348,6 +350,7 @@
"TagCloud": "Tag Cloud",
"Tax": "Tax",
"TimeAgo": "%s ago",
"TimeFormat": "Time format",
"TimeOnPage": "Time on page",
"Total": "Total",
"TotalRatioTooltip": "This is %1$s of all %2$s %3$s.",
Expand Down
8 changes: 5 additions & 3 deletions plugins/Intl/Commands/GenerateIntl.php
Expand Up @@ -262,7 +262,9 @@ protected function fetchCalendarData(OutputInterface $output, $langCode, $reques

$translations['Intl']['Time_AM'] = $calendarData['dayPeriods']['format']['wide']['am'];
$translations['Intl']['Time_PM'] = $calendarData['dayPeriods']['format']['wide']['pm'];
$translations['Intl']['Format_Time'] = $calendarData['timeFormats']['medium'];
$translations['Intl']['Format_Time'] = '{time}';
$translations['Intl']['Format_Time_12'] = $calendarData['dateTimeFormats']['availableFormats']['hms'];
$translations['Intl']['Format_Time_24'] = $calendarData['dateTimeFormats']['availableFormats']['Hms'];
$translations['Intl']['Format_Date_Long'] = $calendarData['dateFormats']['full'];
$translations['Intl']['Format_Date_Day_Month'] = $calendarData['dateTimeFormats']['availableFormats']['MMMEd'];
$translations['Intl']['Format_Date_Short'] = $calendarData['dateFormats']['medium'];
Expand All @@ -273,8 +275,8 @@ protected function fetchCalendarData(OutputInterface $output, $langCode, $reques
}
$translations['Intl']['Format_Year'] = $calendarData['dateTimeFormats']['availableFormats']['y'];

$translations['Intl']['Format_DateTime_Long'] = $calendarData['dateFormats']['full'] . ' ' . $calendarData['timeFormats']['medium'];
$translations['Intl']['Format_DateTime_Short'] = $calendarData['dateFormats']['medium'] . ' ' . $calendarData['timeFormats']['medium'];
$translations['Intl']['Format_DateTime_Long'] = $calendarData['dateFormats']['full'] . ' {time}';
$translations['Intl']['Format_DateTime_Short'] = $calendarData['dateFormats']['medium'] . ' {time}';

$translations['Intl']['Format_Interval_Long_D'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['d'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL'));
$translations['Intl']['Format_Interval_Long_M'] = $this->transformDateFormat($calendarData['dateTimeFormats']['intervalFormats']['yMMMd']['M'], array('MMMM' => 'MMM', 'LLLL' => 'LLL', 'MMM' => 'MMMM', 'LLL' => 'LLLL'));
Expand Down
133 changes: 133 additions & 0 deletions plugins/Intl/DateTimeFormatProvider.php
@@ -0,0 +1,133 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/

namespace Piwik\Plugins\Intl;

use Piwik\Plugins\LanguagesManager\LanguagesManager;
use Piwik\Translation\Translator;

/**
* Provides date and time formats.
*/
class DateTimeFormatProvider extends \Piwik\Intl\Data\Provider\DateTimeFormatProvider
{
protected $use12HourClock;

/**
* @var Translator
*/
protected $translator;

public function __construct(Translator $translator)
{
$this->translator = $translator;
}

/**
* Returns the format pattern for the given format type
*
* @param int $format one of the format constants
*
* @return string
*/
public function getFormatPattern($format)
{

switch ($format) {
case self::DATETIME_FORMAT_LONG:
$pattern = $this->translator->translate('Intl_Format_DateTime_Long');
break;

case self::DATETIME_FORMAT_SHORT:
$pattern = $this->translator->translate('Intl_Format_DateTime_Short');
break;

case self::DATE_FORMAT_LONG:
$pattern = $this->translator->translate('Intl_Format_Date_Long');
break;

case self::DATE_FORMAT_DAY_MONTH:
$pattern = $this->translator->translate('Intl_Format_Date_Day_Month');
break;

case self::DATE_FORMAT_SHORT:
$pattern = $this->translator->translate('Intl_Format_Date_Short');
break;

case self::DATE_FORMAT_MONTH_SHORT:
$pattern = $this->translator->translate('Intl_Format_Month_Short');
break;

case self::DATE_FORMAT_MONTH_LONG:
$pattern = $this->translator->translate('Intl_Format_Month_Long');
break;

case self::DATE_FORMAT_YEAR:
$pattern = $this->translator->translate('Intl_Format_Year');
break;

case self::TIME_FORMAT:
$pattern = $this->translator->translate('Intl_Format_Time');
break;

default:
$pattern = $format;
}

if (strpos($pattern, '{time}') !== false) {
$pattern = str_replace('{time}', $this->getTimeFormat(), $pattern);
}

return $pattern;
}

/**
* Returns interval format pattern for the given format type
*
* @param bool $short whether to return short or long format pattern
* @param string $maxDifference maximal difference in interval dates (Y, M or D)
*
* @return string
*/
public function getRangeFormatPattern($short=false, $maxDifference='Y')
{
return $this->translator->translate(
sprintf(
'Intl_Format_Interval_%s_%s',
$short ? 'Short' : 'Long',
$maxDifference
));
}

protected function getTimeFormat()
{
if (is_null($this->use12HourClock)) {
$this->use12HourClock = LanguagesManager::uses12HourClockForCurrentUser();
}

$timeFormat = 'Intl_Format_Time_24';

if ($this->use12HourClock) {
$timeFormat = 'Intl_Format_Time_12';
}

$template = $this->translator->translate($timeFormat);

return $template;
}

/**
* For testing purpose only: Overwrites time format
*
* @param bool $use12HourClock
*/
public function forceTimeFormat($use12HourClock = false)
{
$this->use12HourClock = $use12HourClock;
}
}
5 changes: 5 additions & 0 deletions plugins/Intl/config/config.php
@@ -0,0 +1,5 @@
<?php

return array(
'Piwik\Intl\Data\Provider\DateTimeFormatProvider' => DI\object('Piwik\Plugins\Intl\DateTimeFormatProvider')
);
8 changes: 5 additions & 3 deletions plugins/Intl/lang/am.json
Expand Up @@ -300,8 +300,8 @@
"Day_Short_StandAlone_6": "ቅዳሜ",
"Day_Short_StandAlone_7": "እሑድ",
"EnglishLanguageName": "Amharic",
"Format_DateTime_Long": "EEEE ፣d MMMM y h:mm:ss a",
"Format_DateTime_Short": "d MMM y h:mm:ss a",
"Format_DateTime_Long": "EEEE ፣d MMMM y {time}",
"Format_DateTime_Short": "d MMM y {time}",
"Format_Date_Day_Month": "E፣ MMM d",
"Format_Date_Long": "EEEE ፣d MMMM y",
"Format_Date_Short": "d MMM y",
Expand All @@ -313,7 +313,9 @@
"Format_Interval_Short_Y": "MMM d፣ y – MMM d፣ y",
"Format_Month_Long": "MMMM y",
"Format_Month_Short": "MMM y",
"Format_Time": "h:mm:ss a",
"Format_Time": "{time}",
"Format_Time_12": "h:mm:ss a",
"Format_Time_24": "HH:mm:ss",
"Format_Year": "y",
"Hours": "ሰዓቶች",
"Language_aa": "አፋርኛ",
Expand Down
8 changes: 5 additions & 3 deletions plugins/Intl/lang/ar.json
Expand Up @@ -300,8 +300,8 @@
"Day_Short_StandAlone_6": "السبت",
"Day_Short_StandAlone_7": "الأحد",
"EnglishLanguageName": "Arabic",
"Format_DateTime_Long": "EEEE، d MMMM، y h:mm:ss a",
"Format_DateTime_Short": "dd‏\/MM‏\/y h:mm:ss a",
"Format_DateTime_Long": "EEEE، d MMMM، y {time}",
"Format_DateTime_Short": "dd‏\/MM‏\/y {time}",
"Format_Date_Day_Month": "E، d MMM",
"Format_Date_Long": "EEEE، d MMMM، y",
"Format_Date_Short": "dd‏\/MM‏\/y",
Expand All @@ -313,7 +313,9 @@
"Format_Interval_Short_Y": "d MMM، y – d MMM، y",
"Format_Month_Long": "MMMM y",
"Format_Month_Short": "MMM y",
"Format_Time": "h:mm:ss a",
"Format_Time": "{time}",
"Format_Time_12": "h:mm:ss a",
"Format_Time_24": "HH:mm:ss",
"Format_Year": "y",
"Hours": "ساعات",
"Language_aa": "الأفارية",
Expand Down