给大家整理了三个 solidity智能合约的日期工具,里面包含基本的日期操作,可以直接拿去使用的。
pragma solidity ^0.5.1;
//时间工具
contract DateUtil {
uint constant internal SECONDS_PER_DAY = 24 * 60 * 60;
uint constant internal SECONDS_PER_HOUR = 60 * 60;
uint constant internal SECONDS_PER_MINUTE = 60;
uint constant internal OFFSET19700101 = 2440588;
//每月天数
uint8[] monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
//时间戳转日期
function daysToDate(int timestamp, int8 timezone) public pure returns (uint year, uint month, uint day){
return _daysToDate(timestamp + timezone * int(SECONDS_PER_HOUR));
}
//当月总天数
function monthTotalDay(int timestamp, int8 timezone) public view returns (uint){
(uint year, uint month,) = daysToDate(timestamp, timezone);
if (month != 2) {
return monthDays[month - 1];
}
return year % 4 == 0 ? 29 : 28;
}
//时间戳转日期,UTC时区
function _daysToDate(int timestamp) private pure returns (uint year, uint month, uint day) {
uint _days = uint(timestamp) / SECONDS_PER_DAY;
uint L = _days + 68569 + OFFSET19700101;
uint 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;
day = L - 2447 * month / 80;
L = month / 11;
month = month + 2 - 12 * L;
year = 100 * (N - 49) + year + L;
}
}
pragma solidity ^0.4.16;
contract DateTime {
/*
* Date and Time utilities for ethereum contracts
*
*/
struct _DateTime {
uint16 year;
uint8 month;
uint8 day;
uint8 hour;
uint8 minute;
uint8 second;
uint8 weekday;
}
uint constant DAY_IN_SECONDS = 86400;
uint constant YEAR_IN_SECONDS = 31536000;
uint constant LEAP_YEAR_IN_SECONDS = 31622400;
uint constant HOUR_IN_SECONDS = 3600;
uint constant MINUTE_IN_SECONDS = 60;
uint16 constant ORIGIN_YEAR = 1970;
//判断输入的年份是不是闰年
function isLeapYear(uint16 year) public pure returns (bool) {
if (year % 4 != 0) {
return false;
}
if (year % 100 != 0) {
return true;
}
if (year % 400 != 0) {
return false;
}
return true;
}
//判断输入的年份 的闰年前
function leapYearsBefore(uint year) public pure returns (uint) {
year -= 1;
return year / 4 - year / 100 + year / 400;
}
//输入年year 月month 得到当月的天数
function getDaysInMonth(uint8 month, uint16 year) public pure returns (uint8) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return 31;
}
else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
}
else if (isLeapYear(year)) {
return 29;
}
else {
return 28;
}
}
function parseTimestamp(uint timestamp) internal pure returns (_DateTime dt) {
uint secondsAccountedFor = 0;
uint buf;
uint8 i;
// Year
dt.year = getYear(timestamp);
buf = leapYearsBefore(dt.year) - leapYearsBefore(ORIGIN_YEAR);
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf;
secondsAccountedFor += YEAR_IN_SECONDS * (dt.year - ORIGIN_YEAR - buf);
// Month
uint secondsInMonth;
for (i = 1; i <= 12; i++) {
secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, dt.year);
if (secondsInMonth + secondsAccountedFor > timestamp) {
dt.month = i;
break;
}
secondsAccountedFor += secondsInMonth;
}
// Day
for (i = 1; i <= getDaysInMonth(dt.month, dt.year); i++) {
if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) {
dt.day = i;
break;
}
secondsAccountedFor += DAY_IN_SECONDS;
}
// Hour
dt.hour = getHour(timestamp);
// Minute
dt.minute = getMinute(timestamp);
// Second
dt.second = getSecond(timestamp);
// Day of week.
dt.weekday = getWeekday(timestamp);
}
//根据时间戳获取年份
function getYear(uint timestamp) public pure returns (uint16) {
uint secondsAccountedFor = 0;
uint16 year;
uint numLeapYears;
// Year
year = uint16(ORIGIN_YEAR + timestamp / YEAR_IN_SECONDS);
numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR);
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears;
secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears);
while (secondsAccountedFor > timestamp) {
if (isLeapYear(uint16(year - 1))) {
secondsAccountedFor -= LEAP_YEAR_IN_SECONDS;
}
else {
secondsAccountedFor -= YEAR_IN_SECONDS;
}
year -= 1;
}
return year;
}
//根据时间戳获取月份
function getMonth(uint timestamp) public pure returns (uint8) {
return parseTimestamp(timestamp).month;
}
//根据时间戳获取当前天数
function getDay(uint timestamp) public pure returns (uint8) {
return parseTimestamp(timestamp).day;
}
function getHour(uint timestamp) public pure returns (uint8) {
return uint8((timestamp / 60 / 60) % 24);
}
//获取分钟
function getMinute(uint timestamp) public pure returns (uint8) {
return uint8((timestamp / 60) % 60);
}
function getSecond(uint timestamp) public pure returns (uint8) {
return uint8(timestamp % 60);
}
//获取星期几
function getWeekday(uint timestamp) public pure returns (uint8) {
return uint8((timestamp / DAY_IN_SECONDS + 4) % 7);
}
//根据年月日获取时间戳
function toTimestamp(uint16 year, uint8 month, uint8 day) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, 0, 0, 0);
}
//根据年月日时获取时间戳
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, hour, 0, 0);
}
//根据年月日时分获取时间戳
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, hour, minute, 0);
}
//根据年月日时分秒获取时间戳
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) public pure returns (uint timestamp) {
uint16 i;
// Year
for (i = ORIGIN_YEAR; i < year; i++) {
if (isLeapYear(i)) {
timestamp += LEAP_YEAR_IN_SECONDS;
}
else {
timestamp += YEAR_IN_SECONDS;
}
}
// Month
uint8[12] memory monthDayCounts;
monthDayCounts[0] = 31;
if (isLeapYear(year)) {
monthDayCounts[1] = 29;
}
else {
monthDayCounts[1] = 28;
}
monthDayCounts[2] = 31;
monthDayCounts[3] = 30;
monthDayCounts[4] = 31;
monthDayCounts[5] = 30;
monthDayCounts[6] = 31;
monthDayCounts[7] = 31;
monthDayCounts[8] = 30;
monthDayCounts[9] = 31;
monthDayCounts[10] = 30;
monthDayCounts[11] = 31;
for (i = 1; i < month; i++) {
timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1];
}
// Day
timestamp += DAY_IN_SECONDS * (day - 1);
// Hour
timestamp += HOUR_IN_SECONDS * (hour);
// Minute
timestamp += MINUTE_IN_SECONDS * (minute);
// Second
timestamp += second;
return timestamp;
}
}
获取季度的时间
pragma solidity ^0.5.1;
//时间工具
contract DateUtil {
uint constant internal SECONDS_PER_DAY = 24 * 60 * 60;
uint constant internal SECONDS_PER_HOUR = 60 * 60;
uint constant internal SECONDS_PER_MINUTE = 60;
uint constant internal OFFSET19700101 = 2440588;
uint16 constant ORIGIN_YEAR = 1970;
uint constant LEAP_YEAR_IN_SECONDS = 31622400;
uint constant YEAR_IN_SECONDS = 31536000;
uint constant DAY_IN_SECONDS = 86400;
uint constant HOUR_IN_SECONDS = 3600;
uint constant MINUTE_IN_SECONDS = 60;
//每月天数
uint8[] monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
//时间戳转日期
function daysToDate(int timestamp, int8 timezone) public pure returns (uint year, uint month, uint day){
return _daysToDate(timestamp + timezone * int(SECONDS_PER_HOUR));
}
//当月总天数
function monthTotalDay(int timestamp, int8 timezone) public view returns (uint){
(uint year, uint month,) = daysToDate(timestamp, timezone);
if (month != 2) {
return monthDays[month - 1];
}
return year % 4 == 0 ? 29 : 28;
}
//时间戳转日期,UTC时区
function _daysToDate(int timestamp) private pure returns (uint year, uint month, uint day) {
uint _days = uint(timestamp) / SECONDS_PER_DAY;
uint L = _days + 68569 + OFFSET19700101;
uint 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;
day = L - 2447 * month / 80;
L = month / 11;
month = month + 2 - 12 * L;
year = 100 * (N - 49) + year + L;
}
//获取当个季度总天数和剩余多少天数
function getQuarterlyDay(int timestamp) public view returns(int){
(uint year, uint month, uint day) = _daysToDate(timestamp);
//年 月 日 季度 总天数 时间戳
return int(getQuarterly(uint16(year),uint8(month),uint8(day),getQuarterly(timestamp),0,timestamp));
}
//当日是否为季度的第一天
function getQuarterlyFirst(int timestamp) public pure returns(bool){
(uint year, uint month, uint day) = _daysToDate(timestamp);
if((month == 1 || month == 4 || month == 7 || month == 10) && day == 1){
return true;
}else{
return false;
}
}
//输入年year 月month 得到当月的天数
function getDaysInMonth(uint8 month, uint16 year) public pure returns (uint8) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return 31;
}
else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
}
else if (isLeapYear(year)) {
return 29;
}
else {
return 28;
}
}
//根据年月日获取时间戳
function toTimestamp(uint16 year, uint8 month, uint8 day) public pure returns (uint timestamp) {
return toTimestamp(year, month, day, 0, 0, 0);
}
//根据年月日时分秒获取时间戳
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) public pure returns (uint timestamp) {
uint16 i;
// Year
for (uint16 i = ORIGIN_YEAR; i < year; i++) {
if (isLeapYear(i)) {
timestamp += LEAP_YEAR_IN_SECONDS;
}
else {
timestamp += YEAR_IN_SECONDS;
}
}
// Month
uint8[12] memory monthDayCounts;
monthDayCounts[0] = 31;
if (isLeapYear(year)) {
monthDayCounts[1] = 29;
}
else {
monthDayCounts[1] = 28;
}
monthDayCounts[2] = 31;
monthDayCounts[3] = 30;
monthDayCounts[4] = 31;
monthDayCounts[5] = 30;
monthDayCounts[6] = 31;
monthDayCounts[7] = 31;
monthDayCounts[8] = 30;
monthDayCounts[9] = 31;
monthDayCounts[10] = 30;
monthDayCounts[11] = 31;
for (i = 1; i < month; i++) {
timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1];
}
// Day
timestamp += DAY_IN_SECONDS * (day - 1);
// Hour
timestamp += HOUR_IN_SECONDS * (hour);
// Minute
timestamp += MINUTE_IN_SECONDS * (minute);
// Second
timestamp += second;
return timestamp;
}
//判断输入的年份是不是闰年
function isLeapYear(uint16 year) public pure returns (bool) {
if (year % 4 != 0) {
return false;
}
if (year % 100 != 0) {
return true;
}
if (year % 400 != 0) {
return false;
}
return true;
}
//传入时间搓获取当前到了第几个季度
function getQuarterly(int timestamp) public pure returns(uint8){
(uint year, uint month, uint day) = _daysToDate(timestamp);
if(month >= 1 && month <= 3){
return 1;
}else if(month >= 4 && month <= 6){
return 2;
}else if(month >= 7 && month <= 9){
return 3;
}else if(month >= 10 && month <= 12){
return 4;
}
}
//年月日 季度 时间戳
function getQuarterly(uint16 year, uint8 month, uint8 day,uint quarterly,uint countNumber,int timestamp) public view returns(uint){
//获取当前日期
(uint yearPs, uint monthPs, uint dayPs) = _daysToDate(timestamp);
if(countNumber == 0){
//获取当月天数
countNumber = monthTotalDay(timestamp,8);
//当月天数-号数=剩余当月天数
countNumber = countNumber - day;
return getQuarterly(uint16(year), uint8(month), uint8(day),quarterly,countNumber,timestamp);
}
if(month > 12){
month = 1;
year++;
}else{
month++;
}
//根据年月日获取时间戳
int time = int(toTimestamp(year,month,day));
//获取季度
uint8 jidu = getQuarterly(time);
if(jidu != uint8(quarterly)){
return countNumber;
}else{
//根据时间搓获取当月天数
uint dayTime = monthTotalDay(time,8);
countNumber = countNumber + dayTime;
return getQuarterly(uint16(year), uint8(month), uint8(day),quarterly,countNumber,timestamp);
}
}
}