Skip to main content

Timestamps

Ormed provides automatic timestamp management for created_at and updated_at columns.

Enabling Timestamps

Add the Timestamps marker mixin to your model:

(table: 'posts')
class TimestampPost extends Model<TimestampPost> with Timestamps {
const TimestampPost({required this.id, required this.title});

(isPrimaryKey: true, autoIncrement: true)
final int id;

final String title;
}

The code generator detects this mixin and:

  • Adds virtual createdAt and updatedAt fields if not explicitly defined
  • Applies timestamp implementation to the generated tracked class
  • Automatically sets timestamps on insert/update operations

Carbon Integration

Ormed integrates with the Carbonized library to provide a fluent API for date manipulation. The createdAt and updatedAt getters return a CarbonInterface? instance.

final user = await repo.find(1);
if (user != null) {
print(user.createdAt?.diffForHumans()); // "2 hours ago"
print(user.updatedAt?.addDays(1).isFuture); // true
}

:::tip Timestamps are Immutable Ormed returns immutable Carbon instances from timestamp getters. This means you can safely chain methods like subDay() without accidentally mutating the model's state:

final yesterday = user.createdAt?.subDay(); // Safe! Returns new instance
print(user.createdAt); // Original value unchanged

See the Date and Time Handling guide for more details on mutable vs immutable Carbon behavior. :::

Flexible Setters

The createdAt and updatedAt setters accept both standard Dart DateTime objects and CarbonInterface instances.

user.updatedAt = DateTime.now();
// or
user.updatedAt = Carbon.now().subDays(1);

Timezone-Aware Timestamps

For timestamps stored in UTC, use TimestampsTZ:

(table: 'articles')
class TimestampArticleTz extends Model<TimestampArticleTz> with TimestampsTZ {
const TimestampArticleTz({required this.id, required this.title});

(isPrimaryKey: true, autoIncrement: true)
final int id;

final String title;
}

This ensures:

  • All timestamps are converted to UTC before storage
  • Timestamps remain in UTC when retrieved
  • Your application handles timezone conversion for display

Prefer UTC storage for multi-region systems; localize only at presentation boundaries.

Migration Setup

Add timestamp columns in your migration:

If you use Timestamps/TimestampsTZ, keep the schema column names aligned with your model configuration.

Custom Column Names

By default, Ormed uses created_at and updated_at. These can be customized via model configuration if needed.

Behavior

On Insert

  • created_at is set to the current timestamp
  • updated_at is set to the current timestamp

On Update

  • updated_at is automatically updated
  • created_at remains unchanged

Manual Control

You can manually set timestamps if needed:

// You can manually set timestamps using DateTime or Carbon:
// final post = $TimestampPost(
// id: 0,
// title: 'My Post',
// createdAt: DateTime(2024, 1, 1),
// updatedAt: Carbon.now().subDays(1),
// );

Disabling Automatic Updates

If you still want timestamp columns but need to control updates yourself, disable auto-updates at the model level:

(table: 'audit_logs', timestamps: false)
class AuditLog extends Model<AuditLog> with Timestamps {
const AuditLog({required this.id, required this.message});

(isPrimaryKey: true)
final int id;

final String message;
}

You can also suppress timestamp updates for a scoped block:

await Model.withoutTimestampsOn(<Type>[Post], () async {
await Posts.query().where('id', 42).update({'title': 'No touch'});
});

Without Timestamps

If you don't need automatic timestamps, simply don't include the mixin:

(table: 'logs')
class Log extends Model<Log> {
// No timestamps mixin - manual control
const Log({required this.id, required this.message, this.timestamp});

(isPrimaryKey: true)
final int id;

final String message;
final DateTime? timestamp;
}

Read This Next

Verify Timestamp Behavior

  1. Insert model and confirm both created_at + updated_at are set.
  2. Update model and confirm only updated_at changes.
  3. Validate timezone behavior (Timestamps vs TimestampsTZ) in your runtime.