Skip to content

Latest commit

 

History

History
494 lines (322 loc) · 15.5 KB

README.md

File metadata and controls

494 lines (322 loc) · 15.5 KB

DateTimeLib

NPM CI MIT License

Gas-Efficient Solidity DateTime Library

Safety

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.

Installation

To install with Foundry:

forge install Atarpara/DateTimeLib

To install with Hardhat or Truffle:

npm install 

Conventions

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.



Functions

dateToEpochDay

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

epochDayToDate

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

dateToTimestamp

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

timestampToDate

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

dateTimeToTimestamp

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

timestampToDateTime

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

isLeapYear

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

daysInMonth

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

weekday

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)

isSupportedDate

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.


isSupportedDateTime

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)

isSupportedEpochDay

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.


isSupportedTimestamp

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.


nthWeekdayInMonthOfYearTimestamp

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)

mondayTimestamp

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.


isWeekEnd

Calculate timestamp falls on a Saturday or Sunday

function isWeekEnd(uint256 timestamp) internal pure returns (bool result)

addYears

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)

addMonths

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)

addDays

Add numDays days to the date and time specified by timestamp.

function addDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result)

addHours

Add numHours hours to the date and time specified by timestamp.

function addHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result)

addMinutes

Add numMinutes minutes to the date and time specified by timestamp.

function addMinutes(uint256 timestamp, uint256 numMinutes) internal pure returns (uint256 result)

addSeconds

Add numSeconds seconds to the date and time specified by timestamp.

function addSeconds(uint256 timestamp, uint256 numSeconds) internal pure returns (uint256 result)

subYears

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)

subMonths

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)

subDays

Subtracts numDays days from the unix timestamp.

function subDays(uint256 timestamp, uint256 numDays) internal pure returns (uint256 result)

subHours

Subtracts numHours from the unix timestamp.

function subHours(uint256 timestamp, uint256 numHours) internal pure returns (uint256 result)

subMinutes

Subtracts numMinutes from the unix timestamp.

function subMinutes(uint256 timestamp, uint256 numMinutes) internal pure returns (uint256 result)

subSeconds

Subtracts numSeconds from the unix timestamp.

function subSeconds(uint256 timestamp, uint256 numSeconds) internal pure returns (uint256 result)

diffYears

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)

diffMonths

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)

diffDays

Calculate the number of days between the dates specified by fromTimeStamp and toTimestamp.

function diffDays(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)

diffHours

Calculate the number of hours between the dates specified by fromTimeStamp and toTimestamp.

function diffHours(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)

diffMinutes

Calculate the number of minutes between the dates specified by fromTimeStamp and toTimestamp.

function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)

diffSeconds

Calculate the number of seconds between the dates specified by fromTimeStamp and toTimestamp.

function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 result)

Acknowledgements

This repository is inspired by or directly modified from many sources, primarily:

References

A copy of the webpage with the algorithm Date Time Algorithm.