Printable month calendar, worked out for the page
Works out how a month actually falls on a sheet of paper: how many week rows the grid needs, which column the 1st lands in, how large every day box comes out at that row count, and the ISO week number against each date. Month and weekday names come from your browser's own locale data, and every figure is computed in this tab.
The calendar
Vector, dimensioned in millimetres, so every box prints at exactly the size quoted above. Print it from here to skip the page furniture, or save it and open it in anything.
Every day, and where it lands
| 1 | Sunday | 1 | 7 | 5 | 2026-02-01 |
| 2 | Monday | 2 | 1 | 6 | 2026-02-02 |
| 3 | Tuesday | 2 | 2 | 6 | 2026-02-03 |
| 4 | Wednesday | 2 | 3 | 6 | 2026-02-04 |
| 5 | Thursday | 2 | 4 | 6 | 2026-02-05 |
| 6 | Friday | 2 | 5 | 6 | 2026-02-06 |
| 7 | Saturday | 2 | 6 | 6 | 2026-02-07 |
| 8 | Sunday | 2 | 7 | 6 | 2026-02-08 |
| 9 | Monday | 3 | 1 | 7 | 2026-02-09 |
| 10 | Tuesday | 3 | 2 | 7 | 2026-02-10 |
| 11 | Wednesday | 3 | 3 | 7 | 2026-02-11 |
| 12 | Thursday | 3 | 4 | 7 | 2026-02-12 |
| 13 | Friday | 3 | 5 | 7 | 2026-02-13 |
| 14 | Saturday | 3 | 6 | 7 | 2026-02-14 |
| 15 | Sunday | 3 | 7 | 7 | 2026-02-15 |
| 16 | Monday | 4 | 1 | 8 | 2026-02-16 |
How it works
What this works out
A month calendar looks like a fixed thing and is not. The same sheet of paper, the same margins and the same month can come out as four rows or as six, depending only on which day the 1st happens to fall on and which day you decide the week starts on. That row count then decides how tall every day box is, which is the difference between a calendar you can write in and one you cannot.
This works the whole layout out before any of it reaches a printer: how many rows the grid needs, which column the 1st sits in, how many blank cells sit either side of the month, how large each box comes out at that row count, and the ISO week number against every date.
The method
Two numbers decide everything. The first is how many blank cells precede the 1st, which is the distance from the opening column round to the weekday the month begins on. The second is the length of the month. Add them and you have the number of cells the grid must hold; divide by seven and round up and you have the rows.
That is why a 28-day February — four weeks exactly — so often still needs five rows. February 2026 begins on a Sunday, and a grid whose first column is Monday has to leave six cells blank before it can put the 1st down. Six blanks plus 28 days is 34 cells, which does not fit in 35 with any room to spare but does not fit in 28 either. Move the first column to Sunday and the blanks vanish, the month fits in four rows, and every box on the sheet grows a quarter taller.
No Date object is used for any of the date arithmetic, which is a deliberate
choice rather than a preference. Date is a local-timezone object, and the
standard way of walking a calendar with it — mutating a date by setDate in a
loop — is how off-by-one-day calendar bugs get written, because a machine west
of Greenwich renders the instant on the previous day. The weekday and the ISO
week number here come instead from Howard Hinnant’s days_from_civil, which is
exact integer arithmetic over the proleptic Gregorian calendar with no leap-year
branch in it at all: shifting the year to begin in March puts February, the only
irregular month, at the end where its extra day disturbs nothing after it. A
Date appears in exactly one place, as the argument Intl.DateTimeFormat needs
to produce a name, and every formatter here is pinned to UTC so the machine’s
own timezone cannot move a name onto the wrong day.
ISO week numbers deserve their own note, because the definition is not the intuitive one. Weeks run Monday to Sunday, and week 1 is the week containing the year’s first Thursday — so a week belongs to whichever calendar year holds its Thursday, and a date near either end of December or January can carry a number from the neighbouring year. Those weeks are not counted twice, which is the whole point of the rule, but it does mean the week number against 1 January is often 52 or 53 rather than 1. They are also unaffected by the first-column setting: ISO weeks are Monday-based by definition, so a Sunday-start grid shows week numbers whose weeks began a day before each row does.
The page geometry is the straightforward part. The printable area is the sheet less twice the margin, less the space reserved above the grid for the heading and the weekday labels. Divide the width by seven columns — eight if the week-number column is on — and the remaining height by the number of rows. Every length is held as a whole number of micrometres until that final division, so subtracting a margin twice cannot leave a floating-point residue behind.
Before you read on
February 2026 has exactly 28 days — four weeks to the day. How many rows does a grid whose first column is Monday need?
Five. February 2026 begins on a Sunday, so a Monday-first grid has to leave six cells blank before it can put the 1st down: 6 + 28 = 34 cells, which needs five rows of seven. Move the first column to Sunday and the blanks vanish, the month fits in four rows, and every box on the sheet grows from 32.80 mm to 41.00 mm tall — a quarter taller, on identical paper, from one control that looks like a preference.
blanks = (0 for Sunday - 1 for Monday + 7) mod 7 = 6The distance from the opening column round to the weekday the month begins on. The + 7 is there so the modulo never sees a negative.
cells = 6 + 28 = 34Blanks plus the length of the month. This is the only place the two numbers meet.
rows = ceil(34 / 7) = 5And one cell left blank after the 28th, since 5 x 7 is 35.
box height = (210 - 24 - 22) / 5 = 32.80 mmA4 landscape less twice a 12 mm margin, less 22 mm reserved above the grid, divided by the rows. Everything is held in whole micrometres until this division.
A worked example
February 2026, week starting Monday, names in English (United Kingdom), A4 landscape, a 12 mm margin, and 22 mm reserved above the grid:
heading February 2026
the 1st falls on Sunday, in column 7
days 28
blank cells 6 before, 1 after
rows 5
printable area 273.00 x 186.00 mm
grid area 273.00 x 164.00 mm (186 less the 22 mm heading)
day box 39.00 x 32.80 mm
ISO weeks 5 through 9
The arithmetic checks by hand in both directions:
| Figure | Arithmetic | Result |
|---|---|---|
| Blank cells before the 1st | (0 for Sunday − 1 for Monday + 7) mod 7 | 6 |
| Cells in the grid | 6 + 28 | 34 |
| Rows | ceil(34 ÷ 7) | 5 |
| Blank cells after the 28th | 5 × 7 − 34 | 1 |
| Box width | (297 − 24) ÷ 7 | 39.00 mm |
| Box height | (210 − 24 − 22) ÷ 5 | 32.80 mm |
Both divisions come out exact here, which is a coincidence of A4 and these margins rather than anything the tool arranges.
Change one control and the sheet changes shape. With the week starting on Sunday instead, the same month has no leading blanks, fits in four rows, and the box height goes from 32.80 mm to 41.00 mm — a quarter taller, on identical paper. August 2026 is the case in the other direction: 31 days beginning on a Saturday is five blanks plus 31, which is 36 cells and six rows, and the boxes come down to 27.33 mm.
These are the same numbers asserted in this tool’s test file, so if the formula
ever changes without this page changing with it, the build fails. The weekday
and ISO week arithmetic is checked there a second way as well, against separate
Date-based implementations, on every month from 1600 to 2400 and on every
single day of every month across a full leap cycle.
What it does not do
It does not draw the calendar. It gives you the geometry and the complete date table — every day with its row, its column, its weekday name and its ISO week number — which downloads as a CSV, and that is enough to lay the sheet out exactly in a drawing program, a spreadsheet or a stylesheet. It is not a ready-made page to send to a printer.
It also models one calendar and not the many things people put on one. There are no public holidays, no moon phases, no week-of-month numbering, no leading or trailing days from the neighbouring months greyed into the blank cells, and no provision for the narrower weekend or week-number columns that a printed calendar often uses. Every box is the same size, which is the one layout that can be stated exactly rather than by a convention nobody agrees on.
And it knows nothing about your printer. The paper sizes are trimmed sizes, so the hardware border a desktop printer physically cannot reach is not deducted, and neither is the scaling a print dialogue applies unless you turn it off. Both of those live on the far side of this page, and both will quietly make the printed sheet disagree with every millimetre above.
It also counts nothing for you. For the number of working days in a span, rather than a grid to write them into, that is arithmetic on two dates and not a layout problem.
The formula
daysInMonth = 29 for February in a leap year, 28 otherwise
30 for April, June, September, November
31 for the rest
leap year = year mod 4 = 0 and (year mod 100 != 0 or year mod 400 = 0)
firstColumn = 0 for a Sunday start, 1 for Monday, 6 for Saturday
weekdays indexed Sunday = 0 … Saturday = 6
leadingBlanks = (weekdayOfThe1st - firstColumn + 7) mod 7
cells = leadingBlanks + daysInMonth
rows = ceil(cells / 7)
trailingBlanks = rows x 7 - cells
for the dth day:
offset = leadingBlanks + d - 1
row = floor(offset / 7) + 1
column = (offset mod 7) + 1
ISO 8601 weeks run Monday to Sunday, and week 1 is the week holding the
year's first Thursday:
isoWeekday = 1 for Monday … 7 for Sunday
thursday = dayNumber + (4 - isoWeekday)
weekYear = the calendar year that thursday falls in
isoWeek = floor((thursday - 1 January of weekYear) / 7) + 1
columns = 8 when a week-number column is shown, otherwise 7
boxWidth = (pageWidth - 2 x margin) / columns
boxHeight = (pageHeight - 2 x margin - headingSpace) / rows
Every length is held as a whole number of micrometres up to that last
division. Every day number is integer arithmetic throughout.
What it assumes
- Dates are computed in the proleptic Gregorian calendar for every year from 1583 onwards, which is why that is the earliest year offered. Britain and its colonies kept the Julian calendar until September 1752, so for a month before then this tool disagrees with the calendar people were actually using at the time — by ten days in 1583 and by eleven by 1752.
- The day the week starts on is chosen explicitly rather than inferred from the language. CLDR does record a first day per territory, but it is keyed on region and not on language, so "French" alone does not answer the question — and the setting changes the row count, which makes guessing it wrong more than a cosmetic error.
- ISO week numbers always count Monday-to-Sunday weeks, whatever day the grid starts on. A Sunday-start calendar therefore shows, against its first row, a week number for a week that began the day before that row does.
- Every column is the same width and every row the same height, including the week-number column when it is switched on. Printed calendars often narrow the week-number column or the weekend, and none of those conventions is standard enough to compute from.
- Paper sizes are trimmed sizes. Your printer's own hardware border, usually 4 to 6 mm and often wider at the trailing edge, is not deducted, so a margin below about 5 mm will be clipped by the printer rather than by anything here.
- Month and weekday names come from the locale data built into the browser reading this page. A cut-down build of that data, which a few embedded and self-compiled runtimes ship, falls back to English without saying so.
Common questions
Why does my calendar sometimes need six rows?
Because the grid has to hold the blank cells before the 1st as well as the days themselves, and once that total passes 35 it spills into a sixth row. Only a 31-day month starting in the sixth or seventh column, or a 30-day month starting in the seventh, can manage it. It happens two or three times in most years, and those sheets look visibly different from the rest because every box loses about a sixth of its height.
Should the week start on Monday or Sunday?
It is a regional convention rather than a correct answer. Monday is the norm across most of Europe and is what ISO 8601 week numbering assumes; Sunday is the norm in the United States, Canada and Japan; Saturday is usual across much of the Middle East. What matters for printing is that the choice moves every date one column and can add or remove a whole row: February 2026 is five rows starting on Monday and four starting on Sunday.
Why is the week number in early January 52 or 53?
Because ISO 8601 numbers weeks, not days, and a week belongs to whichever year holds its Thursday. 1 January 2027 is a Friday, so the week it sits in began on Monday 28 December 2026 and is therefore week 53 of 2026, not week 1 of 2027. The same rule runs the other way: 29 December 2025 is a Monday, so the last three days of 2025 are already week 1 of 2026.
Is my calendar uploaded anywhere?
No. The arithmetic runs in this browser tab and there is no server to send it to. The month and weekday names come from locale data that is already part of your browser, so nothing is fetched to produce them either.
Does this draw the calendar?
Not yet. It gives you the full layout — the row count, the box sizes to the hundredth of a millimetre, and a table of every date with the row, column and ISO week it belongs to, which downloads as CSV. That is enough to build the sheet in a drawing program, a spreadsheet or a stylesheet, but it is not a finished page you can send straight to a printer.
Why does the printed sheet measure smaller than the figures here?
Almost always because it was scaled. Print dialogues default to fitting the page to the printable area, which shrinks everything by two or three per cent. Set the scale to 100%, or "Actual size", and turn off "fit to page". Laying a ruler across all seven columns is the quickest check: on A4 landscape with a 12 mm margin they should measure 273 mm in total.