Skip to content

martinvuyk/mojo_datetime

Repository files navigation

mojo_datetime

Nightly Build Status

A flexible Mojo datetime implementation.

Fully Mojo native, no external dependencies.

Versioning

While Mojo stabilizes, this project will be released for amost every compiler version (it might skip some nightlies) with the schema <project_version>-compiler-<compiler_version>.

Distribution channels

  • Github releases for nightly versions, 1.0.0b1, and 0.26.2
  • The latest 1.0.0b1 version should be in the modular-community channel

Pixi Installation

The project can still be built from source even if a nightly version is skipped by using a previous version's release since the code isn't changing much between minor nightly relases. If one version isn't building due to source incompatibility, just try a lower nightly version tag.

Add mojo_datetime to your project's pixi.toml:

[workspace]
...
preview = ["pixi-build"]

[dependencies]
mojo_datetime = { git = "https://github.com/martinvuyk/mojo_datetime.git", tag = "0.1.1-compiler-1.0.0b1" }

Then run:

pixi install

Nightly releases should be available automatically every midnight (with a corresponding compiler version tag). But it can also be built directly from the main branch.

[dependencies]
mojo_datetime = { git = "https://github.com/martinvuyk/mojo_datetime.git", branch = "main" }

About the library

Many of the core types are able to be injected with updated values in case this library becomes out-of-date. The default values like leap seconds and daylight savings time transition rules are provided on a best-effort basis.

  • DateTime
    • A structure aware of TimeZone, Calendar, and leap days and seconds.
  • TimeZone
    • By default UTC, highly customizable. It can be implicitly built from an IANA TimeZone identifier as long as it is in the default zone info dict.
  • DayOfWeek
    • A calendar-aware day of the week struct, it provides a safe abstraction over the different calendar's interpretation of what a day of the week's value range looks like.
  • TimeDelta
    • A struct representing a positive (incl. 0) time delta. It is aware of what SI unit of time it contains.

Localization system

A trait DTLocale is provided that allows one to specify a dynamic handled Locale with a lifetime, like what Libc requires.

As a fallback, an implementation for LibCLocale is provided, which enables one to use any locale supported by the platform's Libc. But using a Mojo native implementation of the trait should be preferred.

Native Mojo locales are provided for these locales, with a trait NativeDTLocale that can be extended that enables fast bringup:

  • GenericEnglishDTLocale
  • USDTLocale
  • SpanishDTLocale
  • FrenchDTLocale
  • PortugueseDTLocale
  • ChineseDTLocale
  • JapaneseDTLocale
  • RussianDTLocale
  • HindiDTLocale
  • ArabicDTLocale
  • BengaliDTLocale
  • GermanDTLocale
  • KoreanDTLocale
  • IndonesianDTLocale
  • ItalianDTLocale

Examples:

from std.testing import assert_equal, assert_true
from mojo_datetime import DateTime, Calendar, IsoFormat, TZ_UTC, TimeDelta
from mojo_datetime.calendar import PythonCalendar, UTCCalendar

def main() raises:
    var dt = DateTime(2024, 6, 18, 22, 14, 7)
    assert_equal("2024-06-18T22:14:07+00:00", String(dt))
    var res = String()
    dt.write_to[IsoFormat.HH_MM_SS](res)
    dt = DateTime.parse[IsoFormat.HH_MM_SS](res)
    assert_equal("0001-01-01T22:14:07+00:00", String(dt))

    var dt1 = DateTime["Etc/UTC-4"](2024, 6, 18, hour=0)
    var dt2 = DateTime["Etc/UTC-3"](2024, 6, 18, hour=1)
    assert_equal(dt1.to_utc(), dt2.to_utc())

    # time delta
    assert_equal((dt1 + TimeDelta(hours=4)).replace[tz=TZ_UTC](), dt2.to_utc())

    # using python and unix calendar should have no difference in results
    var dt1_p = DateTime["Etc/UTC-4", PythonCalendar](2024, 6, 18, hour=0)
    var dt2_u = DateTime["Etc/UTC-3", UTCCalendar](2024, 6, 18, hour=1)
    assert_equal(dt1_p.to_calendar[UTCCalendar]().to_utc(), dt2_u.to_utc())

    comptime fstr = "mojo: %Y🔥%m🤯%d"
    res = ""
    var ref1 = DateTime(9, 6, 1)
    ref1.write_to[fstr](res)
    assert_equal("mojo: 0009🔥06🤯01", res)
    assert_equal(ref1, DateTime.parse[fstr](res))

    comptime fstr2 = "%Y-%m-%d %H:%M:%S.%f"
    res = ""
    ref1 = DateTime(2024, 9, 9, 9, 9, 9, 9, 9)
    ref1.write_to[fstr2](res)
    assert_equal("2024-09-09 09:09:09.009009", res)
    assert_equal(ref1, DateTime.parse[fstr2](res))

    dt = DateTime({2026, 4, 28, 15, 30, 0})
    comptime fstr3 = "%a %d %b %Y %H:%M:%S"
    res = ""
    dt.write_to[fstr3](res)
    assert_equal(res, "Tue 28 Apr 2026 15:30:00")
    assert_equal(dt, DateTime.parse[fstr3](res))

    comptime fstr4 = "%A %d %B %Y %I:%M:%S %p"
    res = ""
    dt.write_to[fstr4](res)
    assert_equal(res, "Tuesday 28 April 2026 03:30:00 PM")
    assert_equal(dt, DateTime.parse[fstr4](res))

About

A flexible Mojo datetime library implementation

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors