Zig
Bikram Sambat dates, conversion, arithmetic, formatting, parsing, ranges and fiscal years for Zig 0.17.0. The core and the patro are two modules of one package, released together from one tag. They compile the C amalgamation at a pinned tag, so the calendar data and the patro data are the same as every other port.
nepdateis the core module.nepdate_patrois the patro module: tithi, public holidays and events for BS 2077-01-01 to 2084-08-20. It importsnepdate.- There is no package registry. The release is a source archive whose hash you record in
build.zig.zon.
Install
Section titled “Install”zig fetch --save https://github.com/sanamhub/nepdate-zig/archive/refs/tags/v1.0.0-rc.1.tar.gzzig fetch adds the dependency and its hash to your build.zig.zon. Add both modules to your
executable:
const dep = b.dependency("nepdate", .{ .target = target, .optimize = optimize });exe.root_module.addImport("nepdate", dep.module("nepdate"));exe.root_module.addImport("nepdate_patro", dep.module("nepdate_patro"));Quick start
Section titled “Quick start”const nepdate = @import("nepdate");
const date = try nepdate.Date.fromBs(2081, 4, 15);var buffer: [16]u8 = undefined;try date.write(&buffer); // 2081/04/15const ad = date.englishDate(); // 2024-07-30const long = try date.longAlloc(allocator, .{}); // Shrawan 15, 2081A date is always a real day of the calendar, from BS 1901-01-01 to 2199-12-30 (AD 1844-04-11 to 2143-04-15). Construction validates the year, then the month, then the day, and returns an error union. There is no invalid or default value in the API.
const date = try nepdate.Date.fromBs(2081, 4, 32);_ = date.year(); // 2081_ = date.month(); // .shrawan_ = date.day(); // 32_ = date.dayOfWeek(); // .friday_ = date.dayOfYear(); // 126_ = date.monthLength(); // 32_ = date.yearLength(); // 366yearLength is the BS year length, 364 to 367 days, and replaces the C# IsLeapYear().
monthEndDate() replaces MonthEndDate().
Conversion and serialization
Section titled “Conversion and serialization”try nepdate.Date.fromGregorian(2024, 7, 30);try nepdate.Date.fromYmd(20810415);_ = (try nepdate.Date.fromBs(2081, 4, 15)).ymd(); // 20810415const iso = try (try nepdate.Date.fromBs(2081, 4, 15)).toJsonAlloc(allocator);_ = try nepdate.Date.fromJson(iso);Batch conversion keeps input order and is all or nothing:
var out: [1]nepdate.Date = undefined;_ = try nepdate.toNepaliDates(&.{.{ .year = 2024, .month = 7, .day = 30 }}, &out);Arithmetic
Section titled “Arithmetic”const date = try nepdate.Date.fromBs(2081, 4, 32);_ = try date.addDays(30); // 2081-05-30_ = try date.addMonths(2, .clamp); // 2081-06-30_ = try date.addMonths(2, .spill); // 2081-07-02_ = date.daysUntil(try nepdate.Date.fromBs(2081, 4, 16)); // 1daysUntil is other - this; minus is the C# operator direction, this - other. Fractional
months and days are not ported.
Formatting
Section titled “Formatting”const date = try nepdate.Date.fromBs(2081, 4, 15);const short = try date.shortAlloc(allocator, .{ .order = .dmy, .separator = .dash }); // 15-04-2081const unicode = try date.shortAlloc(allocator, .{ .lang = .ne }); // २०८१/०४/१५const long = try date.longAlloc(allocator, .{}); // Shrawan 15, 2081const pattern = try date.formatAlloc(allocator, "MMMM d, yyyy", .en); // Shrawan 15, 2081{f} in std.fmt writes YYYY/MM/DD. Functions that build text take an allocator or a caller
buffer; nothing allocates behind your back.
Parsing
Section titled “Parsing”_ = try nepdate.Date.parse("2081/04/15");_ = try nepdate.Date.parse("२०८१/०४/१५");_ = try nepdate.Date.parseLenient("15 Shrawan 2081 B.S.");_ = nepdate.Date.tryParse("2081/13/01"); // nullThe strict parser accepts ASCII and Devanagari digits. The lenient parser accepts month names in English or Nepali, the day before the year, and era markers. Failures are named error values.
Ranges
Section titled “Ranges”const range = try nepdate.Range.of( try nepdate.Date.fromBs(2081, 4, 10), try nepdate.Date.fromBs(2081, 4, 20),);_ = range.length(); // 11_ = range.contains(try nepdate.Date.fromBs(2081, 4, 15)); // trueconst text = try range.formatAlloc(allocator); // 2081/04/10 - 2081/04/20Ranges are inclusive and non-empty. They offer containment, overlap, adjacency, intersection, union, difference, month and fiscal-quarter splits, interval walks, working days and weekend days.
Fiscal year
Section titled “Fiscal year”const fy = nepdate.FiscalYear.containing(try nepdate.Date.fromBs(2082, 1, 15));_ = fy.year; // 2081var label_buffer: [39]u8 = undefined;_ = try fy.label(&label_buffer, .en); // 2081/82The clock and the zone are arguments, never a hidden local setting.
const instant: i64 = 1722364200; // 2024-07-30 18:30 UTC_ = try nepdate.Date.todayNepal(instant); // 2081-04-16_ = try nepdate.Date.today(0, instant); // 2081-04-15_ = try nepdate.Date.todayIn(.nepal, instant); // 2081-04-16const patro = @import("nepdate_patro");
var events: [8]patro.Event = undefined;const info = try patro.infoInto(try nepdate.Date.fromBs(2081, 1, 1), &events);_ = info.tithiEn(); // Panchami_ = info.is_public_holiday; // true_ = info.events[0].english; // New Yearpatro.info(allocator, date) allocates the event list and has a deinit; infoInto uses your
buffer. The patro covers 2077-01-01 to 2084-08-20 and returns empty values outside that range.
Data and correctness
Section titled “Data and correctness”The tests assert every shared vector file, walk every supported day through Gregorian and
YYYYMMDD, and check the vendored C files against their release tag. The details are in
the port’s README and
API.md.
Performance
Section titled “Performance”B1 to B8 against the C core are in benchmarks.md. The numbers were taken on an idle machine, pinned to one performance core, and the idle check is recorded with the table.