3

PHPで 翌月の日付を取得したいので、いくつかの日付関数を試しましたが、いくつかの問題が発生しました。

MySQL 互換のタイムスタンプ ( date('Y-m-d H:i:s');) としての現在の日付は次のとおりです。
'2012-05-31 14:59:19'

  • date('t', strtotime('next month'));これは翌月の日数を返し、結果として31を返します...これは正しくありません。6月は 30 日しかないためです (7 月の日数を出力するようです)。
  • date('Y-m-d H:i:s', strtotime('next month'));翌月のタイムスタンプ形式を与える 、を返します'2012-07-01 14:59:19'が、私は次のことを期待します:
    '2012-06-30 14:59:19'.

だから私はいくつかのコードを試しました.ここに私の実験date()strtotime()ありDateTime classます.

OUTPUT は次のようになります (ここでも確認できます! )。 翌月に関連する PHP 日付関数

これらは PHP のバグですか、それとも何か誤解していますか?


MySQL の日付関数を使用した場合と同じ結果が期待できますが、いくつか例を示します。

SELECT NOW( )

2012-05-31 17:51:15

SELECT DATE_ADD(NOW(), INTERVAL 1 MONTH)

2012-06-30 17:51:15

SELECT DATE_ADD( '2013-01-30 17:51:15', INTERVAL 1 MONTH )

2013-02-28 17:51:15

SELECT DATE_ADD( '2013-01-31 17:51:15', INTERVAL 1 MONTH )

2013-02-28 17:51:15

4

3 に答える 3

2

OK、解決策を見つけたと思います。これは、MySQL のDATE_ADD関数 with と同様に動作しますINTERNAL 1 MONTH
問題のある可能性のあるすべてのケースで関数をテストしましたが、正しく動作しているようです。
ここに貼り付けます。誰かが役に立つと思うかもしれません。このコードにはいくつかのコメントを入れているので、十分に明確だと思います。

関数は と呼ばれgetOneMonthLaterTimestampます。例:

echo getOneMonthLaterTimestamp('2012-05-31 17:51:15');

出力: 2012-06-30 17:51:15

関数

/**
 * Test function for dumping variables in a readable way
 * 
 * @param mixed $stuff
 * @param string $text
 * @return string 
 */
function my_var_export($stuff, $text = '...') {
    return '<p>' . $text . ' (' . gettype($stuff) . '):</p><pre>' . var_export($stuff, TRUE) . '</pre>';
}

/**
 * Get timestamp format of the date one month later 
 * than the date given in the argument/current date if left empty.
 * 
 * Behaves similar to MySQL's DATE_ADD function with INTERVAL 1 MONTH:
 * SELECT DATE_ADD('2012-05-31 17:51:15', INTERVAL 1 MONTH)
 * --> 2012-06-30 17:51:15
 * SELECT DATE_ADD('2013-01-30 17:51:15', INTERVAL 1 MONTH )
 * --> 2013-02-28 17:51:15
 * 
 * these are equivalent to:
 * echo getOneMonthLaterTimestamp('2012-05-31 17:51:15');
 * echo getOneMonthLaterTimestamp('2013-01-30 17:51:15');
 * 
 * You can also call it without an argument. This way, the current date is taken as a basis.
 * echo getOneMonthLaterTimestamp();
 * 
 * @param string $DateTime_param date/time string
 * @see http://www.php.net/manual/en/datetime.formats.php
 * @see http://www.php.net/manual/en/datetime.construct.php
 * 
 * @return string Date one month later as a MySQL-compatible timestamp format
 */
function getOneMonthLaterTimestamp($DateTime_param = NULL) {
    // if argument is left empty, the current date is taken as a basis
    if (empty($DateTime_param)) {
        $DateTime_param = date('Y-m-d H:i:s');
    }

    $lastDayOfNextMonth = new DateTime($DateTime_param);
    $lastDayOfNextMonth->modify('last day of next month');

    $nextMonth = new DateTime($DateTime_param);
    $nextMonth->modify('next month');

    if ($lastDayOfNextMonth->format('n') < $nextMonth->format('n')) {
        $oneMonthLaterTimestamp = $lastDayOfNextMonth->format('Y-m-d H:i:s');
    }
    else {
        $oneMonthLaterTimestamp = $nextMonth->format('Y-m-d H:i:s');
    }

    return $oneMonthLaterTimestamp;
}

テストケース

$timestamps_to_test_array = array(
  date('Y-m-d H:i:s'),   // 1. current date
  '2011-01-28 23:59:59', // 2.
  '2011-01-29 23:59:59', // 3.
  '2011-01-30 23:59:59', // 4.
  '2011-01-31 23:59:59', // 5.
  '2012-01-28 23:59:59', // 6.
  '2012-01-29 23:59:59', // 7.
  '2012-01-30 23:59:59', // 8.
  '2012-01-31 23:59:59', // 9.
  '2012-02-29 23:59:59', // 10.
  '2012-03-30 23:59:59', // 11.
  '2012-03-31 23:59:59', // 12.
  '2012-04-30 23:59:59', // 13.
  '2012-05-31 23:59:59', // 14.
  '2012-12-31 23:59:59', // 15.
  '2013-01-31 23:59:59', // 16.
  '2013-02-28 23:59:59', // 17.
);

$i = 1;

foreach ($timestamps_to_test_array as $timestamp_to_test) {
    $oneMonthLaterTimestamp = getOneMonthLaterTimestamp($timestamp_to_test);
    echo my_var_export($timestamp_to_test, '[' . $i . ']. Timestamp to test ($timestamp_to_test)');
    echo my_var_export($oneMonthLaterTimestamp, 'Timestamp + 1 month (getOneMonthLaterTimestamp($timestamp_to_test))');
    echo '<hr />';
    $i++;
}

テストケースの出力

ここに出力を貼り付けました: http://pastebin.com/rY5ZRBs9
これがそのスクリーンショットです: http://i.imgur.com/KwlJq.png

翌月の日数を取得する

/**
 * Get number of days in the next month
 *
 * @param string $DateTime_param date/time string
 * @return int Number of days in the next month
 */
function getNumberOfDaysInNextMonth($DateTime_param = NULL) {
    // if argument is empty, the current date is taken as a basis
    if (empty($DateTime_param)) {
        $DateTime_param = date('Y-m-d H:i:s');
    }

    // DateTime instance
    $dateCurrent = new DateTime($DateTime_param);
    $dateCurrent->modify('last day of next month');
    return (int)$dateCurrent->format('t');
}

/**
 * It's identical to getNumberOfDaysInNextMonth()
 *
 * @see getNumberOfDaysInNextMonth
 */
function getLastDayOfNextMonth($DateTime_param = NULL) {
    return getNumberOfDaysInNextMonth($DateTime_param);
}

テストケース

$lastDayOfNextMonth = getLastDayOfNextMonth('2012-05-31 03:50:27');
echo my_var_export($lastDayOfNextMonth, "Get last day of next month (getLastDayOfNextMonth('2012-05-31 03:50:27'))");

出力:

Get last day of next month (getLastDayOfNextMonth('2012-05-31 03:50:27')) (integer):
30
于 2012-06-01T01:39:29.613 に答える
1

この時点で:

翌月をタイムスタンプとして取得 [ date('Ymd H:i:s', strtotime('next month')); ]:
'2012-07-01 14:59:19'

翌月の最終日を DateTime クラスのタイムスタンプとして取得 [ $dateObj->add(new >DateInterval('P1M')); $dateObj->format('Ymd H:i:s'); ]:
'2012-07-01 14:59:19'

「来月」が 7 月の日付を出力することは明らかです...

strtotime('+1 month')代わりに試してください。

編集:説明: 今日は 5 月 31 日です。あなたが呼び出すと、6月31日の日付が間違っているため、7月1日の日付が正しく出力されます...したがって、それも失敗するstrtotime('next month')と思います...strtotime('+1 month')

したがって、より良い解決策は、今月の 15 日の日付を取得し、その日付に対して「翌月」または「+1 か月」を使用することです...

于 2012-05-31T13:18:55.103 に答える
1

ちょっとした操作で目的を達成できます(つまり、質問が正しい場合)

$next_month = mktime(0, 0, 0, date("m")+1, 1, date("Y"));
//gets next month
echo "<br />".date("D jS M, Y", $next_month);
//sets the value
echo "<br />".date("t", $next_month);
//number of days next month

各月には日があるため、これにより、必要な月にアクセスできるようになりますfirst。つまり、次の年を取得するには、適切な値を変更するだけです

于 2012-05-31T13:31:39.283 に答える