We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Convert HH:MM:SS to seconds at beforeCreate model method

Hi,

the users input of my app is "HH:MM:SS" like 01:34:10. However, I would like to convert it to seconds before saving it into my database. I can't successfully do it at the beforeCreate model. I have to do it at the controller, which isn't good.

This isn't working:

public function beforeCreate() {
    // Convert date to german date
    $date = new DateTime($this->date);
    $this->date = $date->format('Y-m-d');

    // Convert HH:MM:SS to seconds
    $duration = $this->duration;
    $this->duration = strtotime("1970-01-01 $duration UTC");
}

Converting the date to german date is working but not second conversion. What I am doing wrong?

What is inside $this->date?

Is this what you are trying to do:

public function beforeCreate() {
    // Your date in HH:MM:SS
    $time = $this->date;

    // Merge it with todays date YYYY-MM-DD HH:MM:SS
    $date = date('Y-m-d') . ' ' . $this->date;

    // Convert it to timestamp
    $this->date = strtotime($date);
}


14.4k

What is inside $this->date?

Is this what you are trying to do:

public function beforeCreate() {
   // Your date in HH:MM:SS
   $time = $this->date;

   // Merge it with todays date YYYY-MM-DD HH:MM:SS
   $date = date('Y-m-d') . ' ' . $this->date;

   // Convert it to timestamp
   $this->date = strtotime($date);
}

No, $this->date was just to show that the method is called. $this->date and $this->duration are separated from each other. I would like to convert HH:MM:SS to seconds inside beforeCreate. HH:MM:SS is inside $this->duration.

Have you tried this:

public function beforeCreate() {
    // Convert date to german date
    $date = new DateTime($this->date);
    $this->date = $date->format('Y-m-d');

    // Convert HH:MM:SS to seconds
    $duration = explode(':',$this->duration);
    $this->duration = floatval($duration[2]) * 360 + floatval($duration[1]) * 60 + $duration[0];
}

This assumes that the duration is ALWAYS HH:MM:SS, it will produce bad results for MM:SS and SS



14.4k

Have you tried this:

public function beforeCreate() {
   // Convert date to german date
   $date = new DateTime($this->date);
   $this->date = $date->format('Y-m-d');

   // Convert HH:MM:SS to seconds
   $duration = explode(':',$this->duration);
   $this->duration = floatval($duration[2]) * 360 + floatval($duration[1]) * 60 + $duration[0];
}

This assumes that the duration is ALWAYS HH:MM:SS, it will produce bad results for MM:SS and SS

Tried it without success. This is actually working fine at my controller:

strtotime("1970-01-01 $duration UTC");

But not at beforeCreate and I just don't understand why this is a difference.

edited Jun '16

But wait, you jsut want to convert HH:MM:SS without date to seconds ? Then you would need to use something like this:

public function beforeCreate()
{
$this->date = (new DateTime("1970-01-01 {$this->date}"))->getTimestamp();
}

Just what strtotime return there in beforeCreate() ? What you mean it not works in beforeCreate ? Your example should work too.



14.4k
edited Jun '16

But wait, you jsut want to convert HH:MM:SS without date to seconds ? Then you would need to use something like this:

public function beforeCreate()
{
$this->date = (new DateTime("1970-01-01 {$this->date}"))->getTimestamp();
}

Just what strtotime return there in beforeCreate() ? What you mean it not works in beforeCreate ? Your example should work too.

I'm sorry for beeing not exactly. $this->date was just to show that the beforeCreate() method is being called. It has nothing to do with the conversion from HH:MM:SS to seconds.

This is what I have to do right now:

// Controller 
$user_run->duration = strtotime("1970-01-01 $duration UTC");
$user_run->create();

This is what I want it to be:

// Model
public function beforeCreate() {
    $this->duration = strtotime("1970-01-01 $this->duration UTC");
}

Currently, I have to convert it at the controller. But for separating purposes I would like to achive it at the model.

edited Jun '16

And where is problem ? You have exception when having it in beforeCreate() ? Or what ? What exactly is not working beacause i don't see your issue. What's value of duration after creating ?

Tried it without success. This is actually working fine at my controller:

strtotime("1970-01-01 $duration UTC");

But not at beforeCreate and I just don't understand why this is a difference.

strotime will return the timestamp in unix seconds, so that line will work perfectly, as @ndabAP said. His problem is that beforeCreate only executes the first part if the code.

Is duration part of the column map?

edited Jun '16

But whay he means executes only the first part of code ? What happens after it ? It's not executed ? There is exception ? It's not saved in database ? What is value of $user_run->create() ? Are there any error messages ? What is value of duration after create ?



14.4k
edited Jun '16

But whay he means executes only the first part of code ? What happens after it ? It's not executed ? There is exception ? It's not saved in database ? What is value of $user_run->create() ? Are there any error messages ? What is value of duration after create ?

When I exectue var dump($user->duration) after save() I get this result:

duration is required
/var/www/legendary.run-phalcon/app/controllers/AddController.php:64:string '01:00:00' (length=8)

So, $this->duration is untouched. It ignored my conversion at my model $this->duration = strtotime("1970-01-01 $this->duration UTC");.



145.0k
Accepted
answer

Whan will happen if you will change beforeCreate to beforeValidationOnCreate ?



14.4k
edited Jun '16

Whan will happen if you will change beforeCreate to beforeValidationOnCreate ?

Yes, that did the trick. But isn't that a bug or do I misunderstand beforeCreate()?

First phalcon runs beforeValidationOnCreate, then there is internal check for not null values for columns, and then there is beforeCreate. You can get rid of not nulls check by:

Model::setup(
    [
        'notNullValidations' => false
    ]
);

This way it should work with beforeCreate too.