Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
40.00% |
4 / 10 |
CRAP | |
66.67% |
66 / 99 |
| DateFormatter | |
0.00% |
0 / 1 |
|
40.00% |
4 / 10 |
120.00 | |
66.67% |
66 / 99 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| format | |
0.00% |
0 / 1 |
42 | |
0.00% |
0 / 15 |
|||
| formatInterval | |
100.00% |
1 / 1 |
7 | |
100.00% |
12 / 12 |
|||
| getSampleDateFormats | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| anonymous function | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| formatTimeDiffUntil | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| formatTimeDiffSince | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| formatDiff | |
0.00% |
0 / 1 |
22.55 | |
89.58% |
43 / 48 |
|||
| dateFormat | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 6 |
|||
| country | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\Core\Datetime\DateFormatter. | |
| */ | |
| namespace Drupal\Core\Datetime; | |
| use Drupal\Core\Config\ConfigFactoryInterface; | |
| use Drupal\Core\Entity\EntityManagerInterface; | |
| use Drupal\Core\Language\Language; | |
| use Drupal\Core\Language\LanguageManagerInterface; | |
| use Drupal\Core\StringTranslation\TranslationInterface; | |
| use Drupal\Core\StringTranslation\StringTranslationTrait; | |
| use Symfony\Component\HttpFoundation\RequestStack; | |
| /** | |
| * Provides a service to handle various date related functionality. | |
| * | |
| * @ingroup i18n | |
| */ | |
| class DateFormatter implements DateFormatterInterface { | |
| use StringTranslationTrait; | |
| /** | |
| * The list of loaded timezones. | |
| * | |
| * @var array | |
| */ | |
| protected $timezones; | |
| /** | |
| * The date format storage. | |
| * | |
| * @var \Drupal\Core\Entity\EntityStorageInterface | |
| */ | |
| protected $dateFormatStorage; | |
| /** | |
| * Language manager for retrieving the default langcode when none is specified. | |
| * | |
| * @var \Drupal\Core\Language\LanguageManagerInterface | |
| */ | |
| protected $languageManager; | |
| /** | |
| * The configuration factory. | |
| * | |
| * @var \Drupal\Core\Config\ConfigFactoryInterface | |
| */ | |
| protected $configFactory; | |
| /** | |
| * The request stack. | |
| * | |
| * @var \Symfony\Component\HttpFoundation\RequestStack | |
| */ | |
| protected $requestStack; | |
| protected $country = NULL; | |
| protected $dateFormats = array(); | |
| /** | |
| * Contains the different date interval units. | |
| * | |
| * This array is keyed by strings representing the unit (e.g. | |
| * '1 year|@count years') and with the amount of values of the unit in | |
| * seconds. | |
| * | |
| * @var array | |
| */ | |
| protected $units = array( | |
| '1 year|@count years' => 31536000, | |
| '1 month|@count months' => 2592000, | |
| '1 week|@count weeks' => 604800, | |
| '1 day|@count days' => 86400, | |
| '1 hour|@count hours' => 3600, | |
| '1 min|@count min' => 60, | |
| '1 sec|@count sec' => 1, | |
| ); | |
| /** | |
| * Constructs a Date object. | |
| * | |
| * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager | |
| * The entity manager. | |
| * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager | |
| * The language manager. | |
| * @param \Drupal\Core\StringTranslation\TranslationInterface $translation | |
| * The string translation. | |
| * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory | |
| * The configuration factory. | |
| * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack | |
| * The request stack. | |
| */ | |
| public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, TranslationInterface $translation, ConfigFactoryInterface $config_factory, RequestStack $request_stack) { | |
| $this->dateFormatStorage = $entity_manager->getStorage('date_format'); | |
| $this->languageManager = $language_manager; | |
| $this->stringTranslation = $translation; | |
| $this->configFactory = $config_factory; | |
| $this->requestStack = $request_stack; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function format($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL) { | |
| if (!isset($timezone)) { | |
| $timezone = date_default_timezone_get(); | |
| } | |
| // Store DateTimeZone objects in an array rather than repeatedly | |
| // constructing identical objects over the life of a request. | |
| if (!isset($this->timezones[$timezone])) { | |
| $this->timezones[$timezone] = timezone_open($timezone); | |
| } | |
| if (empty($langcode)) { | |
| $langcode = $this->languageManager->getCurrentLanguage()->getId(); | |
| } | |
| // Create a DrupalDateTime object from the timestamp and timezone. | |
| $create_settings = array( | |
| 'langcode' => $langcode, | |
| 'country' => $this->country(), | |
| ); | |
| $date = DrupalDateTime::createFromTimestamp($timestamp, $this->timezones[$timezone], $create_settings); | |
| // If we have a non-custom date format use the provided date format pattern. | |
| if ($date_format = $this->dateFormat($type, $langcode)) { | |
| $format = $date_format->getPattern(); | |
| } | |
| // Fall back to medium if a format was not found. | |
| if (empty($format)) { | |
| $format = $this->dateFormat('fallback', $langcode)->getPattern(); | |
| } | |
| // Call $date->format(). | |
| $settings = array( | |
| 'langcode' => $langcode, | |
| ); | |
| return $date->format($format, $settings); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function formatInterval($interval, $granularity = 2, $langcode = NULL) { | |
| $output = ''; | |
| foreach ($this->units as $key => $value) { | |
| $key = explode('|', $key); | |
| if ($interval >= $value) { | |
| $output .= ($output ? ' ' : '') . $this->formatPlural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode)); | |
| $interval %= $value; | |
| $granularity--; | |
| } | |
| elseif ($output) { | |
| // Break if there was previous output but not any output at this level, | |
| // to avoid skipping levels and getting output like "1 year 1 second". | |
| break; | |
| } | |
| if ($granularity == 0) { | |
| break; | |
| } | |
| } | |
| return $output ? $output : $this->t('0 sec', array(), array('langcode' => $langcode)); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timezone = NULL) { | |
| $timestamp = $timestamp ?: time(); | |
| // All date format characters for the PHP date() function. | |
| $date_chars = str_split('dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU'); | |
| $date_elements = array_combine($date_chars, $date_chars); | |
| return array_map(function ($character) use ($timestamp, $timezone, $langcode) { | |
| return $this->format($timestamp, 'custom', $character, $timezone, $langcode); | |
| }, $date_elements); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function formatTimeDiffUntil($timestamp, $options = array()) { | |
| $request_time = $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME'); | |
| return $this->formatDiff($request_time, $timestamp, $options); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function formatTimeDiffSince($timestamp, $options = array()) { | |
| $request_time = $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME'); | |
| return $this->formatDiff($timestamp, $request_time, $options); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function formatDiff($from, $to, $options = array()) { | |
| $options += array( | |
| 'granularity' => 2, | |
| 'langcode' => NULL, | |
| 'strict' => TRUE, | |
| ); | |
| if ($options['strict'] && $from > $to) { | |
| return $this->t('0 seconds'); | |
| } | |
| $date_time_from = new \DateTime(); | |
| $date_time_from->setTimestamp($from); | |
| $date_time_to = new \DateTime(); | |
| $date_time_to->setTimestamp($to); | |
| $interval = $date_time_to->diff($date_time_from); | |
| $granularity = $options['granularity']; | |
| $output = ''; | |
| // We loop over the keys provided by \DateInterval explicitly. Since we | |
| // don't take the "invert" property into account, the resulting output value | |
| // will always be positive. | |
| foreach (array('y', 'm', 'd', 'h', 'i', 's') as $value) { | |
| if ($interval->$value > 0) { | |
| // Switch over the keys to call formatPlural() explicitly with literal | |
| // strings for all different possibilities. | |
| switch ($value) { | |
| case 'y': | |
| $interval_output = $this->formatPlural($interval->y, '1 year', '@count years', array(), array('langcode' => $options['langcode'])); | |
| break; | |
| case 'm': | |
| $interval_output = $this->formatPlural($interval->m, '1 month', '@count months', array(), array('langcode' => $options['langcode'])); | |
| break; | |
| case 'd': | |
| // \DateInterval doesn't support weeks, so we need to calculate them | |
| // ourselves. | |
| $interval_output = ''; | |
| $days = $interval->d; | |
| $weeks = floor($days / 7); | |
| if ($weeks) { | |
| $interval_output .= $this->formatPlural($weeks, '1 week', '@count weeks', array(), array('langcode' => $options['langcode'])); | |
| $days -= $weeks * 7; | |
| $granularity--; | |
| } | |
| if ((!$output || $weeks > 0) && $granularity > 0 && $days > 0) { | |
| $interval_output .= ($interval_output ? ' ' : '') . $this->formatPlural($days, '1 day', '@count days', array(), array('langcode' => $options['langcode'])); | |
| } | |
| else { | |
| // If we did not output days, set the granularity to 0 so that we | |
| // will not output hours and get things like "1 week 1 hour". | |
| $granularity = 0; | |
| } | |
| break; | |
| case 'h': | |
| $interval_output = $this->formatPlural($interval->h, '1 hour', '@count hours', array(), array('langcode' => $options['langcode'])); | |
| break; | |
| case 'i': | |
| $interval_output = $this->formatPlural($interval->i, '1 minute', '@count minutes', array(), array('langcode' => $options['langcode'])); | |
| break; | |
| case 's': | |
| $interval_output = $this->formatPlural($interval->s, '1 second', '@count seconds', array(), array('langcode' => $options['langcode'])); | |
| break; | |
| } | |
| $output .= ($output && $interval_output ? ' ' : '') . $interval_output; | |
| $granularity--; | |
| } | |
| elseif ($output) { | |
| // Break if there was previous output but not any output at this level, | |
| // to avoid skipping levels and getting output like "1 year 1 second". | |
| break; | |
| } | |
| if ($granularity <= 0) { | |
| break; | |
| } | |
| } | |
| if (empty($output)) { | |
| $output = $this->t('0 seconds'); | |
| } | |
| return $output; | |
| } | |
| /** | |
| * Loads the given format pattern for the given langcode. | |
| * | |
| * @param string $format | |
| * The machine name of the date format. | |
| * @param string $langcode | |
| * The langcode of the language to use. | |
| * | |
| * @return string|null | |
| * The pattern for the date format in the given language for non-custom | |
| * formats, NULL otherwise. | |
| */ | |
| protected function dateFormat($format, $langcode) { | |
| if (!isset($this->dateFormats[$format][$langcode])) { | |
| $original_language = $this->languageManager->getConfigOverrideLanguage(); | |
| $this->languageManager->setConfigOverrideLanguage(new Language(array('id' => $langcode))); | |
| $this->dateFormats[$format][$langcode] = $this->dateFormatStorage->load($format); | |
| $this->languageManager->setConfigOverrideLanguage($original_language); | |
| } | |
| return $this->dateFormats[$format][$langcode]; | |
| } | |
| /** | |
| * Returns the default country from config. | |
| * | |
| * @return string | |
| * The config setting for country.default. | |
| */ | |
| protected function country() { | |
| if ($this->country === NULL) { | |
| $this->country = \Drupal::config('system.date')->get('country.default'); | |
| } | |
| return $this->country; | |
| } | |
| } |