3

I have a question regarding populating models, in that I have a DateTime field in my model that I'm pulling / populating from the database. The DateTime value does not include the timezone it was set to when it was stored, its stored in UTC.

I have the original timezone value (Not the same as the CRAFT timezone but the users timezone that actually created the entry) stored in the model attributes as well.

Is there a way I can extend the model so that when the data is populated I can force the correct timezone on the DateTime fields?

I'm pretty sure that Craft is going to convert them to the timezone craft is set to when it pulls it into the model, but I dont want that in this case. I want it set to the TZ stored in the "timeZone" column/attribute...

Example:

Craft Timezone is America/Chicago

The user's timezone is America/New_York

The user selects a date and time and the controller creates the DateTime object with the user's selection, specifying the timezone America/New_Yrok, then tells the model to save, so it stores it in the database.

The Database DateTime value is now stored in UTC.

When I fetch this data and populate a model with it and reference the DateTime object, its going to be in Amercia/Chicago right? since that's what the craft system is set to, right?

So what is the best way to set up the model so it automatically knows to use $this->getAttribute('timeZone') as the timezone for that field rather than the Craft system setting?

EDIT:

This is what I ended up doing that appears to work. I added this to my model:

public static function populateModel($values) {
    $model = PARENT::populateModel($values);

    /** @var $startTime DateTime */
    $startTime = $model->getAttribute('startTime');
    if($startTime) {
        $startTime->setTimezone($model->timeZone);
        $model->setAttribute('startTime', $startTime);
    }
    /** @var $endTime DateTime|null */
    $endTime = $model->getAttribute('endTime');
    if($endTime) {
        $endTime->setTimezone($model->timeZone);
        $model->setAttribute('endTime', $endTime);
    }

    return $model;
}
3

100% untested, but something like this should work:

  1. Have your model override BaseModel's populateModel.

  2. Find the DateTime field you're interested in and get its value.

  3. Create a new DateTime object and pass in the value from the timeZone attribute.

  4. Set the new DateTime object back on the original DateTime field.

  5. Call parent::populateModel($values).

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.