Gas-Efficient Solidity DateTime Library
This is experimental software and is provided on an "as is" and "as available" basis.
We do not give any warranties and will not be liable for any loss incurred through any use of this codebase.
To install with Foundry:
forge install Atarpara/DateTimeLib
To install with Hardhat or Truffle:
npm install
All dates, times and Unix timestamps are UTC.
Unit | Range | Notes |
---|---|---|
timestamp | 0..0x1e18549868c76ff | Unix timestamp. |
epochDay | 0..0x16d3e098039 | Days since 1970-01-01. |
year | 1970..0xffffffff | Gregorian calendar year. |
month | 1..12 | Gregorian calendar month. |
day | 1..31 | Gregorian calendar day of month. |
weekday | 1..7 | The day of the week (1-indexed). |
All functions operate on the uint256
timestamp data type.
Calculate the number of days days
from 1970/01/01 to year
/month
/day
.
function dateToEpochDay(uint256 year, uint256 month, uint256 day) internal pure returns (uint256 epochDay)
NOTE This function does not validate the year
/month
/day
input. Use isSupportedDate(..)
to validate the input if necessary.
Example:
if(DateTimeLib.isSupportedDate(1970,2,1))
uint256 day = DateTimeLib.dateToEpochDay(1970,2,1) // returns 31 day
if(DateTimeLib.isSupportedDate(1971,1,1))
uint256 day = DateTimeLib.dateToEpochDay(1971,1,1) // returns 365 day
Calculate year
/month
/day
from the number of days days
since 1970/01/01 .
function epochDayToDate(uint256 epochDay) internal pure returns (uint256 year, uint256 month, uint256 day)
NOTE This function does not validate the epochDay
input. Use isSupportedEpochDay(..)
to validate the input if necessary.
Example:
if(DateTimeLib.isSupportedEpochDay(0))
(uint256 year, uint256 month, uint256 day) = DateTimeLib.dateToEpochDay(0) // 1970-01-01
if(DateTimeLib.isSupportedEpochDay(224))
(uint256 year, uint256 month, uint256 day) = DateTimeLib.dateToEpochDay(224) // 1970-08-13
Calculate the timestamp
from year
/month
/day
.
function dateToTimestamp(uint256 year, uint256 month, uint256 day) internal pure returns (uint256 result)
NOTE This function does not validate the year
/month
/day
input. Use isSupportedDate(...)
to validate the input if necessary.
Example:
if(DateTimeLib.isSupportedDate(1970,2,1))
uint256 timestamp = DateTimeLib.dateToTimestamp(1970,2,1) // returns 2658600
if(DateTimeLib.isSupportedDate(2022,11,10))
uint256 timestamp = DateTimeLib.dateToTimestamp(2022,11,10) // returns 1668018600
Calculate year
/month
/day
from timestamp
.
function timestampToDate(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day)
NOTE This function does not validate the timestamp
input. Use isSupportedTimestamp(...)
to validate the input if necessary.
Example:
if(DateTimeLib.isSupportedTimestamp(2658650))
(uint256 year, uint256 month, uint256 day) = DateTimeLib.timestampToDate(2658600) // returns 1970-02-01
if(DateTimeLib.isSupportedTimestamp(1668018900))
(uint256 year, uint256 month, uint256 day) = DateTimeLib.timestampToDate(1668018900) // returns 2022-11-10
Calculate timestamp
from year
/month
/day
/hour
/minute
/second
.
function dateTimeToTimestamp(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) internal pure returns (uint256 result)
NOTE This function does not validate the year
/month
/day
/hour
/minute
/second
input. Use isSupportedDateTime(...)
to validate the input if necessary.
Example:
if(DateTimeLib.isSupportedDateTime(1970,02,01,23,30,59))
uint256 timestamp = DateTimeLib.dateTimeToTimestamp(1970,02,01,23,30,59) // returns 2763059
if(DateTimeLib.isSupportedDateTime(2022,11,10,06,47,30))
uint256 timestamp = DateTimeLib.dateTimeToTimestamp(2022,11,10,12,17,30) // returns 1668062850
Calculate year
/month
/day
/hour
/minute
/second
from timestamp
.
function timestampToDateTime(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second)
NOTE This function does not validate the year
/month
/day
/hour
/minute
/second
input. Use isSupportedTimestamp(...)
to validate the input if necessary.
Example:
if(DateTimeLib.isSupportedTimestamp(2763059))
(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) = DateTimeLib.timestampToDateTime(2763059) // returns 1970-02-01 23:30:59
if(DateTimeLib.isSupportedTimestamp(1668062850))
(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) = DateTimeLib.timestampToDateTime(1668062850) // returns 2022-11-10 12:17:30
Check given year is leap or not.
function isLeapYear(uint256 year) internal pure returns (bool leap)
Example:
bool isLeap = DateTimeLib.isLeapYear(1900) // returns False
bool isLeap = DateTimeLib.isLeapYear(2004) // returns True
bool isLeap = DateTimeLib.isLeapYear(2400) // returns True
Return number of day in the month daysInMonth
for the month specified by year
/month
.
function daysInMonth(uint256 year, uint256 month) internal pure returns (uint256 result)
Example:
uint256 day = DateTimeLib.daysInMonth(01, 1900) // returns 31
uint256 day = DateTimeLib.daysInMonth(02, 2001) // returns 28
uint256 day = DateTimeLib.daysInMonth(02, 2004) // returns 29
Return the day of the week weekday
(1 = Monday,2 = Tuesday ..., 7 = Sunday) for the date specified by timestamp
.
function weekday(uint256 timestamp) internal pure returns (uint256 result)
Check the given date is valid or not.
function isSupportedDate(uint256 year, uint256 month, uint256 day) internal pure returns (bool result)
NOTE This algorithm supported fully uint256 limit but Restricted max supported year to type(uint32).max. By the time, we will already be either extinct, an interstellar species, or the Earth's motion would have drastically changed. A smaller supported range will mean smaller bytecode needed to validate the dates.
Check the given datetime is valid or not.
function function isSupportedDateTime(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) internal pure returns (bool result)
Check the given epoch day is valid or not.
function isSupportedEpochDay(uint256 epochDay) internal pure returns (bool result)
NOTE This algorithm supported fully uint256 limit but Restricted max supported epochDay to MAX_SUPPORTED_EPOCH_DAY
. By the time, we will already be either extinct, an interstellar species, or the Earth's motion would have drastically changed.
Check the given timestamp is valid or not.
function isSupportedTimestamp(uint256 timestamp) internal pure returns (bool result)
NOTE This algorithm supported fully uint256 limit but Restricted max supported timstamp to MAX_SUPPORTED_TIMESTAMP
.
Return timestamp
of the Nth weekday from the year
/month
.
function nthWeekdayInMonthOfYearTimestamp(uint256 year, uint256 month, uint256 n, uint256 wd) internal pure returns (uint256 result)
NOTE This function does not validate the year
/month
and wd
input. Use isSupportedDate(year,month,1)
to validate for year
/month
and wd
must be in range of [1,7].
Example:
uint256 timestamp = DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022,12,1,DateTimeLib.FRI) // returns 1669939200 (1st Friday December 2022)
uint256 timestamp = DateTimeLib.nthWeekdayInMonthOfYearTimestamp(2022,11,6,DateTimeLib.WED) // returns 0 (6th Wednesday November 2022)
Calculate timestamp
of the most recent Monday.
function mondayTimestamp(uint256 timestamp) internal pure returns (uint256 result)
NOTE If timestamp < 345600 it returns 0 as per UTC it is thursday.
Calculate timestamp
falls on a Saturday or Sunday
function isWeekEnd(uint256 timestamp) internal pure returns (bool result)
Add numYears
years to the date and time specified by timestamp.
Note that the resulting day of the month will be adjusted if it exceeds the valid number of days in the month. For example, if the original date is 2020/02/29 and an additional year is added to this date, the resulting date will be an invalid date of 2021/02/29. The resulting date is then adjusted to 2021/02/28.
function addYears(uint256 timestamp, uint256 numYears) internal pure returns (uint256 result)
Add numMonths
months to the date and time specified by timestamp.
Note that the resulting day of the month will be adjusted if it exceeds the valid number of days in the month. For example, if the original date is 2019/01/31 and an additional month is added to this date, the resulting date will be an invalid date of 2019/02/31. The resulting date is then adjusted to 2019/02/28.
function addMonths(uint256 timestamp, uint256 numMonths) internal pure returns (uint256 result)
Add numDays
days to the date and time specified by timestamp.
function addDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result)
Add numHours
hours to the date and time specified by timestamp.
function addHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result)
Add numMinutes
minutes to the date and time specified by timestamp.
function addMinutes(uint256 timestamp, uint256 numMinutes) internal pure returns (uint256 result)
Add numSeconds
seconds to the date and time specified by timestamp.
function addSeconds(uint256 timestamp, uint256 numSeconds) internal pure returns (uint256 result)
Subtracts numYears
years from the unix timestamp.
Note that the resulting day of the month will be adjusted if it exceeds the valid number of days in the month. For example, if the original date is 2020/02/29 and a year is subtracted from this date, the resulting date will be an invalid date of 2019/02/29. The resulting date is then adjusted to 2019/02/28.
function subYears(uint256 timestamp, uint256 numYears) internal pure returns (uint256 result)
Subtracts numMonths
months from the unix timestamp.
Note that the resulting day of the month will be adjusted if it exceeds the valid number of days in the month. For example, if the original date is 2019/03/31 and a month is subtracted from this date, the resulting date will be an invalid date of 2019/02/31. The resulting date is then adjusted to 2019/02/28.
function subMonths(uint256 timestamp, uint256 numMonths) internal pure returns (uint256 result)
Subtracts numDays
days from the unix timestamp.
function subDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result)
Subtracts numHours
from the unix timestamp.
function subHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result)
Subtracts numMinutes
from the unix timestamp.
function subMinutes(uint256 timestamp, uint256 numMinutes) internal pure returns (uint256 result)
Subtracts numSeconds
from the unix timestamp.
function subSeconds(uint256 timestamp, uint256 numSeconds) internal pure returns (uint256 result)
Calculate the number of years between the dates specified by fromTimeStamp
and toTimestamp
.
Note that Even if the true time difference is less than a year, the difference can be non-zero is the timestamps are from diffrent Gregorian calendar years.
function diffYears(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)
Calculate the number of months between the dates specified by fromTimeStamp
and toTimestamp
.
Note that Even if the true time difference is less than a month, the difference can be non-zero is the timestamps are from diffrent Gregorian calendar months.
function diffMonths(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)
Calculate the number of days between the dates specified by fromTimeStamp
and toTimestamp
.
function diffDays(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)
Calculate the number of hours between the dates specified by fromTimeStamp
and toTimestamp
.
function diffHours(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)
Calculate the number of minutes between the dates specified by fromTimeStamp
and toTimestamp
.
function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)
Calculate the number of seconds between the dates specified by fromTimeStamp
and toTimestamp
.
function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)
This repository is inspired by or directly modified from many sources, primarily:
A copy of the webpage with the algorithm Date Time Algorithm.