<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: azathothx</title>
    <description>The latest articles on DEV Community by azathothx (@azathothx).</description>
    <link>https://dev.to/azathothx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4082345%2Fd9c56e7a-4c6d-45fb-af68-fa19b5173ee4.png</url>
      <title>DEV Community: azathothx</title>
      <link>https://dev.to/azathothx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/azathothx"/>
    <language>en</language>
    <item>
      <title>Migrating from crontab: five everyday schedules, translated into Kairos</title>
      <dc:creator>azathothx</dc:creator>
      <pubDate>Sun, 13 Sep 2026 15:57:25 +0000</pubDate>
      <link>https://dev.to/azathothx/migrating-from-crontab-five-everyday-schedules-translated-into-kairos-16lf</link>
      <guid>https://dev.to/azathothx/migrating-from-crontab-five-everyday-schedules-translated-into-kairos-16lf</guid>
      <description>&lt;p&gt;If you arrived from the &lt;a href="https://kairos-lang.org/en/" rel="noopener noreferrer"&gt;Kairos 1.0 announcement&lt;/a&gt;, this is the&lt;br&gt;
hands-on one: take a crontab you already have and translate it.&lt;/p&gt;

&lt;p&gt;First, the honest part: &lt;strong&gt;if your jobs are plain fixed-time repeats, stay on cron.&lt;/strong&gt; "Every hour",&lt;br&gt;
"3am daily" — there is nothing to gain from rewriting them. You reach for a schedule language when&lt;br&gt;
you hit one of these: "end of month" won't fit; "business day" won't fit; the job started running at&lt;br&gt;
the wrong hour after a server move; nobody can tell you what was skipped during an outage.&lt;/p&gt;

&lt;p&gt;All examples below use one premise — the 2026 US federal holidays (observed dates) — and were run on&lt;br&gt;
the reference implementation. The premise is declared once and reused:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;premise US {
  calendar-system: Gregorian
  tz: "America/New_York"
  wkst: Sun
}

@US
holidays2026 = [2026-01-01, 2026-01-19, 2026-02-16, 2026-05-25, 2026-06-19,
                2026-07-03, 2026-09-07, 2026-10-12, 2026-11-11, 2026-11-26,
                2026-12-25] covering: 2026..2026
satSun = everyDay |&amp;gt; filter(d =&amp;gt; weekday(d) == Sat or weekday(d) == Sun)
bizDay = everyDay \ (satSun | holidays2026)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. &lt;code&gt;0 9 * * 1-5&lt;/code&gt; — weekdays at 9
&lt;/h2&gt;

&lt;p&gt;Two things this cron line does not say. &lt;strong&gt;Which 9 o'clock&lt;/strong&gt; — it's whatever timezone the host&lt;br&gt;
happens to have, which is exactly how "the batch moved an hour after we containerized" happens.&lt;br&gt;
And &lt;strong&gt;holidays&lt;/strong&gt; — cron has no such concept.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bizDay |&amp;gt; at(T09:00)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Labor Day week (Sep 4–10, 2026):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-09-04T09:00
2026-09-08T09:00
2026-09-09T09:00
2026-09-10T09:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monday 9/7 (Labor Day) and the weekend are skipped. "New York, 9:00" is written in the definition,&lt;br&gt;
so it survives any host move.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. &lt;code&gt;55 23 28-31 * *&lt;/code&gt; + a script — month-end at 23:55
&lt;/h2&gt;

&lt;p&gt;cron has no "last day", so the folk remedy is to wake up on the 28th–31st and let a script check&lt;br&gt;
"is tomorrow the 1st?". The check disappears into the expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monthEnd |&amp;gt; at(T23:55)
#=&amp;gt; 2026-09-30T23:55  2026-10-31T23:55  2026-11-30T23:55  2026-12-31T23:55
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Payday: the 25th, previous business day if it falls on a weekend or holiday
&lt;/h2&gt;

&lt;p&gt;This is where migration starts to pay off — cron cannot express the second half at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;everyDay |&amp;gt; within(month) |&amp;gt; nth(25) |&amp;gt; roll(Preceding, on: bizDay)
#=&amp;gt; 2026-09-25  2026-10-23  2026-11-25  2026-12-24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;October 25 is a Sunday, so it rolls back to Friday the 23rd. December 25 is Christmas Day, so it&lt;br&gt;
rolls back to the 24th. &lt;code&gt;roll&lt;/code&gt; is a &lt;em&gt;conditional&lt;/em&gt; move — it only acts when the point isn't on the&lt;br&gt;
axis — which is what distinguishes it from counting (&lt;code&gt;shift&lt;/code&gt;).&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Last business day of the month
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bizDay |&amp;gt; within(month) |&amp;gt; last
#=&amp;gt; 2026-09-30  2026-10-30  2026-11-30  2026-12-31
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;October 31 is a Saturday, so the month closes on Friday the 30th. "Build the stream of business&lt;br&gt;
days, take the last point of each month" — the structure reads exactly as stated.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Three business days before month-end
&lt;/h2&gt;

&lt;p&gt;The expression that started the whole project. Holidays are simply not on the business-day ruler,&lt;br&gt;
so counting skips them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monthEnd |&amp;gt; roll(Preceding, on: bizDay) |&amp;gt; shift(-3, unit: bizDay)
#=&amp;gt; 2026-08-26  2026-09-25  2026-10-27  2026-11-24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;November: the 30th is a Monday; three business days back skips Thanksgiving (11/26) and lands on&lt;br&gt;
Tuesday the 24th.&lt;/p&gt;
&lt;h2&gt;
  
  
  The three questions cron never answers
&lt;/h2&gt;

&lt;p&gt;Save the definition to a file and ask the CLI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's next?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kairos next -n 3 --from 2026-09-14 payday.kairos
2026-09-25
2026-10-23
2026-11-25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What did I miss?&lt;/strong&gt; Say the box was down Oct 20–31:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kairos list --from 2026-10-20 --to 2026-11-01 payday.kairos
2026-10-23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The payroll run on the 23rd was skipped — and you learn it as a &lt;em&gt;list&lt;/em&gt;, not by re-deriving the&lt;br&gt;
schedule in your head. (&lt;code&gt;--from&lt;/code&gt;/&lt;code&gt;--to&lt;/code&gt; is a half-open interval; the &lt;code&gt;--to&lt;/code&gt; day is excluded.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how do I actually run it? Keep one crontab line.&lt;/strong&gt; Kairos stops at &lt;em&gt;when things should&lt;br&gt;
happen&lt;/em&gt;; firing, retrying, and logging stay with your runner (systemd, a job queue, whatever you&lt;br&gt;
already trust). That division of labor is written into the spec, not left to convention — which is&lt;br&gt;
no help by itself, so here are the two wiring patterns. Both work with the CLI as it ships&lt;br&gt;
(&lt;code&gt;--json&lt;/code&gt; emits the same points, machine-readable, with epoch milliseconds). One thing to know first:&lt;br&gt;
labels, the &lt;code&gt;[--from, --to)&lt;/code&gt; window and the default "today" are read in &lt;strong&gt;your machine's time zone&lt;/strong&gt;&lt;br&gt;
(override with &lt;code&gt;--tz&lt;/code&gt;). The outputs in this post were taken with the machine in &lt;code&gt;America/New_York&lt;/code&gt;;&lt;br&gt;
elsewhere, add &lt;code&gt;--tz America/New_York&lt;/code&gt; and you get the same labels. If the machine's zone and the&lt;br&gt;
definition's &lt;code&gt;premise&lt;/code&gt; zone differ, day-granular points print with a time of day — midnight in New&lt;br&gt;
York shows up as &lt;code&gt;T13:00&lt;/code&gt; in Tokyo — and the daily window may not line up with the definition's day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern 1: cron stays the clock, Kairos makes the decision.&lt;/strong&gt; Keep a single crontab line and move&lt;br&gt;
the calendar logic out of it. Every morning at 9, ask "is there a point today?" and run the job if so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 9 * * *  cd /srv/batch &amp;amp;&amp;amp; ./run-if-today.sh payday.kairos ./payday.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c"&gt;# run-if-today.sh &amp;lt;definition.kairos&amp;gt; &amp;lt;job&amp;gt; — exec the job if there is a point in [today, tomorrow)&lt;/span&gt;
&lt;span class="nv"&gt;today&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%F&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;tomorrow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$today&lt;/span&gt;&lt;span class="s2"&gt; + 1 day"&lt;/span&gt; +%F&lt;span class="si"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;# GNU date; macOS: date -v+1d +%F&lt;/span&gt;
&lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kairos list &lt;span class="nt"&gt;--from&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$today&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--to&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$tomorrow&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.results[0].dates | length'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Holidays and the time zone live in the definition, so the crontab line carries no weekday and no&lt;br&gt;
day-of-month. The window is [today, tomorrow) in the machine's zone; if the definition's &lt;code&gt;premise&lt;/code&gt;&lt;br&gt;
zone is a different one, pass &lt;code&gt;--tz&lt;/code&gt; with that zone so the window is the definition's day. Count with &lt;code&gt;--json&lt;/code&gt;: the human-readable output also prints the coverage summary as&lt;br&gt;
&lt;code&gt;#&lt;/code&gt; lines, so a naive &lt;code&gt;| grep -q .&lt;/code&gt; would fire every day. With the &lt;code&gt;payday.kairos&lt;/code&gt; above this&lt;br&gt;
yields 0 for 2026-09-14 and 1 for 2026-09-25.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern 2: schedule the next point, one at a time.&lt;/strong&gt; Put the time of day into the definition as&lt;br&gt;
well (&lt;code&gt;… |&amp;gt; roll(Preceding, on: bizDay) |&amp;gt; at(T09:00)&lt;/code&gt;) and ask for the next point. &lt;code&gt;next --json&lt;/code&gt;&lt;br&gt;
returns it as wall-clock text and as epoch milliseconds; hand it to a one-shot OS timer, and let the&lt;br&gt;
job re-register the next point as its last step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kairos next &lt;span class="nt"&gt;--json&lt;/span&gt; payday.kairos | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.results[0].dates[0]'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;# e.g. 2026-09-25T09:00 — printed in the machine's local time zone, which is what the timer expects&lt;/span&gt;
systemd-run &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="nt"&gt;--on-calendar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;tr &lt;/span&gt;T &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;:00"&lt;/span&gt; ./payday.sh
&lt;span class="c"&gt;# same shape with at(1) on Linux, or schtasks /sc once on Windows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Re-materialize the point list periodically" is exactly the operating model the spec describes; the&lt;br&gt;
full 20–40-line version of this gets its own post.&lt;/p&gt;

&lt;h2&gt;
  
  
  And the data
&lt;/h2&gt;

&lt;p&gt;The examples inline eleven holidays. In production you feed calendar data through an &lt;code&gt;external&lt;/code&gt;&lt;br&gt;
binding — the expression stays static, the data arrives at runtime — and every table carries a&lt;br&gt;
&lt;code&gt;covering:&lt;/code&gt; claim ("verified through this date"). Past that date, results still come out, but with&lt;br&gt;
a machine-readable annotation saying the calendar ran out. Nothing degrades silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBVUyB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogU3VuCn0KCkBVUwpob2xpZGF5czIwMjYgPSBbMjAyNi0wMS0wMSwgMjAyNi0wMS0xOSwgMjAyNi0wMi0xNiwgMjAyNi0wNS0yNSwgMjAyNi0wNi0xOSwKICAgICAgICAgICAgICAgIDIwMjYtMDctMDMsIDIwMjYtMDktMDcsIDIwMjYtMTAtMTIsIDIwMjYtMTEtMTEsIDIwMjYtMTEtMjYsCiAgICAgICAgICAgICAgICAyMDI2LTEyLTI1XSBjb3ZlcmluZzogMjAyNi4uMjAyNgpzYXRTdW4gPSBldmVyeURheSB8PiBmaWx0ZXIoZCA9PiB3ZWVrZGF5KGQpID09IFNhdCBvciB3ZWVrZGF5KGQpID09IFN1bikKYml6RGF5ID0gZXZlcnlEYXkgXCAoc2F0U3VuIHwgaG9saWRheXMyMDI2KQoKZXZlcnlEYXkgfD4gd2l0aGluKG1vbnRoKSB8PiBudGgoMjUpIHw-IHJvbGwoUHJlY2VkaW5nLCBvbjogYml6RGF5KQ&amp;amp;f=2026-07-01&amp;amp;t=2026-11-01&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;Payday, 25th → previous business day&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBVUyB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogU3VuCn0KCkBVUwpob2xpZGF5czIwMjYgPSBbMjAyNi0wMS0wMSwgMjAyNi0wMS0xOSwgMjAyNi0wMi0xNiwgMjAyNi0wNS0yNSwgMjAyNi0wNi0xOSwKICAgICAgICAgICAgICAgIDIwMjYtMDctMDMsIDIwMjYtMDktMDcsIDIwMjYtMTAtMTIsIDIwMjYtMTEtMTEsIDIwMjYtMTEtMjYsCiAgICAgICAgICAgICAgICAyMDI2LTEyLTI1XSBjb3ZlcmluZzogMjAyNi4uMjAyNgpzYXRTdW4gPSBldmVyeURheSB8PiBmaWx0ZXIoZCA9PiB3ZWVrZGF5KGQpID09IFNhdCBvciB3ZWVrZGF5KGQpID09IFN1bikKYml6RGF5ID0gZXZlcnlEYXkgXCAoc2F0U3VuIHwgaG9saWRheXMyMDI2KQoKbW9udGhFbmQgfD4gcm9sbChQcmVjZWRpbmcsIG9uOiBiaXpEYXkpIHw-IHNoaWZ0KC0zLCB1bml0OiBiaXpEYXkp&amp;amp;f=2026-08-01&amp;amp;t=2026-12-01&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;Three business days before month-end&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything runs in the browser; nothing leaves the page. Install the CLI with&lt;br&gt;
&lt;code&gt;npm i -g kairos-lang&lt;/code&gt;, then &lt;code&gt;kairos next -n 3 payday.kairos&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Kairos is at 1.0 — the language is frozen; the reference implementation is a prototype&lt;br&gt;
(TypeScript, zero runtime dependencies). Docs are canonical in Japanese with a&lt;br&gt;
&lt;a href="https://kairos-lang.org/en/spec/" rel="noopener noreferrer"&gt;full English mirror&lt;/a&gt;. Repo:&lt;br&gt;
&lt;a href="https://github.com/azathothx/kairos-lang" rel="noopener noreferrer"&gt;https://github.com/azathothx/kairos-lang&lt;/a&gt;. Apache-2.0.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure (AI-assisted): the English text of this post was drafted with an LLM from my Japanese originals and reviewed by me before publishing. Every code example and its output was executed by the reference implementation; the numbers are measured, not written.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>cron</category>
      <category>scheduling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Kairos 1.0 — a schedule language where "3 business days before month-end" is an expression</title>
      <dc:creator>azathothx</dc:creator>
      <pubDate>Sun, 13 Sep 2026 15:57:20 +0000</pubDate>
      <link>https://dev.to/azathothx/kairos-10-a-schedule-language-where-3-business-days-before-month-end-is-an-expression-87i</link>
      <guid>https://dev.to/azathothx/kairos-10-a-schedule-language-where-3-business-days-before-month-end-is-an-expression-87i</guid>
      <description>&lt;p&gt;Today I tagged &lt;strong&gt;1.0&lt;/strong&gt; of &lt;a href="https://github.com/azathothx/kairos-lang" rel="noopener noreferrer"&gt;Kairos&lt;/a&gt;, a schedule&lt;br&gt;
definition language I've been building — a small DSL where schedules like "3 business days&lt;br&gt;
before month-end" or "payday on the 25th, previous business day if it's a holiday" are single&lt;br&gt;
expressions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;premise US { calendar-system: Gregorian; calendar: NYSE; tz: "America/New_York"; wkst: Sun }

@US
monthEnd |&amp;gt; roll(Preceding, on: bizDay) |&amp;gt; shift(-3, unit: bizDay)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The itch
&lt;/h2&gt;

&lt;p&gt;cron can say "the 25th". It cannot say "the 25th, rolled back onto business days". Quartz has&lt;br&gt;
&lt;code&gt;L&lt;/code&gt; and &lt;code&gt;LW&lt;/code&gt;, but they don't compose and don't know about holidays. RRULE was designed as an&lt;br&gt;
exchange format, not an expression language.&lt;/p&gt;

&lt;p&gt;The root problem isn't a missing feature — &lt;strong&gt;their expressions don't compose&lt;/strong&gt;. You can't take&lt;br&gt;
the dates one rule derives and feed them into the next rule. Kairos is built around closure:&lt;br&gt;
every expression maps a time stream to a time stream, so derived streams (substitute holidays,&lt;br&gt;
fiscal periods, lunisolar months) feed further definitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in your browser
&lt;/h2&gt;

&lt;p&gt;The reference implementation runs client-side; nothing leaves the page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBVUyB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogU3VuCn0KCkBVUwpob2xpZGF5czIwMjYgPSBbMjAyNi0wMS0wMSwgMjAyNi0wMS0xOSwgMjAyNi0wMi0xNiwgMjAyNi0wNS0yNSwgMjAyNi0wNi0xOSwKICAgICAgICAgICAgICAgIDIwMjYtMDctMDMsIDIwMjYtMDktMDcsIDIwMjYtMTAtMTIsIDIwMjYtMTEtMTEsIDIwMjYtMTEtMjYsCiAgICAgICAgICAgICAgICAyMDI2LTEyLTI1XSBjb3ZlcmluZzogMjAyNi4uMjAyNgpzYXRTdW4gPSBldmVyeURheSB8PiBmaWx0ZXIoZCA9PiB3ZWVrZGF5KGQpID09IFNhdCBvciB3ZWVrZGF5KGQpID09IFN1bikKYml6RGF5ID0gZXZlcnlEYXkgXCAoc2F0U3VuIHwgaG9saWRheXMyMDI2KQoKZXZlcnlEYXkgfD4gd2l0aGluKG1vbnRoKSB8PiBudGgoMjUpIHw-IHJvbGwoUHJlY2VkaW5nLCBvbjogYml6RGF5KQo&amp;amp;f=2026-07-01&amp;amp;t=2026-11-01&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;Payday: the 25th → previous business day (US federal holidays)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBVUyB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogU3VuCn0KCkBVUwpob2xpZGF5czIwMjYgPSBbMjAyNi0wMS0wMSwgMjAyNi0wMS0xOSwgMjAyNi0wMi0xNiwgMjAyNi0wNS0yNSwgMjAyNi0wNi0xOSwKICAgICAgICAgICAgICAgIDIwMjYtMDctMDMsIDIwMjYtMDktMDcsIDIwMjYtMTAtMTIsIDIwMjYtMTEtMTEsIDIwMjYtMTEtMjYsCiAgICAgICAgICAgICAgICAyMDI2LTEyLTI1XSBjb3ZlcmluZzogMjAyNi4uMjAyNgpzYXRTdW4gPSBldmVyeURheSB8PiBmaWx0ZXIoZCA9PiB3ZWVrZGF5KGQpID09IFNhdCBvciB3ZWVrZGF5KGQpID09IFN1bikKYml6RGF5ID0gZXZlcnlEYXkgXCAoc2F0U3VuIHwgaG9saWRheXMyMDI2KQoKbW9udGhFbmQgfD4gcm9sbChQcmVjZWRpbmcsIG9uOiBiaXpEYXkpIHw-IHNoaWZ0KC0zLCB1bml0OiBiaXpEYXkpCg&amp;amp;f=2026-08-01&amp;amp;t=2026-12-01&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;3 business days before month-end&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBVUyB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogU3VuCn0KCkBVUwphY3R1YWwgPSBbMjAyNi0wMS0wMSwgMjAyNi0wMS0xOSwgMjAyNi0wMi0xNiwgMjAyNi0wNS0yNSwgMjAyNi0wNi0xOSwgMjAyNi0wNy0wNCwKICAgICAgICAgIDIwMjYtMDktMDcsIDIwMjYtMTAtMTIsIDIwMjYtMTEtMTEsIDIwMjYtMTEtMjYsIDIwMjYtMTItMjUsCiAgICAgICAgICAyMDI3LTAxLTAxLCAyMDI3LTAxLTE4LCAyMDI3LTAyLTE1LCAyMDI3LTA1LTMxLCAyMDI3LTA2LTE5LCAyMDI3LTA3LTA0LAogICAgICAgICAgMjAyNy0wOS0wNiwgMjAyNy0xMC0xMSwgMjAyNy0xMS0xMSwgMjAyNy0xMS0yNSwgMjAyNy0xMi0yNV0gY292ZXJpbmc6IDIwMjYuLjIwMjcKc2F0SG9sID0gYWN0dWFsIHw-IGZpbHRlcihkID0-IHdlZWtkYXkoZCkgPT0gU2F0KQpzdW5Ib2wgPSBhY3R1YWwgfD4gZmlsdGVyKGQgPT4gd2Vla2RheShkKSA9PSBTdW4pCihhY3R1YWwgXCAoc2F0SG9sIHwgc3VuSG9sKSkgfCAoc2F0SG9sIHw-IHNoaWZ0KC0xLCB1bml0OiBkYXkpKSB8IChzdW5Ib2wgfD4gc2hpZnQoKzEsIHVuaXQ6IGRheSkpCg&amp;amp;f=2026-01-01&amp;amp;t=2027-12-31&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;Deriving the &lt;em&gt;observed&lt;/em&gt; federal holidays from the statutory dates alone&lt;/a&gt; — July 4, 2026 lands on a Saturday; the expression yields July 3. No lookup table of observed dates anywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's different from a date library
&lt;/h2&gt;

&lt;p&gt;Temporal, date-fns, dateutil are arithmetic over &lt;em&gt;points and durations&lt;/em&gt;. Kairos is one layer&lt;br&gt;
up: it defines and governs &lt;strong&gt;sets of instants&lt;/strong&gt; (streams).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calendars are user-defined.&lt;/strong&gt; The Gregorian calendar itself is a transparent stdlib written
in Kairos. Fiscal calendars (4-4-5 included), trading calendars, and the Japanese lunisolar
calendar are ordinary definitions, not built-ins. Derivation rules — like the observed-holiday
expression above, or Japan's substitute-holiday law — live in the definition, not in a
pre-expanded table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A definition denotes a set of instants.&lt;/strong&gt; Evaluation is a pure function — missed fires
during downtime are enumerable, audits are reproducible. This has now survived a summer of
production use by an independent implementation (schedule predictions stable across 10
hostnames and a local→VPS migration).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When calendar data runs out, the results say so&lt;/strong&gt; — machine-readable annotations
(&lt;code&gt;covering&lt;/code&gt; / freshness) instead of silent degradation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mistakes are static errors&lt;/strong&gt; with fix-it guidance: mixing civil-day and elapsed-hour
widths, undeclared timezones or week starts, misaligned streams, unknown named arguments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What 1.0 means
&lt;/h2&gt;

&lt;p&gt;The language is frozen: semantics, the operator family, the grammar (EBNF), and the lexis.&lt;br&gt;
Definitions that parse today keep their meaning. The reference implementation stays honest&lt;br&gt;
about what it is — a prototype (TypeScript, zero runtime deps; 638 tests including doctests:&lt;br&gt;
every example in the docs is executed in CI).&lt;/p&gt;

&lt;p&gt;The documentation is &lt;strong&gt;canonical in Japanese&lt;/strong&gt; — I develop documentation-first in my native&lt;br&gt;
language — with a full English mirror of the spec, operator reference, and stdlib guides.&lt;br&gt;
Evaluator error messages are currently Japanese (the CLI's &lt;code&gt;--json&lt;/code&gt; output is language-neutral).&lt;br&gt;
Apache-2.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/azathothx/kairos-lang" rel="noopener noreferrer"&gt;https://github.com/azathothx/kairos-lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Recipes — schedules cron and RRULE can't express: &lt;a href="https://kairos-lang.org/en/recipes/" rel="noopener noreferrer"&gt;https://kairos-lang.org/en/recipes/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;English spec: &lt;a href="https://kairos-lang.org/en/spec/" rel="noopener noreferrer"&gt;https://kairos-lang.org/en/spec/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install: &lt;code&gt;npm i -g kairos-lang&lt;/code&gt; → &lt;code&gt;kairos next -n 3 payday.kairos&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd love feedback — especially schedules you've needed that didn't fit existing tools. Issues&lt;br&gt;
in English are welcome.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure (AI-assisted): the English text of this post was drafted with an LLM from my Japanese originals and reviewed by me before publishing. Every code example and its output was executed by the reference implementation; the numbers are measured, not written.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>scheduling</category>
      <category>dsl</category>
    </item>
    <item>
      <title>"One day later" and "24 hours later" are different quantities — the batch job that drifts an hour every spring</title>
      <dc:creator>azathothx</dc:creator>
      <pubDate>Tue, 18 Aug 2026 12:03:09 +0000</pubDate>
      <link>https://dev.to/azathothx/one-day-later-and-24-hours-later-are-different-quantities-the-batch-job-that-drifts-an-hour-184i</link>
      <guid>https://dev.to/azathothx/one-day-later-and-24-hours-later-are-different-quantities-the-batch-job-that-drifts-an-hour-184i</guid>
      <description>&lt;h2&gt;
  
  
  The code didn't change. The schedule did.
&lt;/h2&gt;

&lt;p&gt;There's a batch job on a US East Coast server that runs every morning at 9:00. It has been&lt;br&gt;
running fine for months — until the second Sunday of March, when it quietly starts running&lt;br&gt;
at 10:00 every morning. Nobody deployed anything.&lt;/p&gt;

&lt;p&gt;The cause usually looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;next = prev + 24 * 60 * 60 * 1000;   // "one day later"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The US East Coast switches to daylight saving time at 02:00 on the second Sunday of March.&lt;br&gt;
The clock jumps forward one hour, so &lt;strong&gt;that civil day is only 23 hours long&lt;/strong&gt;. "Previous&lt;br&gt;
time + 86,400 seconds" is physically exactly 24 hours later — but read on a wall clock,&lt;br&gt;
it's an hour off. And it stays off until the clocks fall back in November.&lt;/p&gt;

&lt;p&gt;The interesting part is not how to fix the bug. It's the fact that &lt;strong&gt;the phrase "one day"&lt;br&gt;
names two different quantities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A civil day&lt;/strong&gt; — one square on the calendar. It sticks to the wall clock, and on a
transition day it is 23 or 25 hours long.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;24 elapsed hours&lt;/strong&gt; — 86,400 physical seconds, regardless of what the wall clock does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are legitimate readings of "one day"; which one you want depends on the requirement.&lt;br&gt;
A daily 9:00 report wants the former. "Inspect the equipment every 24 hours of runtime"&lt;br&gt;
wants the latter. The accident starts the moment your code holds both in &lt;strong&gt;the same type&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  In Kairos, they are different literals
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/azathothx/kairos-lang" rel="noopener noreferrer"&gt;Kairos&lt;/a&gt; is a schedule definition language I've&lt;br&gt;
been writing about (in Japanese) for a while. It separates the two quantities at the level&lt;br&gt;
of &lt;em&gt;width literals&lt;/em&gt;: &lt;code&gt;1d&lt;/code&gt; is a civil day, &lt;code&gt;24h&lt;/code&gt; is elapsed time. Here is "every day from&lt;br&gt;
9:00" written both ways, evaluated across the 2026 spring-forward date (March 8) in&lt;br&gt;
&lt;code&gt;America/New_York&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;premise NY {
  calendar-system: Gregorian
  tz: "America/New_York"
  wkst: Mon
}

@NY
everyInstant |&amp;gt; strideBy(1d, from: 2026-03-06T09:00)
everyInstant |&amp;gt; strideBy(24h, from: 2026-03-06T09:00)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# expression 1 (4 points)
2026-03-06T09:00
2026-03-07T09:00
2026-03-08T09:00
2026-03-09T09:00
# expression 2 (4 points)
2026-03-06T09:00
2026-03-07T09:00
2026-03-08T10:00
2026-03-09T10:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBOWSB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogTW9uCn0KCkBOWQpldmVyeUluc3RhbnQgfD4gc3RyaWRlQnkoMWQsIGZyb206IDIwMjYtMDMtMDZUMDk6MDApCmV2ZXJ5SW5zdGFudCB8PiBzdHJpZGVCeSgyNGgsIGZyb206IDIwMjYtMDMtMDZUMDk6MDAp&amp;amp;f=2026-03-06&amp;amp;t=2026-03-10&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;▶ Open in Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Expression 1 (&lt;code&gt;1d&lt;/code&gt;) sticks to 09:00 every day. Expression 2 (&lt;code&gt;24h&lt;/code&gt;) drifts to 10:00 on&lt;br&gt;
the transition day — and &lt;strong&gt;stays there&lt;/strong&gt;. That's the batch job from the opening,&lt;br&gt;
reproduced. Neither expression is wrong: &lt;strong&gt;they are different questions&lt;/strong&gt;, and the&lt;br&gt;
language returns different answers.&lt;/p&gt;

&lt;p&gt;And if you try to write a width that mixes the two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;字句エラー(8:26): 市民時と経過時間の幅は混合できない: 1d12h（ADR-28）
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;— a lexical error: &lt;em&gt;"civil-time and elapsed-time widths cannot be mixed: &lt;code&gt;1d12h&lt;/code&gt;"&lt;/em&gt;.&lt;br&gt;
It is rejected &lt;strong&gt;at parse time&lt;/strong&gt;. "One day and twelve hours" is a quantity whose length&lt;br&gt;
is undefined until you know how the civil day stretches; if you could write it, its&lt;br&gt;
behavior on transition days would be implementation-defined. So you can't write it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing a time that doesn't exist
&lt;/h2&gt;

&lt;p&gt;A transition day also has a wall-clock hole: 02:00–03:00 never happens that morning.&lt;br&gt;
Write 02:30 of that day as &lt;em&gt;data&lt;/em&gt; — a named, literal time — and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = [2026-03-08T02:30] covering: 2026..2026
x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;存在しない時刻: 2026-03-08T02:30（tz "America/New_York" の DST の隙間に落ちる——実在の壁時計で書く。ADR-33）
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;— &lt;em&gt;"nonexistent time: 2026-03-08T02:30 (falls into the DST gap of tz "America/New_York" —&lt;br&gt;
write a wall-clock time that exists)"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kairos-lang.org/en/playground/#s=cHJlbWlzZSBOWSB7CiAgY2FsZW5kYXItc3lzdGVtOiBHcmVnb3JpYW4KICB0ejogIkFtZXJpY2EvTmV3X1lvcmsiCiAgd2tzdDogTW9uCn0KCkBOWQp4ID0gWzIwMjYtMDMtMDhUMDI6MzBdIGNvdmVyaW5nOiAyMDI2Li4yMDI2Cng&amp;amp;f=2026-03-06&amp;amp;t=2026-03-10&amp;amp;z=America%2FNew_York" rel="noopener noreferrer"&gt;▶ Open in Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No silent forward-shift to 03:30, no silent drop. &lt;strong&gt;You named a specific wall-clock time;&lt;br&gt;
that time doesn't exist; therefore your data is wrong&lt;/strong&gt; — and the language says so.&lt;br&gt;
Contrast this with points that are &lt;em&gt;derived&lt;/em&gt; by evaluation (say, a "daily at 02:30" rule&lt;br&gt;
hitting the transition day): those resolve deterministically to "the first instant after&lt;br&gt;
the gap", by convention. &lt;strong&gt;Named times are strict; derived times follow conventions.&lt;/strong&gt;&lt;br&gt;
Nothing you didn't write ever runs; nothing you did write is silently rewritten.&lt;/p&gt;

&lt;h2&gt;
  
  
  "We don't have DST here"
&lt;/h2&gt;

&lt;p&gt;Half true. Japan (where I live) hasn't had DST since 1951; our civil days are always&lt;br&gt;
24 hours. But "the server is on UTC, the business runs on Tokyo mornings" is an everyday&lt;br&gt;
setup, and inside it someone is doing the civil-day ↔ elapsed-time conversion — every&lt;br&gt;
single day. A cron line &lt;code&gt;0 9 * * *&lt;/code&gt; means "9:00 &lt;em&gt;wherever the server is&lt;/em&gt;", and its meaning&lt;br&gt;
changes the day you migrate the box. Same species of bug: not "which quantity", but&lt;br&gt;
&lt;strong&gt;"whose wall clock"&lt;/strong&gt; left unstated.&lt;/p&gt;

&lt;p&gt;That's why a Kairos premise &lt;strong&gt;requires&lt;/strong&gt; the timezone declaration (&lt;code&gt;tz: "America/New_York"&lt;/code&gt;&lt;br&gt;
above): no schedule definition can be written without saying whose wall clock it reads.&lt;br&gt;
Move the server; the definition means what it always meant.&lt;/p&gt;

&lt;p&gt;cron's minefield — I've written before about what &lt;code&gt;0 9 13 * 5&lt;/code&gt; actually does — is rarely&lt;br&gt;
a lack of power. It's &lt;strong&gt;polysemy&lt;/strong&gt;: "one day" that names two quantities, "9:00" that&lt;br&gt;
doesn't say whose. What a language can do is split the ambiguous words into distinct&lt;br&gt;
spellings, and make the confusion &lt;em&gt;unwritable&lt;/em&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Kairos is a schedule definition language in RC, developed documentation-first: the spec,&lt;br&gt;
operator reference, and stdlib guides are canonical in Japanese with a full&lt;br&gt;
&lt;a href="https://github.com/azathothx/kairos-lang/tree/main/en/spec" rel="noopener noreferrer"&gt;English mirror&lt;/a&gt;, and every&lt;br&gt;
example in the docs is executed and verified against the reference implementation in CI.&lt;br&gt;
The &lt;a href="https://kairos-lang.org/en/playground/" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; runs that same reference&lt;br&gt;
implementation in your browser (nothing leaves the page); evaluator error messages are the&lt;br&gt;
implementation's canonical Japanese, as you saw above — the English spec defines their exact&lt;br&gt;
semantics. If you came for the "schedules cron and RRULE can't express" angle, the&lt;br&gt;
&lt;a href="https://kairos-lang.org/en/recipes/" rel="noopener noreferrer"&gt;recipes&lt;/a&gt; walk the greatest hits — last business day&lt;br&gt;
of the month, Easter as pure arithmetic, the 4-4-5 fiscal calendar — one page per&lt;br&gt;
requirement, each with a runnable Playground link.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure (AI-assisted): the English text of this post was drafted with an LLM from my Japanese originals and reviewed by me before publishing. Every code example and its output was executed by the reference implementation; the numbers are measured, not written.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>scheduling</category>
      <category>timezone</category>
      <category>dst</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
