<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Porchlight Ledger]]></title><description><![CDATA[Porchlight Ledger]]></description><link>https://porchlightledger.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 04 Nov 2026 19:51:40 GMT</lastBuildDate><atom:link href="https://porchlightledger.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Splitting date ranges across months in a spreadsheet, with no macros (a booking-ledger example)]]></title><description><![CDATA[Note: The Porchlight Ledger spreadsheet is no longer available; this guide is kept for reference. Written by Porchlight Ledger with AI assistance and…]]></description><link>https://porchlightledger.hashnode.dev/splitting-date-ranges-across-months-in-a-spreadsheet-with-no-macros-a-booking-ledger-example</link><guid isPermaLink="true">https://porchlightledger.hashnode.dev/splitting-date-ranges-across-months-in-a-spreadsheet-with-no-macros-a-booking-ledger-example</guid><category><![CDATA[spreadsheets]]></category><category><![CDATA[excel]]></category><category><![CDATA[#googlesheets]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Porchlight Ledger]]></dc:creator><pubDate>Mon, 26 Oct 2026 10:39:19 GMT</pubDate><content:encoded><![CDATA[<p>Note: The Porchlight Ledger spreadsheet is no longer available; this guide is kept for reference.</p>
<p><em>Written by Porchlight Ledger with AI assistance and checked by hand in Excel, Google Sheets and LibreOffice. Originally published on our site: Split bookings across months.</em></p>
<p>A lot of business data comes as date ranges: hotel or holiday-rental stays, subscriptions, rentals, project assignments. Reports, though, are usually monthly. If a stay runs from 29 March to 3 April and you book the whole thing in March, March looks too good and April too weak.</p>
<p>This post shows the formula we use to split a range across months by days (or nights), and the edge cases that tend to break it.</p>
<h2>The core formula: overlap of two intervals</h2>
<p>Treat each booking as a half-open interval <code>[start, end)</code>. For a hotel-style stay, <code>end</code> is the check-out date, so the night of the 31st belongs to the 31st.</p>
<p>For a month that runs from <code>month_start</code> to <code>month_end</code> (the last day), the number of nights that fall in the month is the overlap of the two intervals:</p>
<pre><code class="language-plaintext">nights_in_month = MAX(0, MIN(end, month_end + 1) - MAX(start, month_start))
</code></pre>
<p>With check-in in <code>B2</code>, check-out in <code>C2</code>, and the first and last day of the month in <code>F$1</code> and <code>G$1</code>:</p>
<pre><code class="language-plaintext">=MAX(0, MIN($C2, G$1 + 1) - MAX($B2, F$1))
</code></pre>
<p>That is the whole trick. It works unchanged in Excel 2016+, Google Sheets and LibreOffice Calc because dates are just serial numbers, so subtracting them gives a day count.</p>
<p>For the 29 March to 3 April stay: March gives <code>MIN(3 Apr, 1 Apr) - MAX(29 Mar, 1 Mar) = 3</code> nights, April gives <code>MIN(3 Apr, 1 May) - MAX(29 Mar, 1 Apr) = 2</code> nights. Total 5, which matches <code>C2 - B2</code>.</p>
<h2>Allocating money by the same share</h2>
<p>Once you have nights per month, every amount on the row can be split the same way:</p>
<pre><code class="language-plaintext">share_in_month = nights_in_month / (end - start)
revenue_in_month = gross * share_in_month
</code></pre>
<p>Apply the same share to fees and pass-through taxes so each month's margin stays consistent.</p>
<p>For monthly totals, put one helper column per month next to the bookings (nights in that month), then multiply by the per-night amount and sum the column. You can squeeze it into a single array formula, but empty rows divide by zero and older Excel versions need it entered as an array formula, so the helper-column version is easier to audit. Readable beats clever in a file someone else has to trust.</p>
<h2>Edge cases that break naive versions</h2>
<ol>
<li><strong>Inclusive vs exclusive end.</strong> If your <code>end</code> is the last night rather than the check-out date, add 1 to it first. Mixing the two conventions is the most common off-by-one.</li>
<li><strong>Year boundaries.</strong> A stay from 30 December to 2 January must land partly in December of one year and January of the next. The formula handles it as long as your month header holds a real date (for example <code>2026-12-01</code>) rather than the text "Dec".</li>
<li><strong>Same-day ranges.</strong> <code>end - start = 0</code> means a division by zero in the share. Wrap it: <code>IF(C2 &gt; B2, nights / (C2 - B2), 0)</code>.</li>
<li><strong>Text dates from CSV imports.</strong> Exports often arrive as text (<code>"03/04/2026"</code>), which subtracts to <code>#VALUE!</code> or, worse, parses with day and month swapped. Convert explicitly with <code>DATE()</code> from the parts rather than trusting locale parsing.</li>
<li><strong>Leap years.</strong> Nothing to do: serial dates already know February has 29 days in 2028.</li>
</ol>
<h2>Per-event costs</h2>
<p>Some costs happen once per range, not per day (a cleaning after a stay, a setup fee on a subscription). Either split them by the same share, or assign them to the month in which they actually happen. Both are defensible; switching between them month to month makes your trend meaningless.</p>
<h2>Cash view vs report view</h2>
<p>The split is for reporting income and utilisation. Cash still arrives on the payout date. Keep a separate cash view that matches your bank statement, and don't try to make one table serve both.</p>
]]></content:encoded></item></channel></rss>