Mojo Date and Time

Working with dates and times appears in logging, scheduling, performance measurement, data analysis, and report generation. Mojo provides the time module for precise performance timing, and Python's datetime module is available through interop for calendar date and time operations.

Two Distinct Needs

  Performance timing (Mojo's time module):
    "How many nanoseconds did this function take?"
    Use: PerfCounter, time.now()

  Calendar date/time (Python's datetime module):
    "What day is today? How many days until the deadline?"
    Use: datetime.date, datetime.datetime, timedelta

Measuring Elapsed Time with PerfCounter

from time import perf_counter_ns

fn slow_function(n: Int) -> Int:
    var total = 0
    for i in range(n):
        total += i
    return total

fn main():
    var start = perf_counter_ns()
    var result = slow_function(10_000_000)
    var end = perf_counter_ns()

    var elapsed_ns = end - start
    var elapsed_ms = Float64(elapsed_ns) / 1_000_000.0

    print("Result:", result)
    print("Time:", elapsed_ms, "ms")
perf_counter_ns() returns an integer nanosecond timestamp.
  1 second = 1,000 ms = 1,000,000 µs = 1,000,000,000 ns

  Elapsed = end - start
  Convert: ns ÷ 1,000,000 = ms
           ns ÷ 1,000      = µs

Timing Multiple Sections

from time import perf_counter_ns

fn main():
    # Time section 1
    var t0 = perf_counter_ns()
    var a = 0
    for i in range(1_000_000):
        a += i
    var t1 = perf_counter_ns()

    # Time section 2
    var b = 1
    for i in range(1, 21):
        b *= i
    var t2 = perf_counter_ns()

    print("Sum loop:    ", (t1 - t0) // 1000, "µs")
    print("Factorial:   ", (t2 - t1) // 1000, "µs")
    print("Total:       ", (t2 - t0) // 1000, "µs")
Multi-section timing diagram:
  t0 ──── section 1 ──── t1 ──── section 2 ──── t2
  │                      │                       │
  └── duration1 = t1-t0  └── duration2 = t2-t1   │
  └──────── total = t2 - t0 ─────────────────────┘

Sleeping / Pausing Execution

from time import sleep

fn main():
    print("Starting...")
    sleep(1)    # pause for 1 second (Float64 in seconds)
    print("1 second passed")
    sleep(0.5)  # pause for 500 ms
    print("Another 500ms passed")

Getting the Current Date and Time

from python import Python

fn main() raises:
    var dt = Python.import_module("datetime")

    var now = dt.datetime.now()
    print(now)                    # 2025-03-15 14:23:07.123456
    print(now.year)               # 2025
    print(now.month)              # 3
    print(now.day)                # 15
    print(now.hour)               # 14
    print(now.minute)             # 23
    print(now.second)             # 7

    var today = dt.date.today()
    print(today)                  # 2025-03-15

Formatting Dates as Strings

from python import Python

fn main() raises:
    var dt = Python.import_module("datetime")
    var now = dt.datetime.now()

    # strftime format codes:
    print(now.strftime("%Y-%m-%d"))          # 2025-03-15
    print(now.strftime("%d/%m/%Y"))          # 15/03/2025
    print(now.strftime("%B %d, %Y"))         # March 15, 2025
    print(now.strftime("%H:%M:%S"))          # 14:23:07
    print(now.strftime("%I:%M %p"))          # 02:23 PM
    print(now.strftime("%A, %B %d %Y"))      # Saturday, March 15 2025
strftime format codes:
  %Y  → 4-digit year       2025
  %m  → 2-digit month      03
  %d  → 2-digit day        15
  %H  → hour (24h)         14
  %I  → hour (12h)         02
  %M  → minutes            23
  %S  → seconds            07
  %p  → AM/PM              PM
  %A  → full weekday       Saturday
  %B  → full month name    March
  %a  → short weekday      Sat
  %b  → short month        Mar

Parsing Strings into Dates

from python import Python

fn main() raises:
    var dt = Python.import_module("datetime")

    # Parse a date string
    var d = dt.datetime.strptime("2025-12-31", "%Y-%m-%d")
    print(d.year, d.month, d.day)   # 2025 12 31

    var d2 = dt.datetime.strptime("15/03/2025 14:30", "%d/%m/%Y %H:%M")
    print(d2)   # 2025-03-15 14:30:00

Date Arithmetic with timedelta

from python import Python

fn main() raises:
    var dt = Python.import_module("datetime")

    var today    = dt.date.today()
    var one_week = dt.timedelta(days=7)
    var next_week = today + one_week

    print("Today:     ", today)
    print("Next week: ", next_week)

    # Days between two dates
    var start = dt.date(2025, 1, 1)
    var end   = dt.date(2025, 12, 31)
    var delta = end - start
    print("Days in 2025:", int(delta.days))   # 364
Date arithmetic diagram:
  today: 2025-03-15
    + timedelta(days=7)
  result: 2025-03-22

  end - start = timedelta object
  timedelta.days gives the integer count

Timestamps for Logging

from python import Python
from time import perf_counter_ns

fn log(level: String, message: String) raises:
    var dt = Python.import_module("datetime")
    var now = dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print("[" + str(now) + "] [" + level + "] " + message)

fn main() raises:
    log("INFO",  "Application started")
    log("DEBUG", "Loading config file")
    log("WARN",  "High memory usage detected")
    log("ERROR", "Failed to connect to database")

Output:

[2025-03-15 14:23:07] [INFO]  Application started
[2025-03-15 14:23:07] [DEBUG] Loading config file
[2025-03-15 14:23:07] [WARN]  High memory usage detected
[2025-03-15 14:23:07] [ERROR] Failed to connect to database

UTC and Timezone Awareness

from python import Python

fn main() raises:
    var dt  = Python.import_module("datetime")
    var utc = dt.timezone.utc

    # UTC-aware timestamp
    var now_utc = dt.datetime.now(utc)
    print(now_utc)                   # 2025-03-15 09:23:07+00:00

    # Convert to ISO 8601 format (used in APIs)
    print(now_utc.isoformat())       # 2025-03-15T09:23:07+00:00

Key Takeaways

Use Mojo's perf_counter_ns() for high-precision performance timing in nanoseconds. Use sleep(seconds) to pause execution. For calendar dates and times, use Python's datetime module through interop. Format dates with strftime() using format codes like %Y-%m-%d. Parse date strings back to objects with strptime(). Add and subtract durations with timedelta. Use UTC-aware timestamps in APIs and logs to avoid timezone confusion. Combine datetime.now().strftime() with your log messages to create timestamped records.

Leave a Comment

Your email address will not be published. Required fields are marked *