Date calculations in logic hooks

I’m trying to figure out how to work with date operations using Sugar functions already provided. I have a date field and a days field. I’d like to set another date based on the days field eg. renewal_date = end_date - renewal_days. Would appreciate it if someone could help. It can be done using PHP functions but there are easier ways to do it using the time/date classes included with Sugar. Thanks!

Hi,

The TimeDate class within SuiteCRM makes it simpler to work with dates, particularly from fields which may be in the DB format or the users format. An example of what you want to do would be something like:


function dateSub($dateStr, $days){
    global $timedate;
    //First get a date object to work with
    $date = $timedate->fromDb($dateStr);//May be fromUser fromDBDate e.t.c. depending on the format
    //Note - should check that $date is non empty 
    //Subtract days
    $date->sub(new DateInterval('P'.$days.'D'));
    return $timedate->asDb($date);//also could use asUser e.t.c.
}

Hope this helps,
Jim

2 Likes

Thank you, Jim! I spent quite a bit of time on this yesterday. I have a few questions about your code:

  • What is the global $timedate object and what does it contain?
  • What format is the date saved in the SuiteCRM DB?
  • I used the PHP class DateTime to use DateInterval because I thought DateInterval worked on DateTime objects
  • I tried manipulating the renewal_reminder_date but it doesn’t really work using a Workflow. Wanted to set it to 7 days before the renewal_date. Maybe it is because I’m using a logic hook for the renewal_date and workflow for the renewal_reminder_date or because one is a Date object and the other is a Datetime?

Anyways, here’s my code. Not elegant like yours as my coding skills are rusty but they’re coming back:

function set_renewal_date($bean, $events, $arguments)
{
// Set renewal date to end date - renewal days. This is the date tenant has to renew or terminate lease
//$GLOBALS[‘log’]->fatal($bean->renewal_date_c);

            // Set interval format using renewal_days_c eg. P45D
            $days_interval_format = 'P' . $bean->renewal_days_c . 'D';
            $days_interval = new DateInterval($days_interval_format);
            $end_date = $bean->end_date;
            $renewal_reminder_date = $bean->renewal_reminder_date;
            $end_date_datetime = new DateTime($end_date);
            $end_date_datetime->sub($days_interval); // Subtract interval days from end date

            $bean->renewal_date_c = $end_date_datetime->format('Y-m-d'); // Update renewal date in DB
            $GLOBALS['log']->fatal("End date: $end_date");
            $GLOBALS['log']->fatal($days_interval_format);
            $GLOBALS['log']->fatal("Renewal date: " .  $end_date_datetime->format('Y-m-d'));
            $GLOBALS['log']->fatal("Renewal reminder date: " .  $renewal_reminder_date);
    }

Hi,

It’s an instance of the TimeDate class which extends the PHP DateTime object. It supplies methods for dealing with dates in SuiteCRM.

This depends on your database engine. It’s usually Y-m-d H:i:s (i.e. 2015-01-22 22:12:06).

Using the PHP DateTime and DateInterval classes should still work.

Note that the following may not work depending on the users date formats:


$end_date_datetime = new DateTime($end_date);

If you are using the DateTime class you’ll probably want to fetch the users format and create the DateTime object using DateTime::createFromFormat. The TimeDate::fromUser() method takes care of this however.

Hope this helps,
Jim