Skip to content

Commit

Permalink
create DateTime.sol
Browse files Browse the repository at this point in the history
this file is useful for finding date,time,year month from timestamp.
  • Loading branch information
jinal2349 authored Mar 3, 2023
1 parent 0912806 commit 5c8fe7e
Showing 1 changed file with 354 additions and 0 deletions.
354 changes: 354 additions & 0 deletions Vesting/DateTime.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,354 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ----------------------------------------------------------------------------
// DateTime Library v2.0
//
// A gas-efficient Solidity date and time library
//
// https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
//
// Tested date range 1970/01/01 to 2345/12/31
//
// Conventions:
// Unit | Range | Notes
// :-------- |:-------------:|:-----
// timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
// year | 1970 ... 2345 |
// month | 1 ... 12 |
// day | 1 ... 31 |
// hour | 0 ... 23 |
// minute | 0 ... 59 |
// second | 0 ... 59 |
// dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
// ----------------------------------------------------------------------------

library DateTime {
uint256 constant SECONDS_PER_DAY = 24 * 60 * 60;
uint256 constant SECONDS_PER_HOUR = 60 * 60;
uint256 constant SECONDS_PER_MINUTE = 60;
int256 constant OFFSET19700101 = 2440588;

uint256 constant DOW_MON = 1;
uint256 constant DOW_TUE = 2;
uint256 constant DOW_WED = 3;
uint256 constant DOW_THU = 4;
uint256 constant DOW_FRI = 5;
uint256 constant DOW_SAT = 6;
uint256 constant DOW_SUN = 7;

// ------------------------------------------------------------------------
// Calculate the number of days from 1970/01/01 to year/month/day using
// the date conversion algorithm from
// http://aa.usno.navy.mil/faq/docs/JD_Formula.php
// and subtracting the offset 2440588 so that 1970/01/01 is day 0
//
// 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
// - offset
// ------------------------------------------------------------------------
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);
}

// ------------------------------------------------------------------------
// Calculate year/month/day from the number of days since 1970/01/01 using
// the date conversion algorithm from
// http://aa.usno.navy.mil/faq/docs/JD_Formula.php
// and adding the offset 2440588 so that 1970/01/01 is day 0
//
// int L = days + 68569 + offset
// int N = 4 * L / 146097
// L = L - (146097 * N + 3) / 4
// year = 4000 * (L + 1) / 1461001
// L = L - 1461 * year / 4 + 31
// month = 80 * L / 2447
// dd = L - 2447 * month / 80
// L = month / 11
// month = month + 2 - 12 * L
// year = 100 * (N - 49) + year + L
// ------------------------------------------------------------------------
function _daysToDate(uint256 _days) internal pure returns (uint256 year, uint256 month, uint256 day) {
unchecked {
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 timestampFromDate(uint256 year, uint256 month, uint256 day) internal pure returns (uint256 timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
}

function timestampFromDateTime(
uint256 year,
uint256 month,
uint256 day,
uint256 hour,
uint256 minute,
uint256 second
)
internal
pure
returns (uint256 timestamp)
{
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR
+ minute * SECONDS_PER_MINUTE + second;
}

function timestampToDate(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day) {
unchecked {
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}
}

function timestampToDateTime(uint256 timestamp)
internal
pure
returns (uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second)
{
unchecked {
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint256 secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
secs = secs % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
second = secs % SECONDS_PER_MINUTE;
}
}

function isValidDate(uint256 year, uint256 month, uint256 day) internal pure returns (bool valid) {
if (year >= 1970 && month > 0 && month <= 12) {
uint256 daysInMonth = _getDaysInMonth(year, month);
if (day > 0 && day <= daysInMonth) {
valid = true;
}
}
}

function isValidDateTime(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second)
internal
pure
returns (bool valid)
{
if (isValidDate(year, month, day)) {
if (hour < 24 && minute < 60 && second < 60) {
valid = true;
}
}
}

function isLeapYear(uint256 timestamp) internal pure returns (bool leapYear) {
(uint256 year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
leapYear = _isLeapYear(year);
}

function _isLeapYear(uint256 year) internal pure returns (bool leapYear) {
leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

function isWeekDay(uint256 timestamp) internal pure returns (bool weekDay) {
weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
}

function isWeekEnd(uint256 timestamp) internal pure returns (bool weekEnd) {
weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
}

function getDaysInMonth(uint256 timestamp) internal pure returns (uint256 daysInMonth) {
(uint256 year, uint256 month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
daysInMonth = _getDaysInMonth(year, month);
}

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

// 1 = Monday, 7 = Sunday
function getDayOfWeek(uint256 timestamp) internal pure returns (uint256 dayOfWeek) {
uint256 _days = timestamp / SECONDS_PER_DAY;
dayOfWeek = ((_days + 3) % 7) + 1;
}

function getYear(uint256 timestamp) internal pure returns (uint256 year) {
(year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
}

function getMonth(uint256 timestamp) internal pure returns (uint256 month) {
(, month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
}

function getDay(uint256 timestamp) internal pure returns (uint256 day) {
(,, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
}

function getHour(uint256 timestamp) internal pure returns (uint256 hour) {
uint256 secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
}

function getMinute(uint256 timestamp) internal pure returns (uint256 minute) {
uint256 secs = timestamp % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
}

function getSecond(uint256 timestamp) internal pure returns (uint256 second) {
second = timestamp % SECONDS_PER_MINUTE;
}

function addYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
year += _years;
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 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 addDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _days * SECONDS_PER_DAY;
require(newTimestamp >= timestamp);
}

function addHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
require(newTimestamp >= timestamp);
}

function addMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
require(newTimestamp >= timestamp);
}

function addSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp + _seconds;
require(newTimestamp >= timestamp);
}

function subYears(uint256 timestamp, uint256 _years) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
year -= _years;
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 subMonths(uint256 timestamp, uint256 _months) internal pure returns (uint256 newTimestamp) {
(uint256 year, uint256 month, uint256 day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint256 yearMonth = year * 12 + (month - 1) - _months;
year = yearMonth / 12;
month = (yearMonth % 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 subDays(uint256 timestamp, uint256 _days) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _days * SECONDS_PER_DAY;
require(newTimestamp <= timestamp);
}

function subHours(uint256 timestamp, uint256 _hours) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
require(newTimestamp <= timestamp);
}

function subMinutes(uint256 timestamp, uint256 _minutes) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
require(newTimestamp <= timestamp);
}

function subSeconds(uint256 timestamp, uint256 _seconds) internal pure returns (uint256 newTimestamp) {
newTimestamp = timestamp - _seconds;
require(newTimestamp <= timestamp);
}

function diffYears(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _years) {
require(fromTimestamp <= toTimestamp);
(uint256 fromYear,,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
(uint256 toYear,,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
_years = toYear - fromYear;
}

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

function diffDays(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _days) {
require(fromTimestamp <= toTimestamp);
_days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
}

function diffHours(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _hours) {
require(fromTimestamp <= toTimestamp);
_hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
}

function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _minutes) {
require(fromTimestamp <= toTimestamp);
_minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
}

function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp) internal pure returns (uint256 _seconds) {
require(fromTimestamp <= toTimestamp);
_seconds = toTimestamp - fromTimestamp;
}
}

0 comments on commit 5c8fe7e

Please sign in to comment.