0

Can you suggest me the best solution to use if I want to generate multiple expiration dates in PHP, please? I have something like this:

Name   |  activation_date  |  months
--------------------------------------
Record1    04/05/2016           3
Record2    01/01/2016           6
Record3    12/12/2015           12

For record1, I use the following function,

$expriration_date = date('Y-m-d', strtotime("+{$row['months']} months", strtotime($expriration_date)));

To generate the expiration date starting from the "activation_date" and then I save it into my SQL Database.

The problem is that I would like to generate multiple and periodic expiration dates.

For example, for record1, the expiration dates should be: 04/08/2016, 04/11/2016, 04/02/2016 and so on for 5 years and I would like to do the same for all the records. In five years, Record1 should have 20 expiration dates, Record2 should have 10 expiration dates and so on..

EDIT

Interval times can be 3, 6, 12, 24, 36, 48 and 50 months and I would like to generate periodic expiration dates for 5 years.

How can I do this in PHP?
Moreover, is there a way to notify the most recent expiration dates to the user, then?
I've read about cron-job: this is the only solution?

Thank you for all your support!

Tirth Patel
  • 5,443
  • 3
  • 27
  • 39
Marcus Barnet
  • 2,083
  • 6
  • 28
  • 36

1 Answers1

1

You can use simple for loop

 for ($m = $months; $m <=60 ; $m += $months){
   //add $m to activation_date
   $expriration_date = DateTime::createFromFormat('Y-m-d', $activation_date);
   $expriration_date->add(new DateInterval('P'.$m.'M'));
   //do something with $expriration_date 
 }

You can do this by query, (but you don't post what db engine you use).
This query works on most popular db engines:

WITH
  intervals AS 
   ( SELECT 1 AS n, 3 AS m
     UNION ALL SELECT 2 AS n, 3 AS m
     UNION ALL SELECT 3 AS n, 3 AS m
     UNION ALL SELECT 4 AS n, 3 AS m
     UNION ALL SELECT 5 AS n, 3 AS m
     UNION ALL SELECT 6 AS n, 3 AS m
     UNION ALL SELECT 7 AS n, 3 AS m
     UNION ALL SELECT 8 AS n, 3 AS m
     UNION ALL SELECT 9 AS n, 3 AS m
     UNION ALL SELECT 10 AS n, 3 AS m
     UNION ALL SELECT 11 AS n, 3 AS m
     UNION ALL SELECT 12 AS n, 3 AS m
     UNION ALL SELECT 13 AS n, 3 AS m
     UNION ALL SELECT 14 AS n, 3 AS m
     UNION ALL SELECT 15 AS n, 3 AS m
     UNION ALL SELECT 16 AS n, 3 AS m
     UNION ALL SELECT 17 AS n, 3 AS m
     UNION ALL SELECT 18 AS n, 3 AS m
     UNION ALL SELECT 19 AS n, 3 AS m
     UNION ALL SELECT 20 AS n, 3 AS m
     UNION ALL SELECT 1 AS n, 6 AS m
     UNION ALL SELECT 2 AS n, 6 AS m
     UNION ALL SELECT 3 AS n, 6 AS m
     UNION ALL SELECT 4 AS n, 6 AS m
     UNION ALL SELECT 5 AS n, 6 AS m
     UNION ALL SELECT 6 AS n, 6 AS m
     UNION ALL SELECT 7 AS n, 6 AS m
     UNION ALL SELECT 8 AS n, 6 AS m
     UNION ALL SELECT 9 AS n, 6 AS m
     UNION ALL SELECT 10 AS n, 6 AS m
     UNION ALL SELECT 1 AS n, 12 AS m
     UNION ALL SELECT 2 AS n, 12 AS m
     UNION ALL SELECT 3 AS n, 12 AS m
     UNION ALL SELECT 4 AS n, 12 AS m
     UNION ALL SELECT 5 AS n, 12 AS m)
SELECT name, your_db_func_to_add_month(activation_date, n * m) AS expiration_dates
FROM something 
INNER JOIN intervals ON months = m
WHERE activation_date BETWEEN your_db_func_to_add_month(:testdate, -60) AND :testdate

the :testdate is parameter binded to query,
your_db_func_to_add_month is for example in mysql:

DATE_ADD(:testdate, INTERVAL 60 MONTH)

Edit:
if you define table intervals with data above, then you need only select. For MySQL this query looks like:

SELECT name, DATE_ADD(activation_date, INTERVAL n * m MONTH) (activation_date, n * m) AS expiration_dates
FROM something 
INNER JOIN intervals ON months = m
WHERE activation_date BETWEEN DATE_ADD(:testdate, - INTERVAL 60 MONTH) AND :testdate
Adam Silenko
  • 3,025
  • 1
  • 14
  • 30
  • I'm sorry for my delay! Thank you for your support! my database version is MySQL: 4.1.25-standard-log. Do you think the for loop is better than the SQL solution? Interval times can be 3, 6, 12, 24, 36, 48 and 50 months. – Marcus Barnet Apr 06 '16 at 23:18
  • It depends of result what you need. If you need filter this dates, then probably query is better (you can define table with intervals), but if you need all of this dates, then probably loop will be faster solution. – Adam Silenko Apr 07 '16 at 15:38
  • it can be helpful for your task: http://stackoverflow.com/questions/3368307/how-to-send-emails-via-cron-job-usng-php-mysql – Adam Silenko Apr 07 '16 at 15:48
  • 1
    I was studying your loop cycle: I think it creates too much intervals which are not correct, i.e. if months ==3, I should have 4 expiration_dates within one year and 20 dates in 5 years but the loop seems to generate more than 20 expiration dates, is it correct? – Marcus Barnet Apr 07 '16 at 16:16
  • 1
    typo, it should be `for ($m = $months; $m <=60 ; $m += $months)` because 0 will give activation_date as first expiration_date... – Adam Silenko Apr 07 '16 at 17:16
  • Thank you for your support. I'm trying to use your solution, but it gives me some problems. It says: "Catchable fatal error: Object of class DateTime could not be converted to string" if I try to do this: $scadenza_contratto = $year."-".$month."-".$day; for ($m = $scadenze; $m <=60 ; $m += $scadenze){ $expriration_date = DateTime::createFromFormat('Y-m-d', $scadenza_contratto); $expriration_date->add(new DateInterval('P'.$m.'M')); echo "Expire: ".$expriration_date. "
    "; }
    – Marcus Barnet Apr 09 '16 at 11:09
  • use [DateTime::format](http://php.net/manual/en/datetime.format.php) to return string from DateTime object – Adam Silenko Apr 09 '16 at 11:16
  • for example: `echo $expriration_date->format('Y-m-d');` – Adam Silenko Apr 09 '16 at 11:27
  • Thank you, it works! But, if I want to use this value in a SQL query, should I use the format $expriration_date->format('Y-m-d') also when I have to save this value into my database? Because, if I do: mysql_query("INSERT INTO scadenze (nome_azienda,nome_voce,contratto_id,nome_area,scadenza,created_date) VALUES ('$nome_azienda','$nome_voce','$contratti_id','$nome_area','$expriration_date->format('Y-m-d')','$time')"); it doesn't work unfortunately. – Marcus Barnet Apr 09 '16 at 12:55
  • please use ` to mark begin and end of code. Thanks to that comments are much more legible. – Adam Silenko Apr 09 '16 at 13:04
  • `mysql_query("INSERT INTO scadenze (nome_azienda,nome_voce,contratto_id,nome_area,scadenza,created_date) VALUES ('$nome_azienda','$nome_voce','$contratti_id','$nome_area','$expriration_date->format('Y-m-d')','$time')");` Sorry, I didn't know about that tag, now the code is more readable! :) Thanks for the tip! :) – Marcus Barnet Apr 09 '16 at 13:05
  • I think I solved it by using the format 'Y-m-d H:i:s'. It seems to work now! Thank you, Adam! – Marcus Barnet Apr 09 '16 at 13:09
  • 1
    you should use parametrized query, bind parms then execute. – Adam Silenko Apr 09 '16 at 13:29
  • Adam, I had to open a new question since I wasn't able to solve my problem :( – Marcus Barnet Apr 09 '16 at 15:46