codeigniter4 / codeigniter4/CodeIgniter4

Bug: Database dateFormat['datetime'] does not support millisecond or microsecond values

Open
#10,540 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
PHP
Stars
6k
Forks
2k
Avg merge
1d 11h
Merged PRs (30d)
73

Description

### PHP Version

8.4

### CodeIgniter4 Version

4.7.4

### CodeIgniter4 Installation Method

Composer (as dependency to an existing project)

### Which operating systems have you tested for this bug?

Windows

### Which server did you use?

cli-server (PHP built-in webserver)

### Environment

development

### Database

MySQL 8.4.9

### What happened?

When setting the database connection in app\Config\Database.php, I am using the following dateFormat definition to get millisecond precision in my dates:
```
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s.v',
'time' => 'H:i:s',
],
```
My model then configures the following for timestamps:
```
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
protected $createdField = 'created_at';
```
After inserting an entry the table, the `created_at` column does not include the milliseconds. For example, the column has the value **2026-09-11 10:17:35** however because the column definition in MySQL is timestamp(6) the column should have the value **2026-09-11 10:17:35.509000**.

### Steps to Reproduce

Set the datetime mask as above and the model variables as above and insert a value into your table.

### Expected Output

I expected the `created_at` column to include the milliseconds.

### Anything else?

I have resolved this problem by overriding the `setDate()` function in the BaseModel as follows.

My model class is defined as:
```
class TransactionHistoryModel extends \App\Models\BaseModel {
...
}
```
I have then created my own BaseModel with the setDate override defined as:
```
namespace App\Models;

class BaseModel extends Model {

/**
* Sets the timestamp or current timestamp if null value is passed.
*
* @param int|null $userDate An optional PHP timestamp to be converted
*
* @return int|string
*
* @throws ModelException
*/
protected function setDate(?int $userDate = null)
{
$currentDate = $userDate ? Time::createFromTimestamp($userDate) : Time::now();

return $this->timeToDate($currentDate);
}
}
```
This solution works.

Contributor guide

Open the contributing guide

Research direction

Start with the dateFormat configuration in app\Config\Database.php and trace the model's setDate() and timeToDate() entry points. Reproduce the timestamped insert on MySQL using a timestamp(6) column and the reported datetime mask. Done means created_at preserves the configured millisecond or microsecond precision.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, php
Domain
backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.