Open rmeissner opened 5 years ago
A point we'll have to address if attempting to cater to a 'calendar day' usage will be that of timezones, which may be a major issue due to daylight savings, etc.
Yes that is true. I would probably assume UTC for simplicity and it would be possible to shift the time (e.g UTC+1 or UTC-10)
Leap seconds are dealt with at the EVM level. The unix timestamp that is obtained from block.timestamp
doesn't count real seconds, it counts "civil" seconds. Notice in this table how the same timestamp ending in 800 actually spans two real seconds.
In https://github.com/OpenZeppelin/openzeppelin-solidity/issues/533, the case was made for extending this to also include support for a cleaner Date
type. According to Solidity developers here, this should be done by us, not the language.
block.timestamp
. I think that discussion is not relevant anymore, but the original proposal by @martriay is still relevant.There's some ambiguity in #533, as it is not clear if it proposes Date
to be a function or a type because of the capital D. I think it was intended to be a function, which IMO would be a great starting point.
The reason I commented on this issue is that while auditing a smart contract I found errors in the way dates were computed.
The contract I was auditing had to lock some tokens until a certain date. It computed dates with now + offset
. This has two problems: (1) it depends on the deployment date. (2) the offset is easy to get wrong (spoiler: it was wrong).
I'd love to recommend the authors to use a human-readable representation of the dates, but I couldn't find a maintained function/lib for doing so. Having something like dateToTimestamp(year, month, day)
would be enough for this use-case.
So, functions to create timestamps from human dates: date(2019, 06, 12)
, datetime(2019, 06, 12, 00, 00)
. Sounds quite reasonable and useful.
Would these functions return the uint256
timestamp directly, or a struct with operations?
Also, how should we deal with timezones?
(2) the offset is easy to get wrong (spoiler: it was wrong).
@alcuadrado Mind sharing how it was wrong exactly?
Timezones are a mess, and DST only complicates matters further. I'd make it so that times specified in either UTC, or at a fixed offset (e.g. UTC+8 for Hong Kong, UTC-4 for Chile, etc.).
Would these functions return the
uint256
timestamp directly, or a struct with operations?
I think functions would be more efficient.
Btw, some of the functions in this library are also super useful.
Also, how should we deal with timezones?
I'd only do UTC. I don't see a way of managing timezones trustlessly, as any government can change their country's timezone whenever they want.
@alcuadrado Mind sharing how it was wrong exactly?
The offset was expressed as <base> * <units multiplier>
, and the <unit multiplier>
was wrong. Still, if it weren't wrong, reading it is way harder than a normal date (i.e. year, month & day).
@nventuro @frangio Guys, Any progress on this issue?
We're interested in adding this to the library. No one has started working on it yet.
This looks like good information for whoever wants to work on this: Low-Level Date Algorithms
Is this even under consideration?
The team is not proactively working on this feature but we would be happy to receive a PR implementing the interface I described above:
functions to create timestamps from human dates: date(2019, 06, 12), datetime(2019, 06, 12, 00, 00)
🧐 Motivation Time is important and off-chain there are often cases where time related checks need to be performed. To handle this on chain it would be nice to have some utils that would encapsulate these checks.
There are many use cases for this:
📝 Details There is a library that is already implementing this logic (https://github.com/pipermerriam/ethereum-datetime), but this is not really up to date, nor audited.
Also it would be interesting to consider edge cases like leap seconds (at least mention why they are not implemented).
An api should include method to check if what year/ month/ day/ hour/ minute a certain timestamp is.