簡體   English   中英

如何使用 strtotime 和日期獲取相對於今天的上一月和一年?

[英]How to get previous month and year relative to today, using strtotime and date?

我需要獲得相對於當前日期的前一個月和一年。

但是,請參見以下示例。

// Today is 2011-03-30
echo date('Y-m-d', strtotime('last month'));

// Output:
2011-03-02

這種行為是可以理解的(在某種程度上),由於二月和三月的天數不同,上面示例中的代碼是我需要的,但在每個月的 1 日和 28 日之間只能 100% 正確地工作。

那么,如何以盡可能最優雅的方式獲得上個月和年份(想想date("Ym") ),這適用於一年中的每一天? 最佳解決方案將基於strtotime參數解析。

更新。 稍微澄清一下需求。

我有一段代碼可以獲取過去幾個月的一些統計數據,但我首先顯示上個月的統計數據,然后在需要時加載其他月份。 這就是預期目的。 所以,在這個月期間,我想知道我應該拉哪個月份來加載以前的月份統計數據。

我還有一個時區感知代碼(現在不是很重要),它接受strtotime兼容字符串作為輸入(初始化內部日期),然后允許調整日期/時間,也使用strtotime兼容字符串.

我知道它可以用很少的條件和基本數學來完成,但是與此相比,這真的很混亂,例如(當然,如果它工作正常):

echo tz::date('last month')->format('Y-d')

所以,我只需要前一個月和前一年,以與strtotime兼容的方式。

回答(謝謝,@dnagirl):

// Today is 2011-03-30
echo date('Y-m-d', strtotime('first day of last month')); // Output: 2011-02-01

看看DateTime類。 它應該正確進行計算並且日期格式與strttotime兼容。 就像是:

$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02

如果這一天本身無關緊要,請執行以下操作:

echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));

我找到了一個答案,因為我今天遇到了同樣的問題,這是第 31 次。 正如某些人所建議的那樣,這不是php 中錯誤,而是預期的功能(從那時起)。 根據這篇文章, strtotime 實際所做的是將月份設置回 1 並且不修改天數。 因此,在今天 5 月 31 日的情況下,它正在尋找無效日期的 4 月-31 日。 所以它需要 4 月 30 日,然后在它之后增加 1 天並產生 5 月 1 日。

在您的示例 2011-03-30 中,它將返回一個月到 2 月 30 日,這是無效的,因為 2 月只有 28 天。 然后取那些天的差值 (30-28 = 2),然后在 2 月 28 日(即 3 月 2 日)之后移動兩天。

正如其他人指出的那樣,獲得“上個月”的最佳方法是使用 strtotime 或 DateTime 對象添加“第一天”或“最后一天”:

// Today being 2012-05-31
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d'); 

// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month")); 
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');

因此,如果您進行查詢等,使用這些可以創建日期范圍。

如果您想要相對於特定日期的前一年和一個月,並且有可用的 DateTime,那么您可以執行以下操作:

$d = new \DateTimeImmutable('2013-01-01', new \DateTimeZone('UTC')); 
$firstDay = $d->modify('first day of previous month');
$year = $firstDay->format('Y'); //2012
$month = $firstDay->format('m'); //12
date('Y-m', strtotime('first day of last month'));

strtotime有第二個timestamp參數,使第一個參數相對於第二個參數。 所以你可以這樣做:

date('Y-m', strtotime('-1 month', time()))

如果我正確理解了這個問題,你只想要上個月和它所在的年份:

<?php

  $month = date('m');
  $year = date('Y');
  $last_month = $month-1%12;
  echo ($last_month==0?($year-1):$year)."-".($last_month==0?'12':$last_month);

?>

這是示例: http : //codepad.org/c99nVKG8

呃,它不是一個人提到的錯誤。 這是預期的行為,因為一個月中的天數通常不同。 使用 strtotime 獲取上個月的最簡單方法可能是從本月的第一天開始使用 -1 個月。

$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));

我認為您在 strtotime 函數中發現了一個錯誤。 每當我不得不解決這個問題時,我總是發現自己在計算月/年值。 嘗試這樣的事情:

$LastMonth = (date('n') - 1) % 12;
$Year      =  date('Y') - !$LastMonth;

這是因為上個月的天數比當月少。 我已經通過首先檢查上個月的天數是否少於當前的天數並根據它更改計算來解決此問題。

如果天數較少,則獲取 -1 個月的最后一天,否則獲取 -1 個月的當前日期:

if (date('d') > date('d', strtotime('last day of -1 month')))
{
    $first_end = date('Y-m-d', strtotime('last day of -1 month'));
}
else
{
    $first_end = date('Y-m-d', strtotime('-1 month'));
}

也許比你想要的稍微長一些,但我使用了比可能更多的代碼,以便它更具可讀性。

也就是說,它產生的結果與您得到的結果相同 - 您想要/期望它產生什么?

//Today is whenever I want it to be.
$today = mktime(0,0,0,3,31,2011);

$hour   = date("H",$today);
$minute = date("i",$today);
$second = date("s",$today);
$month  = date("m",$today);
$day    = date("d",$today);
$year   = date("Y",$today);

echo "Today: ".date('Y-m-d', $today)."<br/>";
echo "Recalulated: ".date("Y-m-d",mktime($hour,$minute,$second,$month-1,$day,$year));

如果您只想要月份和年份,那么只需將日期設置為“01”而不是“今天”:

 $day = 1;

那應該給你你需要的東西。 您可以將小時、分鍾和秒設置為零,並且您對使用這些不感興趣。

 date("Y-m",mktime(0,0,0,$month-1,1,$year);

減少了很多;-)

date("m-Y", strtotime("-1 months")); 

會解決這個問題

如果 DateTime 解決方案是可接受的,則此代碼段返回上個月的年份和上個月的月份,避免在一月份運行時可能出現的陷阱。

function fn_LastMonthYearNumber()
{
 $now = new DateTime();
 $lastMonth = $now->sub(new DateInterval('P1M'));
 $lm= $lastMonth->format('m');
 $ly= $lastMonth->format('Y');
 return array($lm,$ly);
}
//return timestamp, use to format month, year as per requirement
function getMonthYear($beforeMonth = '') {
    if($beforeMonth !="" && $beforeMonth >= 1) {
        $date = date('Y')."-".date('m')."-15";
        $timestamp_before = strtotime( $date . ' -'.$beforeMonth.' month' );
        return $timestamp_before;
    } else {
        $time= time();
        return $time;
    }
}


//call function
$month_year = date("Y-m",getMonthYear(1));// last month before  current month
$month_year = date("Y-m",getMonthYear(2)); // second last month before current month
function getOnemonthBefore($date){
    $day = intval(date("t", strtotime("$date")));//get the last day of the month
    $month_date = date("y-m-d",strtotime("$date -$day days"));//get the day 1 month before
    return $month_date;
}

結果日期取決於輸入月份所包含的天數。 如果輸入月份是二月(28 天),則 2 月 5 日之前的 28 天是 1 月 8 日。如果輸入是 5 月 17 日,則之前 31 天是 4 月 16 日。同樣,如果輸入是 5 月 31 日,則結果日期將為 4 月 30 日。

注意:輸入需要完整的日期 ('ym-d') 和輸出 ('ym-d') 您可以修改此代碼以滿足您的需要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM