A Solidity date and time utility library deployed by Piper Merriam on October 6, 2015, providing functions to parse Unix timestamps into human-readable date com
Key Facts
Description
The DateTime contract was deployed at block 343248 on October 6, 2015, by address 0xd3CdA913deB6f67967B99D67aCDFa1712C293601, which also deployed the Ethereum Alarm Clock fourteen days earlier on September 22, 2015. The source code includes the contract's own address in the header comment, a pattern suggesting it was designed as a shared, reusable library that other contracts could reference on-chain.
The library defines a DateTime struct containing fields for year, month, day, hour, minute, second, and weekday as unsigned integers. It exposes a parseTimestamp function that converts a Unix timestamp into this structured form. The implementation correctly handles leap year detection using the full Gregorian calendar rules: years divisible by 4 are leap years, with exceptions for century years not divisible by 400.
The contract was compiled with Solidity v0.1.3, one of the earliest stable compiler versions available on mainnet. The library pattern used here, where utility code is deployed as a standalone contract whose address is distributed, was an early approach to code reuse in Solidity before formal library linking was mature.
This deployment was part of pipermerriam's active development of the Ethereum Alarm Clock system. Scheduling transactions at future block numbers requires working with block timestamps, making date parsing utilities a practical dependency for the scheduling infrastructure.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified on Etherscan.
Show source code (Solidity)
contract DateTime {
/*
* Date and Time utilities for ethereum contracts
*
* address: 0x1a6184cd4c5bea62b0116de7962ee7315b7bcbce
*/
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) constant returns (bool) {
if (year % 4 != 0) {
return false;
}
if (year % 100 != 0) {
return true;
}
if (year % 400 != 0) {
return false;
}
return true;
}
function parseTimestamp(uint timestamp) internal returns (DateTime dt) {
uint secondsAccountedFor = 0;
uint buf;
uint8 i;
dt.year = ORIGIN_YEAR;
// Year
while (true) {
if (isLeapYear(dt.year)) {
buf = LEAP_YEAR_IN_SECONDS;
}
else {
buf = YEAR_IN_SECONDS;
}
if (secondsAccountedFor + buf > timestamp) {
break;
}
dt.year += 1;
secondsAccountedFor += buf;
}
// Month
uint8[12] monthDayCounts;
monthDayCounts[0] = 31;
if (isLeapYear(dt.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;
uint secondsInMonth;
for (i = 0; i < monthDayCounts.length; i++) {
secondsInMonth = DAY_IN_SECONDS * monthDayCounts[i];
if (secondsInMonth + secondsAccountedFor > timestamp) {
dt.month = i + 1;
break;
}
secondsAccountedFor += secondsInMonth;
}
// Day
for (i = 0; i < monthDayCounts[dt.month - 1]; i++) {
if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) {
dt.day = i + 1;
break;
}
secondsAccountedFor += DAY_IN_SECONDS;
}
// Hour
for (i = 0; i < 24; i++) {
if (HOUR_IN_SECONDS + secondsAccountedFor > timestamp) {
dt.hour = i;
break;
}
secondsAccountedFor += HOUR_IN_SECONDS;
}
// Minute
for (i = 0; i < 60; i++) {
if (MINUTE_IN_SECONDS + secondsAccountedFor > timestamp) {
dt.minute = i;
break;
}
secondsAccountedFor += MINUTE_IN_SECONDS;
}
if (timestamp - secondsAccountedFor > 60) {
__throw();
}
// Second
dt.second = uint8(timestamp - secondsAccountedFor);
// Day of week.
buf = timestamp / DAY_IN_SECONDS;
dt.weekday = uint8((buf + 3) % 7);
}
function getYear(uint timestamp) constant returns (uint16) {
return parseTimestamp(timestamp).year;
}
function getMonth(uint timestamp) constant returns (uint16) {
return parseTimestamp(timestamp).month;
}
function getDay(uint timestamp) constant returns (uint16) {
return parseTimestamp(timestamp).day;
}
function getHour(uint timestamp) constant returns (uint16) {
return parseTimestamp(timestamp).hour;
}
function getMinute(uint timestamp) constant returns (uint16) {
return parseTimestamp(timestamp).minute;
}
function getSecond(uint timestamp) constant returns (uint16) {
return parseTimestamp(timestamp).second;
}
function getWeekday(uint timestamp) constant returns (uint8) {
return parseTimestamp(timestamp).weekday;
}
function toTimestamp(uint16 year, uint8 month, uint8 day) constant returns (uint timestamp) {
return toTimestamp(year, month, day, 0, 0, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) constant returns (uint timestamp) {
return toTimestamp(year, month, day, hour, 0, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) constant 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) constant 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] 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 __throw() {
uint[] arst;
arst[1];
}
}