8

PHP (5.3+) の DateTime クラスは、あなたの国で週の最初の曜日が日曜日である限り、うまく機能します。オランダでは、週の最初の日は月曜日です。そのため、このクラスは、週のビューと計算を備えたカレンダーを作成するのには役に立ちません。

週の最初の日が月曜日であるかのように DateTime を動作させる方法について、Stackoverflow またはその他のインターネットで答えが見つからないようです。

Stackoverflow でこの記事を見つけましたが、問題が発生する可能性があるすべての方法を修正するわけではなく、洗練された解決策ではありません。

$dateTime = new DateTime('2012-05-14');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');

これを変更する方法、または DateTime の範囲を変更する方法はありますか? ヨーロッパのほとんどが月曜日に週を始めるので、それが設定ではないことを想像することはできません.

追加: 完全なカレンダーと関数のコードを投稿しても、物事が明確になるわけではありません。しかし、ここに1行の例があります。週の最初の日が何であるかを確認したり、週の最初の日からその週の別の日時まで計算したりする必要があることがよくあります。私のコードはこれらでいっぱいになっています:

$startOfWeek = $date->modify(('Sunday' == $date->format('l')) ? 'Monday last week' : 'Monday this week')->modify('+3 hours')->format(DATETIME);

また、月または年の最初の完全な週を取得しようとすると、望ましくない結果が得られます。私の $date オブジェクトには常に同じ日付が含まれているとは限らないため、この方法でチェックし続ける必要があり、コードが読みにくくなっています。このカレンダーでさらに多くのプログラミングを行う必要があるため、どこで再びバグが発生するか予測できません。

EDITただし、いくつかの矛盾があります。いくつかの奇妙な理由で、DateTime は次のものを正しく取得します。

$test = new DateTime('2012-10-29'); // Monday
echo $test->modify('Sunday this week')->format('Y-m-d');  // 2012-11-04

// But...

$test = new DateTime('2012-11-04'); // Sunday
echo $test->modify('Monday this week')->format('Y-m-d');  // 2012-11-05 instead of 2012-10-29   

しかし、私は質問をより明確にすることができると思います: DateTime() クラスは月曜日を週の最初の日として使用できますか? そうでない場合は、月曜日を週の最初の日として使用するようにクラスを拡張できますか。

更新: わかりました、私はどこかに到達していると思います...私はコーディングクラスのプロではありません..しかし、これは数週間うまくいくようです. しかし、まだ 1 日目、2 日目、そして日曜日という名前のルールも必要です。これは万能ではないと思います。それを修正するための助けをいただければ幸いです。

class EuroDateTime extends DateTime {

// Fields
private $weekModifiers = array (
    'this week',
    'next week',
    'previous week',
    'last week'
);

// Override "modify()"
public function modify($string) {

    // Search pattern
    $pattern = '/'.implode('|', $this->weekModifiers).'/';

    // Change the modifier string if needed
    if ( $this->format('N') == 7 ) { // It's Sunday
        $matches = array();
        if ( preg_match( $pattern, $string, $matches )) {
            $string = str_replace($matches[0], '-7 days '.$matches[0], $string);
        }
    }
    return parent::modify($string);

}

}
// This works
$test = new EuroDateTime('2012-11-04');
echo $test->modify('Monday this week')->format('Y-m-d');
// And I can still concatenate calls like the DateTime class was intended
echo $test->modify('Monday this week')->modify('+3 days')->format('Y-m-d');
4

5 に答える 5

6

これは機能することがわかりましたが、PHP の DateTime クラスにはいくつかの矛盾があります。

出発日が日曜日の場合、前の月曜日は同じ週とは見なされません (このクラスによって固定されます)。ただし、月曜日から出発し、次の日曜日が同じ週と見なされます。彼らが将来それを修正する場合、このクラスにはいくつかの追加が必要になります。

class EuroDateTime extends DateTime {

// Override "modify()"
public function modify($string) {

    // Change the modifier string if needed
    if ( $this->format('N') == 7 ) { // It's Sunday and we're calculating a day using relative weeks
        $matches = array();
        $pattern = '/this week|next week|previous week|last week/i';
        if ( preg_match( $pattern, $string, $matches )) {
            $string = str_replace($matches[0], '-7 days '.$matches[0], $string);
        }
    }
    return parent::modify($string);

}

}
于 2012-10-30T00:48:12.130 に答える
2

「最初」の定義に応じて、日付を手動で変更して「最初」の曜日を取得することを止めるものは何もありません。例えば:

$firstDayOfWeek = 1; // Monday
$dateTime = new DateTime('2012-05-16'); // Wednesday

// calculate how many days to remove to get back to the "first" day
$difference = ($firstDayOfWeek - $dateTime->format('N'));
if ($difference > 0) { $difference -= 7; }
$dateTime->modify("$difference days");

var_dump($dateTime->format('r')); // "Mon, 14 May 2012 00:00:00 +0000"

変化に応じて出力がどのように変化するかに注意してください$firstDayOfWeek。上記(木曜日)に変更された場合は、「最初の」日4と見なされます。Thu, 10 May 2012

編集:これはかなり基本的な例です。これを行う正しい方法は、ユーザー/システムのロケールを使用して「最初の」日を指定し、そこから計算することです。詳細については、この質問を参照してください。

于 2012-10-29T20:30:07.633 に答える
0

月曜日から始まる週の概念があるため、私も問題が何であるかについて混乱しています。このDateTime 形式N月曜日から日曜日までを数えた曜日を示します。月曜日は 1、日曜日は 7Wです。週番号を取得する唯一の方法である も、月曜日に週を開始します。(オランダの週番号は ISO の週番号とまったく同じではないことを覚えているようですが、それは別の話です)。では、正確に欠けている機能は何ですか?

編集したがって、問題は (のみ?)参照日が日曜日の場合、「今週の月曜日」などの相対的な日時形式が間違った結果をもたらすことです。docs からは、ロケールに依存するはずの にDateTime委ねているように聞こえます。strtotimeしたがってロケールが適切に設定されていて、これが機能しない場合は、バグのように聞こえます (それだけの価値があります)。

于 2012-10-29T22:23:51.407 に答える