Date and Time
Tokamak includes a date and time library for working with dates, times, and timestamps.
Quick Start
zig
const tk = @import("tokamak");
// Current time
const now = tk.time.Time.now();
const today = tk.time.Date.today();
// Create specific dates and times
const birthday = tk.time.Date.ymd(1990, 6, 15);
const meeting = tk.time.Time.unix(1234567890);
// Parse from string
const date = try tk.time.Date.parse("2024-12-25");Working with Dates
Creating Dates
zig
// Specific date
const d = tk.time.Date.ymd(2024, 3, 15);
// Current date
const today = tk.time.Date.today();
// Relative dates
const yesterday = tk.time.Date.yesterday();
const tomorrow = tk.time.Date.tomorrow();
// Parse ISO 8601 format
const parsed = try tk.time.Date.parse("2024-03-15");Date Arithmetic
zig
const d = tk.time.Date.ymd(2024, 3, 15);
// Add or subtract days, months, years
const next_week = d.add(.day, 7);
const next_month = d.add(.month, 1);
const next_year = d.add(.year, 1);
// Subtract using negative values
const last_week = d.add(.day, -7);
const last_month = d.add(.month, -1);Month-End Handling
When adding months to a date that doesn't exist in the target month, the day is automatically clamped:
zig
const jan31 = tk.time.Date.ymd(2024, 1, 31);
const feb = jan31.add(.month, 1); // 2024-02-29 (leap year)Period Start and End
zig
const d = tk.time.Date.ymd(2024, 3, 15);
// Start of period
const month_start = d.setStartOf(.month); // 2024-03-01
const year_start = d.setStartOf(.year); // 2024-01-01
// End of period
const month_end = d.setEndOf(.month); // 2024-03-31
const year_end = d.setEndOf(.year); // 2024-12-31Working with Times
Creating Times
zig
// Current time
const now = tk.time.Time.now();
// From Unix timestamp
const t = tk.time.Time.unix(1234567890);
// Midnight today/tomorrow
const today = tk.time.Time.today();
const tomorrow = tk.time.Time.tomorrow();Extracting Components
zig
const t = tk.time.Time.unix(1234567890);
// Get date part
const date = t.date(); // tk.time.Date.ymd(2009, 2, 13)
// Get time components
const hour = t.hour(); // 23
const minute = t.minute(); // 31
const second = t.second(); // 30Time Arithmetic
zig
const t = tk.time.Time.now();
// Add time units
const in_5_minutes = t.add(.minutes, 5);
const in_2_hours = t.add(.hours, 2);
const tomorrow = t.add(.days, 1);
// Combine operations
const later = t.add(.hours, 2).add(.minutes, 30);Setting Components
zig
const t = tk.time.Time.now();
// Set specific time of day
const at_noon = t.setHour(12).setMinute(0).setSecond(0);
// Set date while preserving time-of-day
const christmas = tk.time.Date.ymd(2024, 12, 25);
const christmas_at_current_time = t.setDate(christmas);Period Boundaries
zig
const t = tk.time.Time.now();
// Start of period
const day_start = t.setStartOf(.day); // Today at 00:00:00
const month_start = t.setStartOf(.month); // First day at 00:00:00
const year_start = t.setStartOf(.year); // Jan 1 at 00:00:00
// End of period
const day_end = t.setEndOf(.day); // Today at 23:59:59
const month_end = t.setEndOf(.month); // Last day at 23:59:59
const year_end = t.setEndOf(.year); // Dec 31 at 23:59:59Common Patterns
Date Ranges
zig
// Iterate through a date range
const start = tk.time.Date.ymd(2024, 1, 1);
const end = tk.time.Date.ymd(2024, 1, 31);
var current = start;
while (current.cmp(end) != .gt) {
// Process each date
std.debug.print("{f}\n", .{current});
current = current.add(.day, 1);
}Last Month's Report
zig
const now = tk.time.Date.today();
const month_start = now.setStartOf(.month).add(.month, -1);
const month_end = month_start.setEndOf(.month);
const report_period = .{
.start = tk.time.Time.unix(0).setDate(month_start),
.end = tk.time.Time.unix(0).setDate(month_end),
};Scheduling Tasks
zig
// Schedule task 5 minutes from now
const task_time = tk.time.Time.now().add(.minutes, 5);
// Store as Unix timestamp
const task = Task{
.scheduled_at = task_time.epoch,
.name = "Send reminder email",
};Retry with Backoff
zig
// Exponential backoff
const failed_time = tk.time.Time.now();
const retry_delay = std.math.pow(i64, 2, attempt_count);
const next_retry = failed_time.add(.minutes, retry_delay);Formatting
Dates and times have default string formats:
zig
const d = tk.time.Date.ymd(2024, 3, 15);
const t = tk.time.Time.unix(1234567890);
// Use {f} format specifier
try writer.print("Date: {f}\n", .{d});
// Output: Date: 2024-03-15
try writer.print("Time: {f}\n", .{t});
// Output: Time: 2009-02-13 23:31:30 UTCComparison
zig
const d1 = tk.time.Date.ymd(2024, 3, 15);
const d2 = tk.time.Date.ymd(2024, 3, 16);
// Compare dates
const order = d1.cmp(d2); // .lt, .eq, or .gt
// Compare times (as integers)
const t1 = tk.time.Time.unix(100);
const t2 = tk.time.Time.unix(200);
if (t1.epoch < t2.epoch) {
// t1 is earlier
}Leap Years
Leap years are handled automatically:
zig
// Check if year is leap year
if (tk.time.isLeapYear(2024)) {
// 2024 is a leap year
}
// Automatic handling in date operations
const jan31 = tk.time.Date.ymd(2024, 1, 31);
const feb = jan31.add(.month, 1); // 2024-02-29 (auto-clamped)
const jan31_2023 = tk.time.Date.ymd(2023, 1, 31);
const feb_2023 = jan31_2023.add(.month, 1); // 2023-02-28Important Notes
UTC Only
All times are in UTC. There is no timezone support. If you need timezone conversions, handle them manually:
zig
const utc = tk.time.Time.now();
const offset = 5 * 3600; // UTC+5
const local = utc.add(.seconds, offset);Second Precision
Times have second precision only. For subsecond timing (benchmarks, profiling), use std.time.nanoTimestamp() instead.