Back to homepage

Solidity fundamentals: working with dates and time

Published

Dealing with dates and time is always tricky, and in Solidity there is no difference. Although there are some keywords that help us like now and units like days or hours there are a few things we have to keep in mind.

Date type variables

Dates in Solidity are stored in uint typed variables. The global variable now will return the current unix timestamp of the latest block (the number of seconds that have passed since January 1st 1970).

uint lastUpdated;

// Set `lastUpdated` to `now`
function updateTimestamp() public {
  lastUpdated = now;
}

Unix time is traditionally stored in a 32-bit number. This will lead to the "Year 2038" problem, when 32-bit unix timestamps will overflow because they'll not be able to store that high number. To avoid this issue, we can choose to use 64-bit number instead athough that will require a highr gas fee for our contracts 🤔

Solidity date from JavaScript date

If we want to save a date in a smart contract with a value passed from a web application here is how to do it. We need to transform a JavaScript date to unix timestamp (the number of seconds since 1970) as that's what we'll store in the smart contract as an uint variable.

// JS date object with current date
const today = new Date();

// ⚠️ JS returns the value in miliseconds
const mseconds = today.getTime();

// divided to get the just seconds
const seconds = Math.floor(mseconds / 1000);

// single liner
const dateInSecs = Math.floor(new Date().getTime() / 1000);

Once we have the number of seconds, we can pass that value to our smart contract using Ethers.js or Web3.js.

Date and time units

Solidity provides some native units for dealing with time. We can use the following units: seconds, minutes, hours, days, weeks and years. These units will convert to a uint of the number of seconds in that specific length of time. For example, 1 minutes is 60, 1 hours is 3600 (60 seconds x 60 minutes), etc.

uint a = 3 hours; //  10800 or 3*60*60
uint b = 5 minutes // 300 or 5*60
uint d = 2 weeks // 1209600 or 2*7*24*60*60

These units are very useful to work with dates and time in our smart contracts as they allow us to use math operators like + and -.

Find below some examples of basic operations with dates and time:

Calculate days between two dates

As dates as stored in seconds since Jan 1st 1970, to calculate the number of days between two given dates, we'll just have to rest them and divide it by 60 (to get the minutes), 60 (to get the hours) and 24 (to get the days). Find an example below:

uint startDate = 1638352800; // 2012-12-01 10:00:00
uint endDate = 1638871200; // 2012-12-07 10:00:00

uint daysDiff = (endDate - startDate) / 60 / 60 / 24; // 6 days

Compare dates in solidity

We can use the < or > operators to compare two dates. These allow us to easlily compare two dates or check if a date was before or after another:

uint date_1 = 1638352800; // 2012-12-01 10:00:00
uint date_2 = 1638871200; // 2012-12-07 10:00:00

function isBefore(uint _date1, uint _date2) returns (boolean){

  if(date_1 < date_2) return true;
  return false;
}

Check if time has passed

The code below shows how to check if 10 minutes have passed since the contract was deployed:

pragma solidity >=0.8.1

contract MyContract {
  uint deployDate;

  constructor(){
    deployDate = now;
  }
  // Will return `true` if 10 minutes have passed since `the contract was deployed
  function tenMinutesHavePassed() public view returns (bool) {
    return (now >= (deployDate + 10 minutes));
  }
}

Add and rest days

We can use the math operators + and - with any time unit to calculate specific dates:

uint date = 1638352800; // 2012-12-01 10:00:00

uint later = date + 1 days;

uint nextYear = date + 1 years;

uint before = date - 3 days;

uint prevWeek = date - 1 weeks;

TAGS

If you enjoyed this article consider sharing it on social media or buying me a coffee ✌️

Buy Me A Coffee