Last active
February 11, 2022 11:45
-
-
Save maymax777/ac1d45b4169566f9b794a4ebde7b8b65 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.8.0; | |
library DateTime { | |
uint256 constant SECONDS_PER_DAY = 24 * 60 * 60; | |
int256 constant OFFSET19700101 = 2440588; | |
function _daysFromDate( | |
uint256 year, | |
uint256 month, | |
uint256 day | |
) internal pure returns (uint256 _days) { | |
require(year >= 1970); | |
int256 _year = int256(year); | |
int256 _month = int256(month); | |
int256 _day = int256(day); | |
int256 __days = _day - | |
32075 + | |
(1461 * (_year + 4800 + (_month - 14) / 12)) / | |
4 + | |
(367 * (_month - 2 - ((_month - 14) / 12) * 12)) / | |
12 - | |
(3 * ((_year + 4900 + (_month - 14) / 12) / 100)) / | |
4 - | |
OFFSET19700101; | |
_days = uint256(__days); | |
} | |
function _daysToDate(uint256 _days) | |
internal | |
pure | |
returns ( | |
uint256 year, | |
uint256 month, | |
uint256 day | |
) | |
{ | |
int256 __days = int256(_days); | |
int256 L = __days + 68569 + OFFSET19700101; | |
int256 N = (4 * L) / 146097; | |
L = L - (146097 * N + 3) / 4; | |
int256 _year = (4000 * (L + 1)) / 1461001; | |
L = L - (1461 * _year) / 4 + 31; | |
int256 _month = (80 * L) / 2447; | |
int256 _day = L - (2447 * _month) / 80; | |
L = _month / 11; | |
_month = _month + 2 - 12 * L; | |
_year = 100 * (N - 49) + _year + L; | |
year = uint256(_year); | |
month = uint256(_month); | |
day = uint256(_day); | |
} | |
function _isLeapYear(uint256 year) internal pure returns (bool leapYear) { | |
leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); | |
} | |
function _getDaysInMonth(uint256 year, uint256 month) | |
internal | |
pure | |
returns (uint256 daysInMonth) | |
{ | |
if ( | |
month == 1 || | |
month == 3 || | |
month == 5 || | |
month == 7 || | |
month == 8 || | |
month == 10 || | |
month == 12 | |
) { | |
daysInMonth = 31; | |
} else if (month != 2) { | |
daysInMonth = 30; | |
} else { | |
daysInMonth = _isLeapYear(year) ? 29 : 28; | |
} | |
} | |
function addMonths(uint256 timestamp, uint256 _months) | |
internal | |
pure | |
returns (uint256 newTimestamp) | |
{ | |
(uint256 year, uint256 month, uint256 day) = _daysToDate( | |
timestamp / SECONDS_PER_DAY | |
); | |
month += _months; | |
year += (month - 1) / 12; | |
month = ((month - 1) % 12) + 1; | |
uint256 daysInMonth = _getDaysInMonth(year, month); | |
if (day > daysInMonth) { | |
day = daysInMonth; | |
} | |
newTimestamp = | |
_daysFromDate(year, month, day) * | |
SECONDS_PER_DAY + | |
(timestamp % SECONDS_PER_DAY); | |
require(newTimestamp >= timestamp); | |
} | |
function diffMonths(uint256 fromTimestamp, uint256 toTimestamp) | |
internal | |
pure | |
returns (uint256 _months) | |
{ | |
require(fromTimestamp <= toTimestamp); | |
(uint256 fromYear, uint256 fromMonth, ) = _daysToDate( | |
fromTimestamp / SECONDS_PER_DAY | |
); | |
(uint256 toYear, uint256 toMonth, ) = _daysToDate( | |
toTimestamp / SECONDS_PER_DAY | |
); | |
_months = toYear * 12 + toMonth - fromYear * 12 - fromMonth; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment