0

How do you convert a DATETIME time string from a user's time zone to GMT in CakePHP?

I'm aware of CakeTime and TimeHelper: They seem to handle converting time strings from server time to a user's local time very well, but they don't seem to cover dates that users submit. In one of my models, I've got a user-submitted time field that accepts input in DATETIME format, user's local time: 2014-04-07 04:48:05. I need to convert this to UTC after the form is submitted.

This is my controller method for my view. I'm trying to use CakeTime::format to convert the sighted field to UTC, but it moves the time the right number of hours in the wrong direction: Instead of converting 15:00EST to 19:00GMT, it converts it to 11:00 on save (!?).

How do I convert it from local time to GMT using proper PHP time zones?

public function add() {
    App::uses('CakeTime', 'Utility');
    if ($this->request->is('post')) {
        $this->Post->create();
    // Change the submitted time to UTC before the post saves
        $this->request->data('Post.sighted', CakeTime::format($this->request->data['Post']['sighted'], '%Y-%m-%d %H:%M:%S', 'UTC'));
        if ($this->Post->save($this->request->data)) {
            $this->redirect(array('action' => 'view', $this->Post->id));
        } else {
            $this->Session->setFlash(__('The post could not be saved. Please, try again.'), 'flash/error');
        }
    }
    // Get local time and set the field before the view loads
    $this->request->data['Post']['sighted'] = CakeTime::format(date('Y-m-d H:i:s'), '%Y-%m-%d %H:%M:%S', 'N/A', 'America/New_York');
}
caitlin
  • 2,769
  • 4
  • 29
  • 65

1 Answers1

1

If you would be aware of MVC and OOP basics it would be logical that you can't use a helper inside the model layer. The fatal error tells you simply that you try to access an object that does not exist because there is no such object instantiated.

Checking the API helps as well: http://api.cakephp.org/2.4/source-class-CakeTime.html#1006

It is also mentioned in the official documentation: http://book.cakephp.org/2.0/en/core-utility-libraries/time.html#CakeTime::format

The forth example in the doc block shows how to use the timezone.

CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York');

-

/**
 * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
 * This function also accepts a time string and a format string as first and second parameters.
 * In that case this function behaves as a wrapper for TimeHelper::i18nFormat()
 *
 * ## Examples
 *
 * Create localized & formatted time:
 *
 * {{{
 *   CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012
 *   CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale
 *   CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed
 *   CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone
 * }}}
 *
 * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
 * @param integer|string|DateTime $format date format string (or UNIX timestamp, strtotime() valid string or DateTime object)
 * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
 * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 * @return string Formatted date string
 * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::format
 * @see CakeTime::i18nFormat()
 */
floriank
  • 25,546
  • 9
  • 42
  • 66
  • Yes, but CakeTime assumes the original time strings it's provided are in GMT. – caitlin Apr 07 '14 at 08:37
  • CakeTime was the way to go: It wasn't explicitly mentioned in the docs but you can specify the timezone of the starting date: `$this->request->data('Post.sighted', CakeTime::format($this->request->data['Post']['sighted'] . CakeSession::read("Auth.User.time_zone"), '%Y-%m-%d %H:%M:%S', 'N/A', 'UTC'));` – caitlin Apr 07 '14 at 22:04