--- title: "Calendar" id: 71173 type: "computer_media" slug: "calendar-5" url: "http://localhost/computer_media/calendar-5/" markdown_url: "http://localhost/computer_media/calendar-5.md" published_at: "2026-08-31T08:04:29+00:00" modified_at: "2026-08-31T08:04:30+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/calendar.png" alt: "Calendar screen" excerpt: "Calculate which day of the week any historical date fell on — this calendar program covers any month and year with full leap-year support." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Calendar" slug: "calendar" taxonomy: "genre" url: "http://localhost/type/calendar/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Calendar%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/calendar.png" alt: "Calendar screen" media_type_tags: "Calendar" --- # Calendar This program prints a calendar for any user-specified month and year, calculating the correct starting day of the week using Zeller’s congruence-style formula. It handles leap years with a three-condition check: divisible by 4 but not 100 (line 270), or divisible by 400 (line 280). Month names are stored in a 12-by-9 character array, and the 42-element numeric array A() maps days across a six-week grid of seven columns. The display uses TAB-based column positioning at four-character intervals to align the SUN through SAT header with the day numbers below it. *** ### Program Structure The program is organized into four logical phases: 1. **Input** (lines 5–40): Clear screen, set border, prompt for month and year. 2. **Setup** (lines 60–210): Initialize variables and populate the month-name string array. 3. **Calculation** (lines 220–380): Determine the number of days in the month, compute the starting day of the week, and fill the day-number grid array. 4. **Display & Loop** (lines 390–590): Render the calendar, then offer a repeat prompt. ### Month and Day Storage Line 90 declares `A$(12,9)`, a two-dimensional string array with 12 rows of 9 characters — exactly enough to hold the longest month name, “SEPTEMBER”. Each month name is padded with trailing spaces so all entries are exactly 9 characters wide, making indexed access uniform. A separate numeric array `A(42)` (line 220) represents a six-week by seven-day grid; only positions from `START` to the last day are filled, leaving earlier slots at their default value of 0. ### Day-of-Week Calculation The core algorithm at lines 310–360 uses a variant of Zeller’s congruence. Lines 310–320 adjust January and February to be treated as months 13 and 14 of the previous year, a standard preprocessing step. Line 330 computes the raw remainder `R` using the formula: `R = D + 2*M + 2 + INT((3*M+3)/5) + INT(Y/4) + Y - INT(Y/100) + INT(Y/400)` Line 340 extracts the fractional part of `R/7` and multiplies by 7 to get a value in [0,7), and line 350 rounds it to the nearest integer with `INT(NUM+.5)`. Line 370 maps a result of 0 to 7, making Sunday position 1 through Saturday position 7 consistent with the SUN–SAT header printed at line 460. ### Leap Year Logic Three lines handle leap year detection: - Line 270: divisible by 4 but *not* by 100 → leap year - Line 280: divisible by 400 → leap year (overrides the century exclusion) - Line 300: if February and leap year, set `END=29` Note that line 270 uses the original `Y` value, but by the time it executes, `Y` may be modified by line 320 for January/February inputs. However, lines 260–300 execute *before* lines 310–320, so the leap-year check correctly uses the original year. ### Calendar Rendering Lines 470–560 iterate over six rows (`R=0` to `5`) and seven columns (`C`), using `TAB(4*CC)` to position each value at 4-character intervals aligned with the header ” SUN MON TUE WED THU FRI SAT”. Cells where `A(C)=0` (before the first day) or `A(C)>END` (after the last day) print a blank space instead of a number. The `GO TO 550` statements at lines 510 and 530 skip the day-printing step, acting as an early-continue since BASIC lacks a structured `CONTINUE` statement. ### Variable Naming and Reuse The program uses descriptive multi-character variable names: `MON`, `YEAR`, `LEAP`, `START`, `END`, `NUM`, `DAY`. Notably, `R` is reused as both the Zeller formula accumulator (line 330) and the outer loop variable for row iteration (line 470). This is safe because `R`‘s computed value is consumed before the display loop begins, but it reduces readability. ### Notable Anomalies - Line 250 sets `END=28` unconditionally for February before the leap year check at line 300 can correct it to 29 — this ordering is intentional and correct. - The `BORDER 1` call at line 6 sets the screen border color, relevant to color-capable configurations. - The `NEXT R` at line 560 reuses the loop variable `R` that was previously used for the day formula, which could cause confusion during manual tracing but causes no runtime error. - The display loop runs all six rows unconditionally, even if the month fits in five rows — the sixth row simply prints blanks for any cells where `A(C)>END`. - The REM at line 1 spells “CALENDER” rather than “CALENDAR”, though the program title uses the correct spelling. ## Source Code ``` 1 REM CALENDER 2 REM THIS PROGRAM WILL PRINT ANY MONTH IN ANY YEAR. 3 REM TRY TO FIND OUT WHAT DAY OF THE WEEK A FAMOUS HISTORICAL EVENT OCCURED 5 CLS 6 BORDER 1 10 PRINT "ENTER MONTH (1 TO 12)" 20 INPUT M 30 PRINT "ENTER YEAR" 40 INPUT Y 60 LET D=1 70 LET MON=M 80 LET YEAR=Y 90 DIM A$(12,9) 100 LET A$(1)="JANUARY " 110 LET A$(2)="FEBRUARY " 120 LET A$(3)="MARCH " 130 LET A$(4)="APRIL " 140 LET A$(5)="MAY " 150 LET A$(6)="JUNE " 160 LET A$(7)="JULY " 170 LET A$(8)="AUGUST " 180 LET A$(9)="SEPTEMBER" 190 LET A$(10)="OCTOBER " 200 LET A$(11)="NOVEMBER " 210 LET A$(12)="DECEMBER " 220 DIM A(42) 230 LET END=30 240 IF M=1 OR M=3 OR M=5 OR M=7 OR M=8 OR M=10 OR M=12 THEN LET END=31 250 IF M=2 THEN LET END=28 260 LET LEAP=0 270 IF Y/4= INT (Y/4) AND Y/100 <> INT (Y/100) THEN LET LEAP=1 280 IF Y/400= INT (Y/400) THEN LET LEAP=1 300 IF M=2 AND LEAP=1 THEN LET END=29 310 IF M=1 OR M=2 THEN LET M=M+12 320 IF M=13 OR M=14 THEN LET Y=Y-1 330 LET R=D+2*M+2+ INT ((3*M+3)/5)+ INT (Y/4)+Y- INT (Y/100)+ INT (Y/400) 340 LET NUM=(R/7- INT (R/7))*7 350 LET NUM= INT (NUM+.5) 360 LET START=NUM 370 IF NUM=0 THEN LET START=7 380 LET DAY=1 390 FOR P=START TO 42 400 LET A(P)=DAY 410 LET DAY=DAY+1 420 NEXT P 430 CLS 440 PRINT TAB 10;A$(MON);" ";YEAR 450 PRINT 460 PRINT " SUN MON TUE WED THU FRI SAT" 470 FOR R=0 TO 5 480 FOR C=1+R*7 TO 7+R*7 490 LET CC=C-R*7 500 IF A(C)=0 THEN PRINT TAB (4*CC);" "; 510 IF A(C)=0 THEN GO TO 550 520 IF A(C)>END THEN PRINT TAB (4*CC);" "; 530 IF A(C)>END THEN GO TO 550 540 PRINT TAB (4*CC);A(C); 550 NEXT C 560 NEXT R 570 PRINT AT 15,1;"WOULD YOU LIKE TO TRY AGAIN?(Y OR N)" 580 INPUT B$ 590 IF B$="Y" THEN GO TO 5 ```