How Is Rokuyo (六曜) Actually Calculated?
One formula, and the one line that keeps a leap month from silently breaking it.
Bokki Editorial
The short answer
Rokuyo (六曜) — the six-day cycle of 大安, 赤口, 先勝, 友引, 先負 and 仏滅 that Bokki's home page shows as one of four daily "symbol" cards — comes from a single formula: take the date's lunar calendar month number, add the lunar day number, and divide by six; the remainder picks one of the six days in a fixed order. It sounds like the simplest calculation on this whole site. It is also the one place where Bokki's code reads whether a date fell inside a lunar leap month, because the lunar calendar library that supplies the month number returns a negative number for leap months — and forgetting to strip that sign is a real, specific bug we can measure the exact size of.
The formula and today's example
rokuyo.ts converts a solar date to the lunar calendar (the same library the Saju engine uses, lunar-typescript), reads the lunar month and day, adds them, and takes the result mod 6 against a fixed array: 大安 (index 0), 赤口 (1), 先勝 (2), 友引 (3), 先負 (4), 仏滅 (5). For 24 August 2026 the lunar calendar reads month 7, day 12: 7 + 12 = 19, 19 mod 6 = 1, which names 赤口 — the day tradition says only noon is favourable. That result is checked against the library's own separate reference method, getLiuYao(), on every date the tests run, not just trusted because the arithmetic looks right.
Why a leap month needs Math.abs()
lunar-typescript has one quirk worth knowing: for a date that falls inside a leap month, the month number it returns is negative — a leap 2nd month reads as month −2, not month 2. Take 5 April 2023, which is the 15th day of that year's leap 2nd month (윤2월): the library reports month = −2, day = 15. Bokki's code takes the absolute value first: Math.abs(−2) + 15 = 17, and 17 mod 6 = 5, which names 仏滅 — and that matches the library's own getLiuYao() for the same date exactly. Skip the absolute value and the arithmetic still runs, but it runs on the wrong numbers: −2 + 15 = 13, and 13 mod 6 = 1, which names 赤口 instead — a completely different, wrong day. Nothing throws an error either way; the negative sign just quietly changes which of six answers you get.
How often this would have mattered
We scanned every day from 1950 to 2050 — 36,890 days — computing rokuyo() and comparing it against lunar-typescript's own getLiuYao() on each one. The match is perfect: zero mismatches across the whole century. Of those 36,890 days, 1,080 (2.9%) fall inside a lunar leap month. Rerunning the arithmetic without the absolute value on just those 1,080 days, 727 of them (67.3%) come out to a different day than the correct one — roughly two out of every three leap-month days would have quietly shown the wrong rokuyo, with no error and no way to notice unless you happened to check against the source.
What we don't calculate
Rokuyo isn't tied to any astronomical event — it's a pure calendar convention, so there's nothing in the sky to verify it against, only the calendar's own canonical implementation, which is what we checked. We reframed the traditionally most-feared day, 仏滅, as "a good day to empty out and begin again" rather than a warning (D-003, per PHILOSOPHY) — that's a warmth choice layered on top of the calculation, and it didn't touch which day lands in which slot; the six-day order and the mod-6 arithmetic are untouched. We didn't implement regional variants of the six-day cycle that some sources describe with a different starting offset — we verified against lunar-typescript's canonical mapping only, the same source Bokki's Saju engine already trusts. And rokuyo only reaches about a quarter of home-page visitors, since it's one of four daily symbol cards chosen by the date — we didn't change how often it appears to write this piece.
Closing note — 36,890 days scanned, 0 mismatches, 727 near-misses avoided
In short: rokuyo is (lunar month + lunar day) mod 6 against a fixed six-day cycle, and it is the one calculation on this site that reads the lunar calendar's leap-month sign directly. Scanned across a century (1950-2050, 36,890 days), it matches the reference library's own getLiuYao() on every single day. Inside that century, 1,080 days (2.9%) fall in a leap month, and dropping the one Math.abs() call that strips the leap-month library's negative sign would have produced the wrong day on 727 of them — 67.3%, or roughly two out of every three leap-month days. A leap month doesn't reach Saju's calculation at all (see the companion piece on leap months and Saju), but it reaches this one directly, and one absolute-value call is the entire difference between right and wrong two-thirds of the time it does.