phpforeachsmartysmarty3smarty2

Smarty how to calculate days difference between two dates


How can I calculate difference between two dates and find the number of days in SMARTY template engine? I know the logic part should be done is PHP and assigned the value to SMARTY. But sometimes we land in a situation where we have to perform vice versa no matter what. I have to calculate this difference in smarty even though it defies the logic of using a template engine.

Here is my code:

function returnReferrals($type){
  global $pdo;

  $stmt = $pdo->prepare("SELECT * FROM referrals
                         LEFT JOIN members ON members.mem_id = referrals.ref_referral
                         WHERE ref_type = :type AND ref_referrer = :mem");
  $stmt-> bindValue(':type', $type);
  $stmt-> bindValue(':mem', userId());
  $stmt-> execute();

  $res = array();
  while($result = $stmt->fetch()){
    $res[] = $result;
  }
  return $res;
}

$referrals = returnReferrals($type);

$smarty->assign('referrals', $referrals);

referrals.tpl

{foreach $referrals as $refs}
  
  <!-- Here I need to calculate days difference and have logic like below -->

  {if $days > 2}Inactive{else}Active{/if}

{/foreach}

Now to get the $days I need to calculate difference between two dates where one date comes from database datetime field $refs.ref_last_click and other is the current date. I could easily do this if I could in PHP but since I have assigned the looping variable to the template to be used in the foreach loop I have to now do it in SMARTY. How can I do this?


Solution

  • Here is my smarty function (add to your smarty plugin directory):

    /* 
    * Smarty plugin 
    * ------------------------------------------------------------- 
    * Type: function 
    * Name: date_diff 
    * Purpose: factor difference between two dates in days, weeks, or years
    * Input: d1 = "mm/dd/yyyy" or "yyyy/mm/dd" or "yyyy-mm-dd"
    *        d2 = "mm/dd/yyyy" or "yyyy/mm/dd" or "yyyy-mm-dd" or $smarty.now
    *        assign = name of variable to assign difference to 
    *        interval = "days" (default), "weeks", "years" 
    * Examples: {date_diff d1="2020-01-20"}
    * Examples: {date_diff d1="2020-01-20" d2=2020-02-10 interval="weeks"}
    * Examples: {date_diff d1="2020-01-20" d2=2020-02-10 assign="variable_diff"} result: {$variable_diff}
    * -------------------------------------------------------------
    */
    function smarty_function_date_diff($params, &$smarty)
    {
        $d1          = isset($params['d1']) ? $params['d1'] : date('Y-m-d');
        $d2          = isset($params['d2']) ? $params['d2'] : date('Y-m-d');
        $assign_name = isset($params['assign']) ? $params['assign'] : '';
    
        $date1 = strtotime($d1);
        $date2 = strtotime($d2);
    
        // use current for empty string
        if (! $date1) {
           $date1 = date('Y-m-d');
        }
        if (! $date2) {
           $date2 = date('Y-m-d');
        }
    
        $interval = isset($params['interval']) ? $params['interval'] : 'days';
    
        // diff in days
        $diff = ($date2 - $date1) / 60 / 60 / 24;
    
        if ($interval === "weeks") {
            $diff /= 7;
        }
        elseif ($interval === "years") {
            $diff /= 365.25;
        }
    
        $diff = floor($diff);
    
        if ($assign_name) {
            $smarty->assign($assign_name, $diff);
        }
        else {
            return $diff;
        }
    
    }
    

    then your code:

    {foreach $referrals as $refs}
    
        {date_diff d1=$refs.ref_last_click assign='days'}
        {* 'd2' will appear as default current time *}
    
        {if $days > 2}Inactive{else}Active{/if}
    
    {/foreach}