Awarded: ICDevs.org Bounty #53 - DateTime Library Motoko - $10,000

ICDevs.org DateTime Library - #53

Current Status: Discussion

  • Discussion (03/24/2023)
  • Ratification: (TBD)
  • Open for application: (TBD)
  • Assigned (TBD)
  • In Review
  • Closed

Official Link

Bounty Details

  • Bounty Amount: $10,000 USD of ICP at award date.
  • ICDevs.org Bounty Acceleration: For each 1 ICP sent to 6e8afebab59f703356e189297e3f49fbe18ace5150ccc43f74f30ceb3f6b5ece, ICDevs.org will add .25 ICP to this issue and .75 ICP to fund other ICDevs.org initiatives.
  • Developer Type: Individual
  • Opened: TBD
  • Time Commitment: Months
  • Project Type: DateTime Library for Motoko
  • Experience Type: Expert - DateTime and Motoko

Description

The proposed project aims to create an updated and fully-featured datetime library for Motoko. The current datetime library in Motoko is basic and does not consider time zones, which can lead to inaccuracies in date and time calculations.

The new datetime library will be designed to be comprehensive and feature-rich, with support for time zones, date and time formatting, and a range of date and time calculations including duration arithmetic. The library will also include support for leap years and daylight saving time, which are important considerations in many applications.

To create this new datetime library, the project will require anf experienced developers who is proficient in Motoko and that has a strong understanding of date and time calculations. The dev will work closely with the Motoko community to ensure that the new library meets the needs of developers working on the Internet Computer.

There are several popular open source DateTime frameworks written in other languages such as Luxon in Javascript, Moment in Javascript and Joda-Time in Java. The new datetime library should be designed taking the best practices and learnings from these libraries while incorporating the unique features and requirements of Motoko.

Overall, the new datetime library will provide a valuable resource for developers working on the Internet Computer, enabling them to create more accurate and reliable applications that consider time zones and other important date and time factors.

The solution should include a significant test suite similar to the test suite of the libraries mentioned above.

This bounty gives the opportunity to

  • learn about Motoko
  • learn about DateTime programming

To apply for this bounty you should:

  • Include links to previous work building web applications and any other open-source contributions (i.e., your Github).
  • Provide a brief overview of how you will complete the task. This can include things like which dependencies you will use, how you will make it self-contained, the sacrifices you would have to make to achieve that, or how you will make it simple. Anything that can convince us you are taking a thoughtful and expert approach to this design.
  • Give an estimated timeline on completing the task.
  • Post your application text to the Bounty Thread

Selection Process

The ICDevs.org developerā€™s advisors will propose a vote to award the bounty and the Developer Advisors will vote.

Bounty Completion

Please keep your ongoing code in a public repository(fork or branch is ok). Please provide regular (at least weekly) updates. Code commits count as updates if you link to your branch/fork from the bounty thread. We just need to be able to see that you are making progress.

The balance of the bounty will be paid out at completion.

Once you have finished, please alert the dev forum thread that you have completed work and where we can find that work. We will review and award the bounty reward if the terms have been met. If there is any coordination work(like a pull request) or additional documentation needed we will inform you of what is needed before we can award the reward.

Bounty Abandonment and Re-awarding

If you cease work on the bounty for a prolonged(at the Developer Advisory Boardā€™s discretion) or if the quality of work degrades to the point that we think someone else should be working on the bounty we may re-award it. We will be transparent about this and try to work with you to push through and complete the project, but sometimes, it may be necessary to move on or to augment your contribution with another resource which would result in a split bounty.

Funding

The bounty was generously funded by the DFINITY Foundation. If you would like to turbocharge this bounty you can seed additional donations of ICP to 6e8afebab59f703356e189297e3f49fbe18ace5150ccc43f74f30ceb3f6b5ece. ICDevs will add .25 for every 1 token donated to the bounty. All donations will be tax deductible for US Citizens and Corporations. If you send a donation and need a donation receipt, please email the hash of your donation transaction, physical address, and name to donations@icdevs.org. More information about how you can contribute can be found at our donations page.

FYI: General Bounty Process

Discussion

The draft bounty is posted to the DFINITY developerā€™s forum for discussion

Ratification: (01/09/2023)

The developer advisorā€™s board will propose a bounty be ratified and a vote will take place to ratify the bounty. Until a bounty is ratified by the Dev it hasnā€™t been officially adopted. Please take this into consideration if you are considering starting early.

Open for application

Developers can submit applications to the Dev Forum post. The council will consider these as they come in and propose a vote to award the bounty to one of the applicants. If you would like to apply anonymously you can send an email to austin at icdevs dot org or sending a PM on the dev forum.

Assigned

A developer is currently working on this bounty, you are free to contribute, but any splitting of the award will need to be discussed with the currently assigned developer.

In Review

The Dev Council is reviewing the submission

Awarded

The award has been given and the bounty is closed.

Other ICDevs.org Bounties

5 Likes

I think I might want to tackle this one, if you guys will have me back. I have done a weird amount of DateTime and Timezone C# programming work for a previous job that should help me out here. Im playing with a few ideas on what the datetime/time types are going to look like but I came up with a list of features to support. Can add or change any if anyone has thoughts.

# Creation:

- Create DateTime for the current date and time
- Create DateTime from a specific date and time
- Create DateTime from various formats (e.g., ISO 8601, Unix timestamp)
- Handle timezone conversion to UTC and back and daylight savings time
- Validate date and time components (e.g., correct number of days in a month, valid hours, minutes, and seconds)

# Formatting:

- Format DateTime into human-readable strings in various formats (e.g., ISO 8601, RFC 2822, Unix timestamp)
  -? Format DateTime according to locale-specific rules and conventions
  -? Customize formatting with user-defined patterns

# Date and Time Manipulation:

- Add or subtract durations (e.g., days, hours, minutes, seconds)
- Set specific date and time components (e.g., year, month, day)
- Compare DateTimes for equality or order
- Truncate/Round DateTimes to a specific unit (e.g., remove minutes and seconds, leaving only hours)

# TimeSpans:

- Represent stretches of time as TimeSpans (e.g., 2 hours, 30 minutes)
- Perform arithmetic operations with TimeSpans (e.g., add, subtract)
- Calculate the difference between two DateTime objects as a TimeSpan

# Calendar Support:

- Retrieve calendar-related information (e.g., week number, day of the week)
- Perform calendar-specific calculations (e.g., add or subtract months, years)
- Identify leap years and handle leap year-specific calculations

5 Likes

Minimal DateTime implementation (no manipulation, etc.):

2 Likes

It may come in handy

2 Likes

Heres a question. Something I havent really settled on with Motoko yet is

  • the more functional/record + functions approach
    vs
  • the more object oriented approach with having a DateTime object with methods

Any thoughts on which way to go down.
With motoko, I feel like I should be doing more of the data + functions approach but there is some ease of use with the object oriented approach

Hereā€™s another simple library if this helps at all.

Iā€™m in favor of an object oriented approach that can produce its internal state if ā€œstableā€ data is necessary. Then, you can pass that data back into the class constructor or function if needed (i.e. fromDateTime() )

1 Like

Just as an update, ive been working on this on the side but I have just been waiting for approval to give this priority.
Thats all, just wanted to check in.

1 Like

What approvals do you need? You should be good to go on our end.

:man_shrugging: i didnā€™t see any confirmation and it still says open

What is the process these days for approval/review, do you guys use a DAO/group consensus or is it all you @skilesare

Iā€™ll stay putting priority towards it and give weekly updates

Ahhā€¦youā€™re rightā€¦I thought Iā€™d submitted it to the board, but I havenā€™t done so yetā€¦I though it was in the last batch. Iā€™ll do it asap, but as youā€™ve done other bounties I donā€™t expect anyone to object.

1 Like

UPDATE:

Im just going to put in here some design decisions I made which i encourage people to give me feedback during the process.
Here is what I got so far

The library is split into 3 modules/types for dates:

  • Components - the year, month, day, etcā€¦ of a date as a record type. This will be used as a data structure to create datetimes or get from datetimes. If converted into a datetime with a timezone, then the ā€˜timestampā€™/utc time will be different for each unique timezone.
public type Components = {
     year : Int;
     month : Nat;
     day : Nat;
     hour : Nat;
     minute : Nat;
     nanosecond : Nat;
};

I went with the ā€˜nanosecondā€™ vs the normal ā€˜secondā€™ or mixing different types of seconds. Open to critiques but it seems to work well this way.
I use a isValid(components : Components) : Bool to make sure that the combination of values are valid since there is no restrictions to the type.

  • DateTime - The class that holds a UTC/timestamp representation of a datetime. It will have all the normal functionality like adding, conversions to other formats, comparisons, and getting/calculating of datetime information.
    It takes in nanoseconds in the constructor
    I went with DateTime having no timezones because from my experience, if you dont need timezones, then they only get in the way an complicate things. Rather another class will be for timezones with datetimes
  • DateTimeWithTZ - (Name is a work in progress) The DateTimeWithTZ is a class with very similar functionality to DateTime, but the constrcutor and functionality handles timezone data.
    The constructor takes in Components and a timezone (could be nanoseconds but I found that it might be more? clear this way and there might need to be an initial conversion, but I dont have strong thoughts)
    TimeZones currently look like this:

    public type TimeZone = {
        #fixed : FixedTimeZone;
        #dynamic : DynamicTimeZone;
    };

    public type DynamicTimeZone = {
        getOffsetSeconds : (components : Components) -> Int;
    };

    public type FixedTimeZone = {
        #seconds : Int;
        #hoursAndMinutes : (Int, Nat);
    };

Where a timezone could be fixed or by dynamic. Dynamic would be a function that would get the fixed timezone value at a certain datetime.
My goal is to have a IANA implementation of this that is optional where someone could use the IANA timezones at the cost of size of the database data. Im not sure exactly how to approach the splitting up of the data if someone wants the smallest possible library and get what they need and not have it be tedious. Any thoughts appreciated about this.
I havent yet even tried to tackle the parsing of the logic of IANA data but Im assuming that is the way we want to go

2 Likes

If this is meant to work with time stamps received from external clients or sending data to other clients, milliseconds is a bit more standard. Maybe keep nanos, but add milliseconds (and nanos is the remainder).

Where does the tz come into play in this function here, and why does this return an Int?

I guess the confusing part is the TZ in the naming, but thereā€™s no reference to a time zone in the parameters passed in.

The idea is that a locales timezone is really just a certain offset on a certain date that can change overtime due to daylights savings or tweaks the governments decide to make for any reason. So this could be implemented by some IANA database code where it would determine the offset given a datetime.

Ya i need to rethink the whole area of timezone naming.
getTimeZoneOffset or getTimeZoneOffsetSeconds?

Just spitballing here - I like the idea of

func componentsToMillisSinceEpoch(components: Components, tzinfo: TzInfo) -> Int;

or

type Offset = Int; // relative to UTC, -12 to +12? Or an enum of #m12 to #p12

func componentsToMillisSinceEpoch(components: Components, offset: Offset) -> Int;

Then if you have DateTime as:

public type DateTime = {
  components : Components;
  offset : Int // relative to UTC, -12 to +12? Or an enum of #m12 to #p12
};

offset remains the internal representation, and you can layer whatever text TZ/region sugar on top.

Also, unsolicited advice, but Iā€™m a fan of chain style syntax like I did for motoko-color, where you preserve the initial DateTime but can immutably generate modified copies easily. Not sure how efficient this is though :sweat_smile:

1 Like

The problem is that timezones != offset which is the need of the dynamic timezone. The getOffsetSeconds gets the seconds of what the offset is at the specified ā€˜timezone agnostic datetimeā€™ (Components). So the offset would have to be an Int since the timezones are really determined by the seconds off it is from UTC even though most are divisible by hours. Look back before 1900 and no one is in sync like Rangoon before 1920 was +6:24:47 which makes my life just great lol

More like this? with good documentation. Or I could call it a TimeZoneLocale or something

if the components put in are before 1920, then i get out the seconds equivalent of +6:24:47

    public type Seconds = Int;
    public type DynamicTimeZone = {
        getOffset: (components : Components) -> Seconds;
    };

Big fan of the fluent/chain style. Used it a lot in my C# work, ill take a look. I think i am doing that somewhat already since I create a new DateTime object after a modification.

1 Like

For this reason it might be nice to have the tz/offset be a variant, so you can add and specify the exact tz/offset you want (#pst, #edt, #cet, #minus7, #plus5), and even allow a custom #customOffset: Int where the developer can provide that hour/seconds offset and dig their own grave :rofl:

Most of the time though, the developer will know the TZ theyā€™re looking for, and you can always add new variants as people request them.

Iā€™ve never written a datetime library though, so againā€¦take all this with a grain of salt.

Maybe @claudio, @kentosugama, and @rvanasa have some better input :slight_smile:

1 Like

Ya, i would say my current implementation is more technical and less user friendly. Ill probably do the predefined offset and custom like you suggest or if i can make it easy enough and small enough I was thinking about doing something that looks like DateTimeWithTZ(components, TimeZone.Locale("America/Los_Angeles") or DateTimeWithTZ(components, TimeZone.Offset(-8))

Any thoughts on LocalDateTime/LocalizedDateTime vs DateTimeWithTZ?

Is there a particular justification for the inclusion of timezones? Given that backend services operate globally and are not heavily reliant on the concept of timezones, their significance appears to be limited. Conversely, the client operates within a specific timezone, rendering the need for extensive timezone support less impactful. Therefore, I fail to perceive significant additional value in accommodating timezones, to be honest.

2 Likes

The justification is to allow for moving beyond just backend services. For motoko to grow we need to be able to write all kinds of software. (Completed: ICDevs.org - Bounty #34 - Wasmer Motoko - $10,000)

Right now you donā€™t write front end code in motoko, but that doesnā€™t mean you canā€™t.

The most direct use case: If you wanted to write a bbs with @kpeacock 's express like framework where the user can select their timezone, the server would need to format the date on posts if you were trying to make a pure html site.