private static function SmartDateTrait::rangeDateReduce in Smart Date 3.x
Same name and namespace in other branches
- 8.2 src/SmartDateTrait.php \Drupal\smart_date\SmartDateTrait::rangeDateReduce()
- 3.0.x src/SmartDateTrait.php \Drupal\smart_date\SmartDateTrait::rangeDateReduce()
- 3.1.x src/SmartDateTrait.php \Drupal\smart_date\SmartDateTrait::rangeDateReduce()
- 3.2.x src/SmartDateTrait.php \Drupal\smart_date\SmartDateTrait::rangeDateReduce()
- 3.3.x src/SmartDateTrait.php \Drupal\smart_date\SmartDateTrait::rangeDateReduce()
- 3.4.x src/SmartDateTrait.php \Drupal\smart_date\SmartDateTrait::rangeDateReduce()
Reduce duplication in a provided date range.
Parameters
array $range: The date/time range to format.
array $settings: The date/time range to format.
object $start_ts: A timestamp.
object $end_ts: A timestamp.
string|null $timezone: Timezone.
Return value
string|array The range, with duplicate elements removed.
1 call to SmartDateTrait::rangeDateReduce()
- SmartDateTrait::formatSmartDate in src/
SmartDateTrait.php - Creates a formatted date value as a string.
File
- src/
SmartDateTrait.php, line 253
Class
- SmartDateTrait
- Provides friendly methods for smart date range.
Namespace
Drupal\smart_dateCode
private static function rangeDateReduce(array $range, array $settings, $start_ts, $end_ts, $timezone = NULL) {
// First attempt has the following limitations, to reduce complexity:
// * Day ranges only work either d or j, and no other day tokens.
// * Not able to handle S token unless adjacent to day.
// * Month, day ranges only work if year at start or end.
$start = getdate($start_ts);
$end = getdate($end_ts);
// If the years are different, no deduplication necessary.
if ($start['year'] != $end['year']) {
return $range;
}
$valid_days = [];
$invalid_days = [];
// Check for workable day tokens.
preg_match_all('/[dj]/', $settings['date_format'], $valid_days, PREG_OFFSET_CAPTURE);
// Check for challenging day tokens.
preg_match_all('/[DNlwz]/', $settings['date_format'], $invalid_days, PREG_OFFSET_CAPTURE);
// If specific conditions are met format as a range within the month.
if ($start['month'] == $end['month'] && count($valid_days[0]) == 1 && count($invalid_days[0]) == 0) {
// Split the date string at the valid day token.
$day_loc = $valid_days[0][0][1];
// Don't remove the S token from the start if present.
if ($s_loc = strpos($settings['date_format'], 'S', $day_loc)) {
$offset = 1 + $s_loc - $day_loc;
}
else {
$offset = 1;
}
$start_format = substr($settings['date_format'], 0, $day_loc + $offset);
$end_format = substr($settings['date_format'], $day_loc);
$range['start']['date'] = \Drupal::service('date.formatter')
->format($start_ts, '', $start_format, $timezone);
$range['end']['date'] = \Drupal::service('date.formatter')
->format($end_ts, '', $end_format, $timezone);
}
else {
// Only remaining possibility is to deduplicate the year.
// NOTE: Our code only works with a 4 digit year format.
if (strpos($settings['date_format'], 'Y') === 0) {
$year_pos = 0;
}
elseif (strpos($settings['date_format'], 'Y') == strlen($settings['date_format']) - 1) {
$year_pos = -1;
}
else {
// Too complicated if year is in the middle.
$year_pos = FALSE;
}
if ($year_pos !== FALSE) {
$valid_tokens = [];
// Check for workable day or month tokens.
preg_match_all('/[djDNlwzSFmMn]/', $settings['date_format'], $valid_tokens, PREG_OFFSET_CAPTURE);
if ($valid_tokens) {
if ($year_pos == 0) {
// Year is at the beginning, so change the end to start at the
// first valid token after it.
$first_token = $valid_tokens[0][0];
$end_format = substr($settings['date_format'], $first_token[1]);
$range['end']['date'] = \Drupal::service('date.formatter')
->format($end_ts, '', $end_format, $timezone);
}
else {
$last_token = array_pop($valid_tokens[0]);
$start_format = substr($settings['date_format'], 0, $last_token[1] + 1);
$range['start']['date'] = \Drupal::service('date.formatter')
->format($start_ts, '', $start_format, $timezone);
}
}
}
}
return $range;
}