summaryrefslogtreecommitdiff
path: root/src/cmd/date.zig
blob: a2996679574a75c6ae5c2b7bd19174e4ede5ae05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const std = @import("std");
const Allocator = std.mem.Allocator;
const print = std.debug.print;

const types = @import("./lib/types.zig");
const CommandStatus = types.CommandStatus;
const OutputCapture = types.OutputCapture;
const InputSource = types.InputSource;

fn isLeapYear(year: u32) bool {
    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0);
}

pub const Date = struct {
    pub fn eval(date: Date, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
        _ = date;
        _ = input_source;

        const timestamp = std.time.timestamp();
        const epoch_seconds = @as(u64, @intCast(timestamp));
        const epoch_day = @divFloor(epoch_seconds, std.time.s_per_day);

        // Calculate days since Unix epoch (1970-01-01)
        // Unix epoch is 719163 days since year 1 AD
        const days_since_year_1 = epoch_day + 719163;

        // Simple algorithm to convert days to year/month/day
        var year: u32 = 1;
        var remaining_days = days_since_year_1;

        // Find the year
        while (true) {
            const days_in_year: u64 = if (isLeapYear(year)) 366 else 365;
            if (remaining_days < days_in_year) break;
            remaining_days -= days_in_year;
            year += 1;
        }

        // Days in each month (non-leap year)
        const days_in_month = [_]u32{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

        var month: u32 = 1;
        for (days_in_month, 1..) |days, m| {
            var month_days = days;
            // Adjust February for leap years
            if (m == 2 and isLeapYear(year)) {
                month_days = 29;
            }

            if (remaining_days < month_days) {
                month = @intCast(m);
                break;
            }
            remaining_days -= month_days;
        }

        const day = remaining_days + 1; // Days are 1-indexed

        const output = try std.fmt.allocPrint(allocator, "Current date is {d:0>2}/{d:0>2}/{d}\n", .{ month, day, year });
        defer allocator.free(output);
        if (output_capture) |capture| {
            try capture.write(output);
        } else {
            print("{s}", .{output});
        }
        return CommandStatus{ .Code = 0 };
    }
};