Solidity: Работа с датой и временем

Работа с датой и временем в каждом языке программирования всегда имеет свою специфику. Разберем некоторые моменты и приведем примеры для языка Solidity, который используется для создания децентрализованных приложений на базе блокчейна Ethereum.

Переменные с типом Дата

Даты в Solidity хранятся в переменных типа uint. Глобальная переменная now будет возвращать дату и время в формате unix последнего блока (количество секунд, прошедших с 1 января 1970 года).

uint lastUpdated;

// Установить в переменную `lastUpdated` текущее время
function updateTimestamp() public {
  lastUpdated = now;
}

Время Unix традиционно хранится в виде 32-битного числа. Это приведет к проблеме «2038 год», когда 32-битные временные метки unix будут переполнены, потому что они не смогут сохранить это большое число. Чтобы избежать этой проблемы, мы можем вместо этого использовать 64-битный номер, хотя это потребует более высокой платы за газ для наших контрактов.

Преобразование JavaScript даты в дату Solidity

Если мы хотим сохранить дату в смарт-контракте со значением, переданным из веб-приложения, то нам нужно преобразовать дату JavaScript в формат unix, которую мы будем хранить в смарт-контракте как переменную uint.

// Получаем объект JS с текущей датой
const today = new Date();

// ⚠️ JS возвращает время в миллисекундах
const mseconds = today.getTime();

// Разделим на 1000, чтобы получить время в секундах
const seconds = Math.floor(mseconds / 1000);

// Запишем все эти действия в одну строку
const dateInSecs = Math.floor(new Date().getTime() / 1000);

Получив количество секунд, мы можем передать это значение в наш смарт-контракт, используя Ethers.js или Web3.js.

Единицы даты и времени

Solidity предоставляет некоторые встроенные единицы измерения времени: seconds, minutes, hours, days, weeks и years. Эти единицы измерения будут преобразованы в секунды за указанный промежуток времени. Например, 1 minutes — это 60, 1 hours — это 3600 (60 секунд х 60 минут) и т. д.

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

Эти единицы очень полезны для работы с датами и временем в наших смарт-контрактах, поскольку они позволяют нам использовать математические операторы, такие как + и .

Как вычислить количество дней между двумя датами?

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

Как сравнить даты в Solidity?

Можно использовать операторы < или > для сравнения двух дат. Это позволяет нам легко сравнивать две даты или проверять, была ли дата раньше или позже другой:

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;
}

Как проверить истекло ли время?

Код ниже показывает, как проверить, прошло ли 10 минут с момента развертывания контракта:

pragma solidity >=0.8.1

contract MyContract {
  uint deployDate;

  constructor(){
    deployDate = now;
  }

  // Будет возвращено `true` если прошло 10 минут с момента деплоя смарт-контракта
  function tenMinutesHavePassed() public view returns (bool) {
    return (now >= (deployDate + 10 minutes));
  }
}

Как увеличить или уменьшить количество дней от текущей даты?

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;

 

 

Рейтинг
( 12 оценок, среднее 2.75 из 5 )
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: