ngày tăng thêm một tháng


103

Giả sử tôi có một ngày ở định dạng sau: 2010-12-11 (năm-thứ-ngày)

Với PHP, tôi muốn tăng ngày một tháng và tôi muốn năm được tự động tăng, nếu cần (tức là tăng từ tháng 12 năm 2012 đến tháng 1 năm 2013).

Trân trọng.

Câu trả lời:


167
$time = strtotime("2010.12.11");
$final = date("Y-m-d", strtotime("+1 month", $time));

// Finally you will have the date you're looking for.

31
Nó không hoạt động với tất cả các ngày. Ví dụ: 2013-05-31 sẽ hiển thị tháng 7 thay vì tháng tiếp theo là tháng 6.
Patrick Desjardins

1
Tôi đang theo dõi, 2014-03-03 2014-01-31 vì lý do gì?
Manish Goyal

Nó không hoạt động với chuỗi này: "2014-06-19 15:00:19"
Meetai.com

1
Điều này đôi khi phá vỡ. Câu trả lời của @jason về mặt kỹ thuật là đúng hơn vì nó tính đến những thứ như năm nhuận, độ dài tháng, v.v. Đó phải được đánh dấu là câu trả lời đúng.
skift

4
câu trả lời này rất nguy hiểm vì nó không thành công trong các tình huống "ngày cuối cùng của tháng" khó phát hiện.
ckonig,

43

Tôi cần chức năng tương tự, ngoại trừ chu kỳ hàng tháng (cộng với tháng, trừ đi 1 ngày). Sau khi tìm kiếm SO một lúc, tôi đã có thể tạo ra giải pháp plug-n-play này:

function add_months($months, DateTime $dateObject) 
    {
        $next = new DateTime($dateObject->format('Y-m-d'));
        $next->modify('last day of +'.$months.' month');

        if($dateObject->format('d') > $next->format('d')) {
            return $dateObject->diff($next);
        } else {
            return new DateInterval('P'.$months.'M');
        }
    }

function endCycle($d1, $months)
    {
        $date = new DateTime($d1);

        // call second function to add the months
        $newDate = $date->add(add_months($months, $date));

        // goes back 1 day from date, remove if you want same day of month
        $newDate->sub(new DateInterval('P1D')); 

        //formats final date to Y-m-d form
        $dateReturned = $newDate->format('Y-m-d'); 

        return $dateReturned;
    }

Thí dụ:

$startDate = '2014-06-03'; // select date in Y-m-d format
$nMonths = 1; // choose how many months you want to move ahead
$final = endCycle($startDate, $nMonths); // output: 2014-07-02

3
Tuyệt vời, đúng những gì tôi cần. Cảm ơn vì đã tiết kiệm cho tôi rất nhiều thời gian!
Tum

Không sao, rất vui vì bạn thấy nó hữu ích
Jason

Cảm ơn Jason, điều này rất hữu ích. Tôi đã định dạng lại nó và thêm nhiều bình luận hơn để giúp tôi hiểu tất cả. Trong trường hợp có thể giúp được bất cứ ai, tôi đã đăng nó xuống thêm (đã cố gắng thêm nó ở đây nhưng nó quá dài).
Greg

1
nó cho giá trị tương tự cho ngày 30 tháng 1 và ngày 31 tháng 1!
bảy,

Hoạt động như một sự quyến rũ, vừa được thử nghiệm từ ngày 1 tháng 1 đến ngày 31 tháng 12 năm 2020, cảm ơn!
Paul Nowak

34

Sử dụng DateTime::add.

$start = new DateTime("2010-12-11", new DateTimeZone("UTC"));
$month_later = clone $start;
$month_later->add(new DateInterval("P1M"));

Tôi đã sử dụng clone vì add sửa đổi đối tượng gốc, đối tượng này có thể không được mong muốn.


1
không hoạt động .. (DateTime mới ("2010-01-31", DateTimeZone mới ("UTC"))) -> add (new DateInterval ("P1M")) -> format ('Ym-d') dẫn đến 2010-03-03
Scholtz

13
strtotime( "+1 month", strtotime( $time ) );

điều này trả về một dấu thời gian có thể được sử dụng với hàm ngày


@Gelen: cái này không hiệu quả, sai ngày .... vui lòng cho biết cách sử dụng phương pháp của bạn, giá trị của $ time ở đây là bao nhiêu?
sqlchild

điều này không hoạt động, cung cấp sai ngày .... vui lòng cho biết cách sử dụng phương pháp của bạn, giá trị của $ time ở đây là gì?
sqlchild

Vấn đề tương tự như câu trả lời được chấp nhận. Không hoạt động trên tất cả các chuỗi.
Meetai.com

điều này làm việc cho tôi (tất nhiên $timecó giá trị ban đầu).
tatskie

6
(date('d') > 28) ? date("mdY", strtotime("last day of next month")) : date("mdY", strtotime("+1 month"));

Điều này sẽ bù đắp cho tháng Hai và 31 ngày khác của tháng. Tất nhiên, bạn có thể kiểm tra nhiều hơn để có được chính xác hơn cho các định dạng ngày tương đối 'ngày này tháng sau' (điều này không hoạt động đáng buồn, hãy xem bên dưới) và bạn cũng có thể sử dụng DateTime.

Cả hai DateInterval('P1M')strtotime("+1 month")về cơ bản là thêm 31 ngày một cách mù quáng bất kể số ngày trong tháng tiếp theo.

  • 2010-01-31 => Ngày 3 tháng 3
  • 2012-01-31 => Ngày 2 tháng 3 (năm nhuận)

3
"thêm một cách mù quáng 31 ngày bất kể số ngày trong tháng sau", hoàn toàn đúng! (+1).
Jose Manuel Abarca Rodríguez


5

Tôi sử dụng cách này: -

 $occDate='2014-01-28';
 $forOdNextMonth= date('m', strtotime("+1 month", strtotime($occDate)));
//Output:- $forOdNextMonth=02


/*****************more example****************/
$occDate='2014-12-28';

$forOdNextMonth= date('m', strtotime("+1 month", strtotime($occDate)));
//Output:- $forOdNextMonth=01

//***********************wrong way**********************************//
$forOdNextMonth= date('m', strtotime("+1 month", $occDate));
  //Output:- $forOdNextMonth=02; //instead of $forOdNextMonth=01;
//******************************************************************//

1
nó làm việc cho tôi cảm ơn. Tuy nhiên, date ('m', strtotime ("+ 1 tháng", strtotime ($ mysDate))) và date ('m', strtotime ("+ 1 tháng", $ shorDate)) hoạt động giống nhau.

1
Không, cả hai đều là sự khác biệt @ sah.cyBuzzSc. Hãy xem xét ví dụ: - $ opensDate = '2014-12-28'; $ forOdNextMonth = date ('m', strtotime ("+ 1 tháng", $ opensDate)); Giá trị $ forOdNextMonth là 02.
Nhoet

cảm ơn vì đã giải thích @chotesah. Ví dụ thứ hai của bạn là khá tốt.

3

Trước tiên, vui lòng đặt định dạng ngày của bạn như 12-12-2012

Sau khi sử dụng chức năng này, nó hoạt động bình thường;

$date =  date('d-m-Y',strtotime("12-12-2012 +2 Months");

Đây là ngày 12-12-2012 là ngày của bạn và +2 Tháng là gia số của tháng;

Bạn cũng tăng dần Năm, Ngày

strtotime("12-12-2012 +1 Year");

Trả lời là ngày 12-12-2013


1

Cảm ơn Jason, bài viết của bạn rất hữu ích. Tôi đã định dạng lại nó và thêm nhiều bình luận hơn để giúp tôi hiểu tất cả. Trong trường hợp có thể giúp được bất cứ ai, tôi đã đăng nó ở đây:

function cycle_end_date($cycle_start_date, $months) {
    $cycle_start_date_object = new DateTime($cycle_start_date);

    //Find the date interval that we will need to add to the start date
    $date_interval = find_date_interval($months, $cycle_start_date_object);

    //Add this date interval to the current date (the DateTime class handles remaining complexity like year-ends)
    $cycle_end_date_object = $cycle_start_date_object->add($date_interval);

    //Subtract (sub) 1 day from date
    $cycle_end_date_object->sub(new DateInterval('P1D')); 

    //Format final date to Y-m-d
    $cycle_end_date = $cycle_end_date_object->format('Y-m-d'); 

    return $cycle_end_date;
}

//Find the date interval we need to add to start date to get end date
function find_date_interval($n_months, DateTime $cycle_start_date_object) {
    //Create new datetime object identical to inputted one
    $date_of_last_day_next_month = new DateTime($cycle_start_date_object->format('Y-m-d'));

    //And modify it so it is the date of the last day of the next month
    $date_of_last_day_next_month->modify('last day of +'.$n_months.' month');

    //If the day of inputted date (e.g. 31) is greater than last day of next month (e.g. 28)
    if($cycle_start_date_object->format('d') > $date_of_last_day_next_month->format('d')) {
        //Return a DateInterval object equal to the number of days difference
        return $cycle_start_date_object->diff($date_of_last_day_next_month);
    //Otherwise the date is easy and we can just add a month to it
    } else {
        //Return a DateInterval object equal to a period (P) of 1 month (M)
        return new DateInterval('P'.$n_months.'M');
    }
}

$cycle_start_date = '2014-01-31'; // select date in Y-m-d format
$n_months = 1; // choose how many months you want to move ahead
$cycle_end_date = cycle_end_date($cycle_start_date, $n_months); // output: 2014-07-02

1
$date = strtotime("2017-12-11");
$newDate = date("Y-m-d", strtotime("+1 month", $date));

Nếu bạn muốn tăng dần theo ngày, bạn cũng có thể làm điều đó

$date = strtotime("2017-12-11");
$newDate = date("Y-m-d", strtotime("+5 day", $date));

1

Chỉ cần cập nhật câu trả lời với phương pháp đơn giản để tìm ngày sau không tháng. Vì câu trả lời tốt nhất được đánh dấu không đưa ra giải pháp chính xác.

<?php

    $date = date('2020-05-31');
    $current = date("m",strtotime($date));
    $next = date("m",strtotime($date."+1 month"));
    if($current==$next-1){
        $needed = date('Y-m-d',strtotime($date." +1 month"));
    }else{
        $needed = date('Y-m-d', strtotime("last day of next month",strtotime($date)));
    }
    echo "Date after 1 month from 2020-05-31 would be : $needed";

?>

Chỉ Đây là giải pháp chính xác cho ngày tháng +1.
ứng dụng asad

0
function dayOfWeek($date){
    return DateTime::createFromFormat('Y-m-d', $date)->format('N');
}

Các ví dụ sử dụng:

echo dayOfWeek(2016-12-22);
// "4"
echo dayOfWeek(date('Y-m-d'));
// "4"

0

Đối với bất kỳ ai đang tìm kiếm câu trả lời cho bất kỳ định dạng ngày nào.

echo date_create_from_format('d/m/Y', '15/04/2017')->add(new DateInterval('P1M'))->format('d/m/Y');

Chỉ cần thay đổi định dạng ngày.


-2

đặt ngày vào hộp nhập liệu rồi nhấp vào nút lấy ngày từ ngày trong jquery

$(document).ready( function() {
    $("button").click(function(){   
    var day = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
    var a = new Date();
    $(".result").text(day[a.getDay()]);

    });  
             });

-2
 <?php
              $selectdata ="select fromd,tod  from register where username='$username'";
            $q=mysqli_query($conm,$selectdata);
            $row=mysqli_fetch_array($q);

            $startdate=$row['fromd']; 
            $stdate=date('Y', strtotime($startdate));  

            $endate=$row['tod']; 
            $enddate=date('Y', strtotime($endate));  

            $years = range ($stdate,$enddate);
            echo '<select name="years" class="form-control">';
            echo '<option>SELECT</option>';
            foreach($years as $year)
              {   echo '<option value="'.$year.'"> '.$year.' </option>';  }
                echo '</select>'; ?>

2
Sao chép mã dán không phải lúc nào cũng hữu ích. Bạn cũng nên giải thích mã một chút.
mrkernelpanic

-2

Tất cả các giải pháp được trình bày không hoạt động bình thường.
strtotime () và DateTime :: thêm hoặc DateTime :: sửa đổi đôi khi đưa ra kết quả không hợp lệ.
Ví dụ:
- 31.08.2019 + 1 tháng tặng 01.10.2019 thay vì 30.09.2019
- 29.02.2020 + 1 năm tặng 01.03.2021 thay vì 28.02.2021
(thử nghiệm trên PHP 5.5, PHP 7.3)

Dưới đây là chức năng của tôi dựa trên ý tưởng được đăng bởi Angelo để giải quyết vấn đề:

// $time - unix time or date in any format accepted by strtotime() e.g. 2020-02-29  
// $days, $months, $years - values to add
// returns new date in format 2021-02-28
function addTime($time, $days, $months, $years)
{
    // Convert unix time to date format
    if (is_numeric($time))
    $time = date('Y-m-d', $time);

    try
    {
        $date_time = new DateTime($time);
    }
    catch (Exception $e)
    {
        echo $e->getMessage();
        exit;
    }

    if ($days)
    $date_time->add(new DateInterval('P'.$days.'D'));

    // Preserve day number
    if ($months or $years)
    $old_day = $date_time->format('d');

    if ($months)
    $date_time->add(new DateInterval('P'.$months.'M'));

    if ($years)
    $date_time->add(new DateInterval('P'.$years.'Y'));

    // Patch for adding months or years    
    if ($months or $years)
    {
        $new_day = $date_time->format("d");

        // The day is changed - set the last day of the previous month
        if ($old_day != $new_day)
        $date_time->sub(new DateInterval('P'.$new_day.'D'));
    }
    // You can chage returned format here
    return $date_time->format('Y-m-d');
}

Các ví dụ sử dụng:

echo addTime('2020-02-29', 0, 0, 1); // add 1 year (result: 2021-02-28)
echo addTime('2019-08-31', 0, 1, 0); // add 1 month (result: 2019-09-30)
echo addTime('2019-03-15', 12, 2, 1); // add 12 days, 2 months, 1 year (result: 2019-09-30)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.