# Handling timestamps on Chromia with Rell · Working with timestamps in Rell · Learn Chromia

> A blockchain runs on many nodes, so there is no single, well-defined moment at which a piece of code executes. A call such as System.currentTimeMillis()…

Source: https://chromia.com/learn/latest-known-time/introduction/

Working with timestamps in RellLesson 1 of 1

1. [01Handling timestamps on Chromia with Rell](https://chromia.com/learn/latest-known-time/introduction/)

[Learn](https://chromia.com/learn/)[Working with timestamps in Rell](https://chromia.com/learn/latest-known-time/)

01 / 01Guide

# Handling timestamps on Chromia with Rell

A blockchain runs on many nodes, so there is no single, well-defined moment at which a piece of code executes. A call such as `System.currentTimeMillis()` would produce a different value on each node. Synchronized clocks don't fix this: the primary node runs the code first and the validating nodes follow, and network latency and hardware differences mean they never read the time at exactly the same instant.

A reliable time value must therefore come from something every node agrees on, namely the *latest known time* or *previous block time*. Every block header carries a timestamp that the validating nodes accept, which makes it a good source. You can read it by querying the [system block entity](https://docs.chromia.com/rell/language-features/systemlib/system-entities).

rell

```nolines
block @ {} (@max .timestamp);
```

While the blockchain is initializing, no blocks exist yet, so this query returns null. If you set a timestamp on an object, for example, you first have to initialize it to zero:

rell

```
object my_object {
    mutable timestamp = 0;
}
```

You then update the value yourself through an operation.

rell

```
operation set_time() {
    my_object.timestamp = block @ {} (@max .timestamp);
}
```

Inside an `operation`, you have access to a special context, `op_context`, which exposes a `last_block_time` property. You can use it to shorten the expression above. You might want to make it the default value for timestamp attributes on entities. However, when you add such an attribute to an entity that already holds data, you need the block query to assign a correct timestamp to the existing records:

rell

```
entity my_entity {
    timestamp = if (op_context.exists) op_context.last_block_time else block @ {} (@max .timestamp)!!;
}
```

The reason is that the default value is applied to all existing entities when the blockchain restarts after the update. At that point no operation is running, so `op_context` is not available (`op_context.exists` is false).

To handle every case the same way, define a function `last_known_time()`:

rell

```nolines
function last_known_time()
    = if (op_context.exists) op_context.last_block_time else block @ {} (@max .timestamp) ?: 0;
```

You can call this function safely in any context:

rell

```
object my_object {
    timestamp = last_known_time();
}

entity my_entity {
    timestamp = last_known_time();
}

operation my_operation() {
    create my_entity();
}

query get_last_known_time() = last_known_time();
```

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Course**Working with timestamps in Rell**](https://chromia.com/learn/latest-known-time/)[Course done →**Start building**](https://chromia.com/developers/#start)
