Timestamp or date in Rust or Motoko

I’m using the Rust CDK, but this is relevant to Motoko as well. I want to generate a timestamp or get the current date and time…how do I do this? I did a quick skim through the Motoko documentation and didn’t see anything.

1 Like

Time.now() returns the canisters’ timestamp in nanoseconds

7 Likes

NB that timestamp seems to be static within the context of a message/request. So can’t use it to do any kind of timing within one such request.

2 Likes

That is what you’re going to have to go with because of the distributed nature of the calculation. If your output depends on the timing of internal processes you lose determinism due to different memory management, processing, etc. You’d never be able to reach consensus.

3 Likes

On second thought you could split the call into two functions where the second one is gated by a certain timestep. Microseconds is going to be tough though and you minimum unit is going to need to be blocks/second.

1 Like

Echoing the comments above. The timestamp is provided by the block maker and ratified by the notary group.

1 Like

Great information everyone, thanks. Does anyone have the Rust code to get the time?

1 Like
3 Likes

Here’s a hack to update the timestamp by await-ing:

actor Timer {
  func noop(): async () {};

  public func call(): async () {
    let a = Time.now();
    await noop();
    let b = Time.now();
  }
}
5 Likes

I believe this hack should be considered harmful. Why would someone use it?
I mean, one could just plus some value to the first timestamp.

Haha this really is a hack, it introduces the latency of another async call which could be several seconds. I guess if you’re doing really long synchronous operations and you need an updated timestamp, this could be useful…

Hi. Is this local time?

System time

The canister can query the IC for the current time.

ic0.time : () -> i64

The time is given as nanoseconds since 1970-01-01. The IC guarantees that

  • the time, as observed by the canister, is monotonically increasing, even across canister upgrades.
  • within an invocation of one entry point, the time is constant.

The system times of different canisters are unrelated, and calls from one canister to another may appear to travel “backwards in time”.


NOTE

While an implementation will likely try to keep the System Time close to the real time, this is not formally part of this specification.

1 Like

Also be careful that even though the IC timestamp has nanosecond granularity, I believe it is still coarse in the sense that all messages in the same block will have the same time.

So if you request IC time in quick succession, the timestamps will have duplicates.

How can I call ic from within my canister? Can you point me to an example? Do I have to import something?

In Motoko, import Time "mo:base/Time"; then call Time.now().

In Rust, call ic_cdk::api::time().

1 Like

A few timely questions :watch: :slightly_smiling_face:

Why was the decision made to use nanosecond precision instead of ms precision for canister facing APIs?

How reliable is the timestamp I receive in a canister during a query call where the first instruction is to call Time.now()?

When I call Time.now() am I getting the exact nanosecond time of the entire IC (all subnets’ and canister’s internal times are in complete synchronicity), or at some point in the past (several nanosecond drift)?

How does the IC sync it’s system time with the outside world? Does it use a single external API or consensus from several different APIs?

1 Like

I can only speculate that this is less restrictive and allows for more use cases.

I personally didn’t appreciate it until I worked in a sector that relied on such precision.

How practical it is on the IC given the other properties of how time works is probably a different matter :slightly_smiling_face:


My previous post in this thread might answer some of this:

2 Likes