Repeat record in database on same day of each month

Asked

Viewed 113 times

1

I need to schedule bills to pay and that every payment would be on a day of each month.

I’m doing this, but it’s not working:

$hoje = new DateTime($data_hoje);
                        $semana = new DateInterval('P'.$_POST['repetir'].'D');
                        $repeticoes = $_POST['repita'];

 for ($i_receber = 0 ; $i_receber < 30 - 1 ; $i_receber++) {

                            $hoje = $hoje->add($semana);

    Inserido com sucesso! Início2 <b><? echo $hoje->format('Y-m-d')

    }

For example if put to repeat every day 20 of each month, returns so

Inserido com sucesso! Início: 2019-05-20
Inserido com sucesso! Início: 2019-06-19
Inserido com sucesso! Início: 2019-07-19

When it should be

Inserido com sucesso! Início: 2019-05-20
Inserido com sucesso! Início: 2019-06-20
Inserido com sucesso! Início: 2019-07-20
  • 1

    I did not see the difference of the function result with the expected result. You can correct?

  • Enter the question also how the $_POST data comes

  • @Victorcarnavalhas been corrected

  • @Andrélins comes like this $week = new Dateinterval('P'. 30.’D');

1 answer

2


If you want to add up 1 month, you don’t need to make a loop adding up days, you can directly add up a DateInterval corresponding to one month:

$d = new DateTime();
$d->setDate(2019, 5, 20); // 20 de maio de 2019
echo $d->format('d/m/Y'); // 20/05/2019
$d->add(new DateInterval('P1M')); // soma 1 mês => 20 de junho de 2019
echo $d->format('d/m/Y'); // 20/06/2019

P1M corresponds to a duration of 1 month, according to the format defined by ISO 8601 standard.

In your code you used 'P'.$_POST['repetir'].'D', whose result will be a duration in days (P30D, for example, which corresponds to a duration of 30 days). Regardless of the value used, the result will not always be precise, because months have varying sizes: they may have 28, 29, 30 or 31 days, and adding a fixed amount of days will not always result on the same day of the following month. So it’s best to use a duration in months (such as P1M for 1 month).

If you want to repeat this for several months, just put in a loop:

$quantidade_meses = 3;
for ($i = 0 ; $i < $quantidade_meses ; $i++) {
    $d->add(new DateInterval('P1M'));
    echo $d->format('d/m/Y');
}

The only care to take is when the date is in the last days of the month. Ex:

$d = new DateTime();
// muda para 31 de janeiro de 2019
$d->setDate(2019, 1, 31);
// somar 1 mês = 3 de março de 2019
$d->add(new DateInterval("P1M"));

When adding 1 month to 31 January 2019, the result should be 31 February. But February doesn’t have 31 days, so PHP adjusts to 3 March.

I don’t know how it makes sense to add 1 month to a date in January and the result is in March (two months later). In such cases, many languages and Apis choose to adjust the result to February 28, for example. If you want the same adjustment in PHP, you’ll have to do it manually.


Another alternative is to use the method modify:

$d->modify('+1 month');

But it has the same problem already cited for dates like 31 January 2019 (results on 3 March).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.