【问题标题】:Two date range return两个日期范围返回
【发布时间】:2020-02-20 09:03:45
【问题描述】:

如何返回两个日期组合字符串,如下所示。

Start Date : 11/2/2020
End Date : 26/2/2020

那么输出应该是这样的:2020 年 2 月 11 日至 26 日

Start Date : 26/2/2020
End Date : 5/3/2020

那么输出应该是这样的:2020 年 2 月 26 日到 3 月 5 日

Start Date : 29/12/2020
End Date : 2/1/2021

那么输出应该是这样的:2020 年 12 月 29 日到 2021 年 1 月 2 日

请帮我解决这个问题。

【问题讨论】:

  • 欢迎来到 Stack Overflow。这是一个很好的问题。到目前为止,您尝试过什么?
  • @KIKOSoftware 对不起,我想不出这种逻辑。
  • 您首先需要分别查看日期的所有三个组成部分 - 日、月和年。如果年份相同,那么您只需输出一次 - 否则,每个输出值都需要是完整的日期。如果年份相同,则对月份进行相同的检查,并输出相应的部分。
  • 这是您的答案:stackoverflow.com/a/60039218/12232340 如果您是英语,则使用第一个解决方案,如果不是英语,则使用第二个解决方案。

标签: php wordpress date


【解决方案1】:

欢迎来到 stackoverflow :-)

PHP 有一个原生的DateTime 类,它允许您执行日期操作和日期格式设置。

在您的具体情况下,您可以开始将两个日期转换为对象,然后将 reformat 转换为您预期的格式。

这是一个例子:

$date = DateTime::createFromFormat('d/m/Y', $startString);

考虑到这一点,我们现在可以创建一个函数来检查您的要求并以您的自定义格式返回字符串。

function my_date_range(DateTime $start, DateTime $end)
{
    $sameYear = $start->format('Y') === $end->format('Y');
    $sameMonth = $sameYear && $start->format('m') === $end->format('m');
    $sameDay = $sameMonth && $start->format('d') === $end->format('d');

    if ($sameDay) {
        return $start->format('d M Y');
    }
    if ($sameMonth) {
        return sprintf('%s to %s', $start->format('d'), $end->format('d M Y'));
    }
    if ($sameYear) {
        return sprintf('%s to %s', $start->format('d M'), $end->format('d M Y'));
    }

    return sprintf("%s to %s", $start->format('d M Y'), $end->format('d M Y'));
}

您将在下面找到我的示例日期和用法:

var_dump(
    my_date_range(DateTime::createFromFormat('d/m/Y', '11/2/2020'), DateTime::createFromFormat('d/m/Y', '26/2/2020')),
    my_date_range(DateTime::createFromFormat('d/m/Y', '26/2/2020'), DateTime::createFromFormat('d/m/Y', '5/3/2020')),
    my_date_range(DateTime::createFromFormat('d/m/Y', '29/12/2020'), DateTime::createFromFormat('d/m/Y', '2/1/2021')),
    my_date_range(DateTime::createFromFormat('d/m/Y', '2/1/2021'), DateTime::createFromFormat('d/m/Y', '2/1/2021')),
)

结果:

string(17) "11 to 26 Feb 2020"
string(21) "26 Feb to 05 Mar 2020"
string(26) "29 Dec 2020 to 02 Jan 2021"
string(11) "02 Jan 2021"

【讨论】:

  • 这并没有省略两个日期相同的“重复”部分。对于这里的第一个示例,您只会得到11 feb 2020 to 26 feb 2020,这不是我们所要求的。
  • @CBroe 哇哦。谢谢你的提示。你是完全正确的。我会采纳我的答案:-)
【解决方案2】:

一种方法:

  • 将您的日期部分放入数组 - ['11', 'Feb', '2020']

  • 以相反的顺序循环它们,从一年到一天

  • 取消设置开始日期数组中的每个条目,这些条目与结束日期数组中的相应条目具有相同的值 - 只要当前部分匹配;一旦发生第一个不匹配,就跳出循环

  • 将剩下的部分重新组合在一起

 

function time_range_format($start, $end) {
  for($i=2; $i>=0; --$i) {
    if($end[$i] == $start[$i]) {
      unset($start[$i]);
    }
    else {
      break; // important to leave the loop, once the first non-matching part is encountered
    }
  }
  return ($start ? implode(' ', $start) . ' to ' : '') . implode(' ', $end);
}

var_dump(
  time_range_format(['11', 'Feb', '2020'], ['26', 'Feb', '2020']),
  time_range_format(['26', 'Feb', '2020'], ['5', 'Mar', '2020']),
  time_range_format(['29', 'Dec', '2020'], ['2', 'Jan', '2021']),
  time_range_format(['29', 'Dec', '2020'], ['29', 'Dec', '2020'])
);

以上示例的结果:

11 to 26 Feb 2020
26 Feb to 5 Mar 2020
29 Dec 2020 to 2 Jan 2021
29 Dec 2020

通过检查 $start 末尾是否仍然包含任何内容,如果包含则仅输出 to,您甚至可以处理开始日期和结束日期相同的“边缘情况”,就像最后一样此示例的行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-13
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多