How to calculate date

Hello,

i need help on calculating or displaying remaining days to a specified date. Here is what Iam working on. A list of projects which will have a start date and an end date. I want to show the status of each project, so if a project is currently running it shows “green” + remaining days. If a project is done it will show “blue” + end date. And if a project is planned it should be displaying “yellow” + remaining days. Iam newbie to php, but know some basics.

My template looks like this:


 <?php foreach (page('home')->children() as $row): ?>

    <tr onclick="document.location = '<?= $row->url() ?>';">
      <td><img class="rounded-circle " src="<?= $row->image("thumb.jpg")->url() ?>"><span class="proj_name"><?= $row->title() ?></span></td>
      <td><?= $row->industry() ?></td>
      <td><?= $row->country() ?></td>
    <td><span class="live"><?= $row->date() ?></span><span class="space">•</span><span class="icon2"></span><span class="small_text">22 days remaining</span></td>      
    </tr>
    
    <?php endforeach ?>

22

Have a look at the DateTime class: https://www.php.net/manual/de/class.datetime.php

It allows you do calculations like the difference in days between given dates etc.

The rest is just a couple of if statements.

Example: Calculate difference in days between today and enddate:

$today = new Datetime(date('Y-m-d'));
$endDate = new Datetime($page->endDate()->toDate('Y-m-d'));
$diff = $endDate->diff($today);
dump($diff->days);
2 Likes

Thank you, but my problem is more how to integrate a calculation? Do i need the snippets or controllers for it, lets say i want to use this code:

```
$date1 = "2007-03-24";
$date2 = "2009-06-26";

$diff = abs(strtotime($date2) - strtotime($date1));

$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));

printf("%d years, %d months, %d days\n", $years, $months, $days);
```

I’d probably create functions in a plugin or the controller or a page model or field method that return my numbers, then call them in the snippet or template.

Your code looks a bit complicated, the Datetime class makes this a lot easier, as it already delivers your years, month, days etc.

Thank you for this :slight_smile: any difference when using time? So do i need to convert it? So in my panel i have a datepicker and a timepicker. I would get rid of it, if it makes it easier.

No, what I suggested has nothing to do with the Panel. If you have different fields for date and time and you want to go down to the hour or second level, then you have to combine the data of these fields (although that can also be done in a page model). However, I’d use the Datetime field instead of two different fields.

iam still confused if i should use the snippets, plugins or controller? I want my template clean. So my imagination is a kind of like function in the template:

returnDate(EndDate);

that gives the remaining time and a second function that give me a class name (string) in return.

That’s what I already said above, do your calculations in a function or a page model, then call these functions/methods in your templates/snippets.

// some plugin index.php

function getDiff($enddate) {
  // logic here
  $diff = 'blabla';
  return $diff;
}

In template:

<?= getDiff($endate) ?>

You can also do this as a page model instead…

Thank you so far, as you said it makes more sense put the function on the page. So here is my template but i get two results and line breaks. Any idea what i did wrong?

<?php snippet('header') ?>

<?php
    
function getDiff($remain) {
    
$today = new Datetime(date('Y-m-d'));
$endDate = new Datetime($remain->toDate('Y-m-d'));
$diff = $endDate->diff($today); 
    
return dump($diff->days);
}

?>

<main>

    <div class="main-cont">
    
<table class="table" id="mydatatable">
  <thead>
    <tr>
      
      <th scope="col">Project</th>
      <th scope="col">Industry</th>
      <th scope="col">Country</th>
        <th scope="col">Sale Status</th>
    </tr>
  </thead>
  <tbody>
    
    <?php foreach (page('home')->children() as $row): ?>

    <tr onclick="document.location = '<?= $row->url() ?>';">
      <td><img class="rounded-circle " src="<?= $row->image("thumb.jpg")->url() ?>"><span class="proj_name"><?= $row->title() ?></span></td>
      <td><?= $row->industry() ?></td>
      <td><?= $row->country() ?></td>
    <td><span class="live"><?= $row->date() ?></span><span class="space">•</span><span class="icon2"></span>
    <span class="small_text"><?= getDiff($row->date()) ?> days remaining</span></td>      
    </tr>
    
    <?php endforeach ?>
      
  </tbody>
</table>

42

NO, I didn’t say to put the function in the template, I recommended to put it in a plugin or page model.

Also, you shouldn’t return the dump()but

function getDiff($remain) {
    
$today = new Datetime(date('Y-m-d'));
$endDate = new Datetime($remain->toDate('Y-m-d'));
$diff = $endDate->diff($today); 
    
return $diff->days;
}

Only ever use dump() for debugging, to check what your stuff contains.

1 Like

Thank you learned a lot :slight_smile: Looks good so far, just the only strange thing is that i get a positiv number even when the date is in the past. Any way to check this? Appreciate your time.

So would be great to check if a project is done and than hide this remaining time info.

Didn’t you want to check if it is done anyway and then make it blue or whatever?

As I already said above, a couple of if statements is needed to cover your different use cases.

if ($page->enddate()->toDate('Y-m-d') > date('Y-m-d'))
  echo "This project is in the past";
}

if ($page->startDate()->toDate('Y-m-d') < date('Y-m-d'))
  echo "This project is in the future";
}

if ($page->startDate()->toDate('Y-m-d') > date('Y-m-d') && $page->endDate()->toDate('Y-m-d') <= date('Y-m-d'))
  echo "This project is current";
}

for your different use cases.

Yes this looks perfect for what i am trying to build. Thanks again.

i always get 0 as a result:

function getDiff($remain) {

$num;    
    
$today = new Datetime(date('Y-m-d'));
$endDate = new Datetime($remain->toDate('Y-m-d'));
 
if ($remain->toDate('Y-m-d') > $today) {
  $diff = $endDate->diff($today); 
   $num = $diff->days;
    
} else {
  $num = 0;  
}  
   
return $num;
    
}

Just saw i used $remain instead of $endDate. But now it works :slight_smile: