PHP人类日期范围/持续时间格式

时间:2015-04-30 19:19:59

标签: php date format

PHP制作精良,我想知道是否有我需要的功能。

对于持续超过一天的事件,人类的格式化方式很复杂。

... Exemples

活动一:2015-04-20至2015-04-22可以为这样的人格式化:2015年4月20日至22日

活动二:2015-04-01至2015-05-31人类 - > 2015年4月至5月

活动三:2015-04-30至2015-05-02人类 - > 2015年4月30日至5月2日

简而言之,永远不要重复不需要重复的内容。链接" - "尽可能多。

必须进行本地化,格式可能会因本地而异。例如,美国人喜欢MonthName DayNumber Year,但法国人喜欢DayNumber MonthName Year。

我计划编程这样的格式化,但我想知道它是否已经存在:)

3 个答案:

答案 0 :(得分:3)

这有效......

function humanDateRanges($start, $end){
    $startTime=strtotime($start);
    $endTime=strtotime($end);

    if(date('Y',$startTime)!=date('Y',$endTime)){
        echo date('F j, Y',$startTime) . " to " . date('F j, Y',$endTime);
    }else{
        if((date('j',$startTime)==1)&&(date('j',$endTime)==date('t',$endTime))){
            echo date('F',$startTime) . " to " . date('F, Y',$endTime);
        }else{
            if(date('m',$startTime)!=date('m',$endTime)){
                echo date('F j',$startTime) . " to " . date('F j, Y',$endTime);
            }else{
                echo date('F j',$startTime) . " to " . date('j, Y',$endTime);
            }
        }
    }
}

humanDateRanges("2015-04-20", "2015-04-22");
//April 20 to 22, 2015
humanDateRanges("2015-04-01", "2015-05-31");
//April to May, 2015
humanDateRanges("2015-04-30", "2015-05-02");
//April 30 to May 2, 2015
humanDateRanges("2014-05-02", "2015-05-02");
//May 2, 2014 to May 2, 2015

但我认为在某些情况下,甚至需要告诉人类,4月至5月将从1日开始到31日结束。

答案 1 :(得分:0)

以防万一其他人偶然发现:我写了一个小型图书馆试图以一种同样适用于国际化的方式解决这个问题:

https://github.com/flack/ranger

它应该为ltr语言提供合理的默认值(并且rtl支持不应该太难添加)

答案 2 :(得分:0)

这是一种尝试针对所有可能的语言环境的解决方案。
肯定还有改进的空间。
看看这个演示:https://www.tehplayground.com/JIrjclNy3jEoVrTJ

function format_dateRange($from, $to, $options=[]){
    if (!is_numeric($from)) $from = strtotime($from);
    if (!is_numeric($to)) $to = strtotime($to);

    $fromArr = explode('.',date('Y.n.j', $from));
    $toArr   = explode('.',date('Y.n.j', $to));

    $sameYear  = $fromArr[0] === $toArr[0];
    $sameMonth = $sameYear && $fromArr[1] === $toArr[1];
    $sameDay   = $sameMonth && $fromArr[2] === $toArr[2];


    $locale = $options['locale'] ?? setlocale(LC_ALL, 0);
    $dateType = $options['dateType'] ?? \IntlDateFormatter::LONG;
    $timeType = $options['timeType'] ?? \IntlDateFormatter::SHORT;
    $ignoreTime = $timeType === 'none' || ($timeType === 'optional' && !$sameDay);

    if ($timeType === 'optional') {
        $timeType = $sameDay ? \IntlDateFormatter::SHORT : \IntlDateFormatter::NONE;
    }

    $startFormatter = new \IntlDateFormatter($locale,$dateType,$timeType,null);
    $pattern = $startFormatter->getPattern();

    $timeSeparator = $options['timeSeparator'] ?? ' – '; 
    $daySeparator  = $options['daySeparator'] ?? ' – ';
    $dateSeparator = $options['dateSeparator'] ?? ' – ';

    if ($timeType === \IntlDateFormatter::NONE) {
        if ($sameMonth) { // include day-range
            preg_match("/(?<!['])dd?\.?/", $pattern, $matches);
            $partPattern = trim($matches[0]);
            $endFormatter = new \IntlDateFormatter($locale,$dateType,$timeType,null);
            $endFormatter->setPattern($partPattern);
            $endPart = $endFormatter->getPattern();
            $preg = "/".preg_quote($partPattern)."(?!e)/"; 
            $pattern = preg_replace($preg, $partPattern."'".$daySeparator.($endFormatter->format($to))."'", $pattern); 
        } else if ($sameYear) { // include day-month-range
            preg_match('/(d+.+M+|M+.+d+(?!\'))/', $pattern, $matches);
            $partPattern = $matches[0];
            $endFormatter = new \IntlDateFormatter($locale,$dateType,$timeType,null);
            $endFormatter->setPattern($partPattern);
            $endPart = $endFormatter->getPattern();
            $pattern = str_replace($partPattern, $partPattern."'".$daySeparator.($endFormatter->format($to))."'", $pattern);
        }
        // else just the pattern?
    } else {
        if ($sameDay) { // incluce time-range
            $endFormatter = new \IntlDateFormatter($locale,\IntlDateFormatter::NONE,$timeType,null);
            $endPart = $endFormatter->getPattern();
            $pattern = str_replace($endPart, $endPart."'".$timeSeparator.($endFormatter->format($to))."'", $pattern);
        } else { // append end-date
            $endFormatter = new \IntlDateFormatter($locale,$dateType,$timeType,null);
            $pattern .= "'".$dateSeparator.$endFormatter->format($to)."'";
        }
    }

    $startFormatter->setPattern($pattern);
    $str = $startFormatter->format($from);
    return $str;
}

$locales = ['af-ZA','am-ET','ar-AE','ar-BH','ar-DZ','ar-EG','ar-IQ','ar-JO','ar-KW','ar-LB','ar-LY','ar-MA','arn-CL','ar-OM','ar-QA','ar-SA','ar-SY','ar-TN','ar-YE','as-IN','az-Cyrl-AZ','az-Latn-AZ','ba-RU','be-BY','bg-BG','bn-BD','bn-IN','bo-CN','br-FR','bs-Cyrl-BA','bs-Latn-BA','ca-ES','co-FR','cs-CZ','cy-GB','da-DK','de-AT','de-CH','de-DE','de-LI','de-LU','dsb-DE','dv-MV','el-GR','en-029','en-AU','en-BZ','en-CA','en-GB','en-IE','en-IN','en-JM','en-MY','en-NZ','en-PH','en-SG','en-TT','en-US','en-ZA','en-ZW','es-AR','es-BO','es-CL','es-CO','es-CR','es-DO','es-EC','es-ES','es-GT','es-HN','es-MX','es-NI','es-PA','es-PE','es-PR','es-PY','es-SV','es-US','es-UY','es-VE','et-EE','eu-ES','fa-IR','fi-FI','fil-PH','fo-FO','fr-BE','fr-CA','fr-CH','fr-FR','fr-LU','fr-MC','fy-NL','ga-IE','gd-GB','gl-ES','gsw-FR','gu-IN','ha-Latn-NG','he-IL','hi-IN','hr-BA','hr-HR','hsb-DE','hu-HU','hy-AM','id-ID','ig-NG','ii-CN','is-IS','it-CH','it-IT','iu-Cans-CA','iu-Latn-CA','ja-JP','ka-GE','kk-KZ','kl-GL','km-KH','kn-IN','kok-IN','ko-KR','ky-KG','lb-LU','lo-LA','lt-LT','lv-LV','mi-NZ','mk-MK','ml-IN','mn-MN','mn-Mong-CN','moh-CA','mr-IN','ms-BN','ms-MY','mt-MT','nb-NO','ne-NP','nl-BE','nl-NL','nn-NO','nso-ZA','oc-FR','or-IN','pa-IN','pl-PL','prs-AF','ps-AF','pt-BR','pt-PT','qut-GT','quz-BO','quz-EC','quz-PE','rm-CH','ro-RO','ru-RU','rw-RW','sah-RU','sa-IN','se-FI','se-NO','se-SE','si-LK','sk-SK','sl-SI','sma-NO','sma-SE','smj-NO','smj-SE','smn-FI','sms-FI','sq-AL','sr-Cyrl-BA','sr-Cyrl-CS','sr-Cyrl-ME','sr-Cyrl-RS','sr-Latn-BA','sr-Latn-CS','sr-Latn-ME','sr-Latn-RS','sv-FI','sv-SE','sw-KE','syr-SY','ta-IN','te-IN','tg-Cyrl-TJ','th-TH','tk-TM','tn-ZA','tr-TR','tt-RU','tzm-Latn-DZ','ug-CN','uk-UA','ur-PK','uz-Cyrl-UZ','uz-Latn-UZ','vi-VN','wo-SN','xh-ZA','yo-NG','zh-CN','zh-HK','zh-MO','zh-SG','zh-TW','zu-ZA'];
$variants = [];
foreach ($locales as $locale) {
    $variant = format_dateRange(time(), time()+60*5, ['locale' => $locale, 'timeType' => 'optional']);
    $variants[$variant] = [
        'locale' => $locale,
        'sameday' => $variant,
        'samemonth' => format_dateRange(time()-60*60*13, time()+60*60*13, ['locale' => $locale, 'timeType' => 'optional']),
        'sameyear' => format_dateRange(time()-60*60*24*16, time()+60*60*24*16, ['locale' => $locale, 'timeType' => 'optional']),
    ];
}

echo '<table>';
foreach ($variants as $variant => $row) {
    echo 
    '<tr>'.
        '<td>'.$row['locale'].
        '<td>'.$row['sameday'].
        '<td>'.$row['samemonth'].
        '<td>'.$row['sameyear'];
}
echo '</table>';