Can a 30 year old 8 bit computing platform determine the day name for days past Y2K (year 2000) in BASIC? Sure, with a few lines of code! As it turns out it was actually very easy to do.
I know plenty about determining leap years, calculating date differences, manipulating dates, validating dates and finding years with compatible days. However I was unsure how to determine the actual day name of any given day in the calendar year. Wikipedia came to the rescue with several formulas on this page: http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week
Using the first (table) method on the Wikipedia site I was able to create a simple BASIC program to correctly compute the day name for any date in the 21st century (2001-2100). More correctly this program works with dates from 2000 to 2099, so I’ll refer to it as the 2000’s.
Formula
The formula is: (d + m + y + (y / 4) + c ) mod 7
where:
- d = day number
- m = corresponding month number. This is a magic number so to speak and not the actual month number. It represents a grouping of corresponding months, which are months that start on the same day. Note that January and February have different values on leap years.
- y = last two digits of year (i.e.: 14 of 2014)
- c = century number. This is one of 6, 4, 2, or 0. It’s 6 if the first two digits of the year are evenly divisible by 4. Then each century after follows in 4, 2, 0 order.
The result is a number from 0 to 6 which represents the day of the week starting with Sunday (0) and ending on Saturday (6).
Rather than list all the tables, please refer to the Wikipedia entry. They are listed in the first section which is the tabular method.
Source
Here is the program source. A break down will follow:
6 DIM LT(12),DN$(10),D$(6) 8 M=0:D=0:Y=0 10 REM 11 REM *** GET DATE FROM USER *** 20 ? "Enter Date (mmddyy):";:INPUT D$ 50 REM 51 REM *** GET MONTH *** 60 M=VAL(D$(1,2)) 100 REM 101 REM *** GET DAY *** 110 D=VAL(D$(3,4)) 150 REM 151 REM *** GET YEAR *** 160 Y=VAL(D$(5,6)) 200 REM 201 REM *** LOAD MONTH TABLE *** 210 RESTORE 510 220 FOR I=1 TO 12:READ X:LT(I)=X:NEXT I 250 REM 251 REM *** CALCULATE *** 260 A=INT(Y/4) 265 L=Y-(INT(Y/4)*4) 270 MA=LT(M) 275 IF L=0 AND M=1 THEN MA=6 280 IF L=0 AND M=2 THEN MA=2 285 C=D+MA+Y+A+6 290 DW=C-(INT(C/7)*7) 300 REM 301 REM *** FIND DAY NAME *** 310 RESTORE 530 320 FOR I=0 TO DW:READ DN$:NEXT I 350 REM 351 REM *** PRINT RESULT *** 360 ? "Day Number: ";DW 370 ? " Day Name: ";DN$ 499 END 500 REM *** MONTH TABLE *** 510 DATA 0,3,3,6,1,4,6,2,5,0,3,5 520 REM *** DAY NAME TABLE *** 530 DATA Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
Breakdown
- Line 6: Reserve space for the strings we need
- Line 8: Initialize month, day and year variables to 0
- Lines 10-20: Print date prompt and get a string (D$) from the user, hopefully in MMDDYY format
- Lines 50-60: Pick characters 1 and 2 from the input string (D$) and convert to an integer value storing the value in the month variable M
- Lines 100-110: Pick characters 3 and 4 from the input string (D$) and convert to an integer value storing the value in day variable D
- Lines 150-160: Pick characters 5 and 6 from the input string (D$) and convert to an integer value storing the value in year variable Y
- Lines 200-220: Load the corresponding month table into an array for easy reference
- Line 210: Set the data read location used by BASIC to the data statement on line 510
- Line 220: Read each months corresponding month value and store it in the month lookup table array (LT)
- Lines 250-290: Calculate the day number using the formula
- Line 260: Compute the y / 4 portion of the formula and store the result in variable A
- Line 265: Determine if year is leap year by computing the equivalent of y mod 4 and store the result in variable L. Take the integer portion of the year divided by 4, then multiply it by 4, then subtract the result from the year. If the result is 0 the year was evenly divisible by 4, and is a leap year.
- Line 270: Get the month adjustment (corresponding month value) from the month lookup table array (LT) for the user month (M) and store the value in variable MA
- Line 275: If year is a leap year (L=0) and user month (M) is 1 (January), set the month adjustment (corresponding month value) variable (MA) to 6
- Line 280: If year is a leap year (L=0) and user month (M) is 2 (February), set the month adjustment (corresponding month value) variable (MA) to 2
- Line 285: Perform the computation of the formula except the mod 7 part using the calculated variables and store the result in variable C
- Line 290: Perform the computation of the mod 7 part of the formula on variable C. Take the integer portion of variable C divided by 7, then multiply it by 7, then subtract the result from variable C and store the result in day of week variable DW. The result is the day number of the week starting with Sunday (0) and ending with Saturday (6).
- Lines 300-320: Find the day name based on the value of the day of week variable (DW)
- Line 310: Set the data read location used by BASIC to the data statement on line 530
- Line 320: Read each days name value in a loop and store it in the day name string variable (DN$) until the loop hits the value of the day of week value DW. At completion DN$ will be defined as the day name that corresponds to the day number.
- Line 350-370: Print the result to the screen
- Line 360: Print the day of week variable (DW) value, just for reference.
- Line 370: Print the day name string variable (DN$)
- Line 499: End the program
- Line 510: Corresponding month values for months 1 to 12
- Line 530: Day name strings for days 0 to 6
Results
The results displayed here are accurate. They can be validated at the Time And Date website located here: http://www.timeanddate.com/calendar/?year=2014&country=1
In the first example I run the program using the current date in 2014:
Then I run it for March 1 of next year (2015):
Then I run it for the leap day in 2016 which is a leap year, and a date in 2017:
They all check out!
Pingback: S1E7 APX Weekly Planner | Inverse ATASCII