05-04-2022, 09:50 AM
Added one more feature, left justify...
So just remember "monospace" is needed to make the fonts fixed width, as well as to get the _FONTWIDTH function to return a value other than zero.
Pete
Code: (Select All)
OPTION _EXPLICIT
OPTION BASE 1
DIM AM_PM AS STRING ' This flag will be set to either "AM" or "PM"
DIM CurrentDate AS STRING ' Hold the entire date (Month / Day / Year) as a string
DIM CurrentTime AS STRING ' Hold the entire time (Hours / Minutes / Seconds) as a string
DIM Day AS INTEGER ' Day of the month (1-31) as a number
DIM DayOfWeek AS INTEGER ' Day of the week (1-7) as a number
DIM DayOfWeekString(7) AS STRING ' An array holding each day of the week as an English word
DIM DayString(31) AS STRING ' An array holding each day of the month (1-31) as a string
DIM Decade AS INTEGER ' The numerical value of the last 2 digits of the year
DIM font AS LONG
DIM fontpath AS STRING
DIM handle AS LONG
DIM Hour AS INTEGER ' Numerical value holding the current hour (0-23)
DIM HourString(12) AS STRING ' The current hour as an English word. Since we use AM / PM this holds only one through twelve.
DIM LeapYear AS INTEGER ' To to indicate if current year is a leap year. 1 = Leap Year, 0 = No Leap Year
DIM Minute AS INTEGER ' The current minute as a numeral from 0 to 59
DIM MinuteString(59) AS STRING ' An array hold minutes as English words from one to fifty-nine
DIM Month AS INTEGER ' The current month as a number from 1 to 12
DIM MonthString(12) AS STRING ' The current month as an English word (January, February, ... , November, December).
DIM MonthTable(12) AS INTEGER ' A table with an offset for each month used to calculate what day of the week it is (Monday, Tuesday, etc).
DIM OldSecond AS INTEGER ' A variable that is used to determine if the seconds have changed from the last time we checked
DIM Result1 AS INTEGER ' A temporary variable
DIM Result2 AS INTEGER ' A temporary variable
DIM Result3 AS INTEGER ' A temporary variable
DIM Second AS INTEGER ' The current seconds as a number (0-59)
DIM SecondString(59) AS STRING ' The current seconds as an English word from one through fifty-nine
DIM Temp AS INTEGER ' A temporary variable
DIM Temp2 AS INTEGER ' A temporary variable
DIM x AS INTEGER
DIM Year AS INTEGER
handle& = _NEWIMAGE(800, 600, 256)
SCREEN handle&
'handle& = _NEWIMAGE(_DESKTOPWIDTH, _DESKTOPHEIGHT, 256)
'SCREEN handle&
'_FullScreen
fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf" 'Find Windows Folder Path.
font& = _LOADFONT(fontpath$, 16, "MONOSPACE")
_FONT font&
' Read the spelled out version of various elements into arrays. This will save time later so that we don't have to constantly
' parse this over and over in out main program loop.
RESTORE DayOfWeek
FOR x = 1 TO 7
READ DayOfWeekString$(x)
NEXT x
RESTORE Day
FOR x = 1 TO 31
READ DayString$(x)
NEXT x
RESTORE Month
FOR x = 1 TO 12
READ MonthString$(x)
NEXT x
RESTORE Hour
FOR x = 1 TO 12
READ HourString$(x)
NEXT x
RESTORE Minute
FOR x = 1 TO 59
READ MinuteString$(x)
NEXT x
RESTORE Second
FOR x = 1 TO 59
READ SecondString$(x)
NEXT x
RESTORE MonthTable
FOR x = 1 TO 12
READ MonthTable(x)
NEXT x
CLS
' This is the main loop that retries the date and time, breaks it down into individual components, and then
' displays the time and date in words.
DO
_LIMIT 60 ' Limit the number of times that we perform this loop to a maximum of 60 iterations per second
CurrentDate$ = DATE$
CurrentTime$ = TIME$
Month = VAL(LEFT$(CurrentDate$, 2))
Day = VAL(MID$(CurrentDate$, 4, 3))
Year = VAL(RIGHT$(CurrentDate$, 4))
Decade = VAL(RIGHT$(CurrentDate$, 2))
Hour = VAL(LEFT$(CurrentTime$, 2))
Minute = VAL(MID$(CurrentTime$, 4, 2))
Second = VAL(RIGHT$(CurrentTime$, 2))
' At the end of the loop that displays the time on the screen, we set OldSecond to the current seconds. When we reach
' this point again, if the current seconds are still the same, we skip the display process since there are no changes.
' If the seconds have changed, then proceed with updating the display.
IF (OldSecond = Second) THEN GOTO DisplayFinished
' Calculate the day of the week
' IMPORTANT: The calculations below are valid through 2099.
' Step 1: Add the day of the month and the number from the month table. We will read the values from the month table.
Temp = Day + MonthTable(Month)
' Step 2: If the number calculated above is greater than 6, then subtract the highest multiple of 7 from this number.
IF Temp > 6 THEN
Temp2 = INT(Temp / 7)
Temp = Temp - (Temp2 * 7)
END IF
Result1 = Temp
' Step 3: From the last two digits of the year, subtract the year that has the highest multiple of 28.
Temp = Decade
IF Decade > 27 THEN
Temp2 = INT(Temp / 28)
Temp = Decade - (Temp2 * 28)
END IF
Result2 = Temp
' Step 4: Take the last 2 digits of the year, divide by 4, and drop anything after the decimal point. Add that value to Result2.
Temp = 0
IF Decade > 3 THEN
Temp = INT(Decade / 4)
END IF
Result3 = Result2 + Temp
' Step 5: If the month is Jan or Feb AND the year is a leap year, subtract 1 from Result3.
IF Month < 3 THEN
IF (Year / 4) = (INT(Year / 4)) THEN
LeapYear = 1
ELSE
LeapYear = 0
END IF
Result3 = Result3 - LeapYear
END IF
' Step 6: Add Result1 and Result3. Subtract the highest multiple of 7. The result will be 0-6 with 0 being Sat, and 6 being Fri.
Result3 = Result3 + Result1
IF Result3 > 6 THEN
Temp = INT(Result3 / 7)
Result3 = Result3 - (Temp * 7)
END IF
' To make handling easier, we will add 1 to result so that the day of the week will now be a number from 1 to 7. The
' end result is that Sat = 1, Fri = 7.
DayOfWeek = Result3 + 1
' End calculation of the day of the week.
' Set the default color of items printed to the screen to grey on black. Current values will be highlighted.
' Currently, this means white text on a red background, but we intend to allow customization later.
LOCATE 1, 1
COLOR 8, 0
' Print all days of the week
FOR x = 1 TO 7
IF x = DayOfWeek THEN
COLOR 15, 4: PRINT DayOfWeekString$(x);: COLOR 8, 0: IF POS(0) > 1 THEN PRINT " ";
ELSE
PRINT DayOfWeekString$(x);: IF POS(0) > 1 THEN PRINT " ";
END IF
NEXT x
' Always print the word "the" in the highlight color
COLOR 15, 4: PRINT "the";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
' Print the day of the month
FOR x = 1 TO 31
IF x = Day THEN
COLOR 15, 4: PRINT DayString$(x);: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT DayString$(x);: IF POS(0) > 1 THEN PRINT " ";
END IF
NEXT x
' Always print the word "of" in the highlight color
COLOR 15, 4: PRINT "of";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
' Print the month
FOR x = 1 TO 12
IF x = Month THEN
COLOR 15, 4: PRINT MonthString$(x);: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT MonthString$(x);: IF POS(0) > 1 THEN PRINT " ";
END IF
NEXT x
' Always print a comma (,) in the highlight color
COLOR 15, 4: PRINT ",";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
' Print the hour. Hours are numbered from 0 to 23. Since we are using AM and PM we need to manipulate the hours a little bit
' and set an AM / PM flag.
' Set an AM / PM Flag. AM_PM$ will be set to either "AM" or "PM".
SELECT CASE Hour
CASE 0 TO 11
AM_PM$ = "AM"
CASE ELSE
AM_PM$ = "PM"
END SELECT
' Convert 24 hour time to AM / PM (12 hour) format
SELECT CASE Hour
CASE 0
Hour = Hour + 12
EXIT SELECT
CASE 13 TO 23
Hour = Hour - 12
EXIT SELECT
END SELECT
FOR x = 1 TO 12
IF x = Hour THEN
COLOR 15, 4: PRINT HourString$(x);: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT HourString$(x);: IF POS(0) > 1 THEN PRINT " ";
END IF
NEXT x
' If minutes are equal to zero, highlight the word "o'clock".
IF (Minute = 0) THEN
COLOR 15, 4: PRINT "o'clock";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT "o'clock ";
END IF
' Print the minute. Minutes are numbered from 0 to 59. If seconds are 0, then we highlight the word "precisely",
' otherwise we highlight the word "and" and the appropriate second following the minutes.
FOR x = 1 TO 59
IF x = Minute THEN
COLOR 15, 4: PRINT MinuteString$(x);: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT MinuteString$(x);: IF POS(0) > 1 THEN PRINT " ";
END IF
NEXT x
' Print the AM and PM indicators.
SELECT CASE AM_PM$
CASE "AM"
COLOR 15, 4: PRINT "AM";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
PRINT "PM";: IF POS(0) > 1 THEN PRINT " ";
CASE "PM"
PRINT "AM";: PRINT " ";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
COLOR 15, 4: PRINT "PM";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
END SELECT
' If seconds are 0, then highlight the word "precisely", otherwise, highlight the word "and".
SELECT CASE Second
CASE 0
PRINT "and";: IF POS(0) > 1 THEN PRINT " ";
COLOR 15, 4: PRINT "precisely";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
CASE ELSE
COLOR 15, 4: PRINT "and";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
PRINT "precisely";: IF POS(0) > 1 THEN PRINT " ";
END SELECT
' Print the second. Seconds are numbered from 0 to 59.
FOR x = 1 TO 59
SELECT CASE x
CASE 1
IF Second = 1 THEN
COLOR 15, 4: PRINT SecondString$(x);: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
COLOR 15, 4: PRINT "second";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT SecondString$(x);: IF POS(0) > 1 THEN PRINT " ";
PRINT "second";: IF POS(0) > 1 THEN PRINT " ";
END IF
CASE ELSE
IF Second = x THEN
COLOR 15, 4: PRINT SecondString$(x);: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
ELSE
PRINT SecondString$(x);: IF POS(0) > 1 THEN PRINT " ";
END IF
END SELECT
NEXT x
' Highlight the word "seconds" if Second > 1.
SELECT CASE Second
CASE 0, 1
PRINT "seconds";: IF POS(0) > 1 THEN PRINT " ";
CASE ELSE
COLOR 15, 4: PRINT "seconds";: IF POS(0) > 1 THEN COLOR 8, 0: PRINT " ";
END SELECT
OldSecond = Second
DisplayFinished:
LOOP
END
DayOfWeek:
DATA "Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"
Day:
DATA "first","second","third","fourth","fifth","sixth","seventh","eighth","ninth","tenth","eleventh","twelfth","thirteenth"
DATA "fourteenth","fifteenth","sixteenth","seventeenth","eighteenth","nineteenth","twentieth","twenty-first","twenty-second"
DATA "twenty-third","twenty-fourth","twenty-fifth","twenty-sixth","twenty-seventh","twenty-eighth","twenty-ninth","thirtieth","thirty-first"
Month:
DATA "January","February","March","April","May","June","July","August","September","October","November","December"
Hour:
DATA "one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"
Minute:
DATA "oh-one","oh-two","oh-three","oh-four","oh-five","oh-six","oh-seven","oh-eight","oh-nine","ten","eleven","twelve","thirteen"
DATA "fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty","twenty-one","twenty-two","twenty-three","twenty-four"
DATA "twenty-five","twenty-six","twenty-seven","twenty-eight","twenty-nine","thirty","thirty-one","thirty-two","thirty-three"
DATA "thirty-four","thirty-five","thirty-six","thirty-seven","thirty-eight","thirty-nine","forty","forty-one","forty-two","forty-three"
DATA "forty-four","forty-five","forty-six","forty-seven","forty-eight","forty-nine","fifty","fifty-one","fifty-two","fifty-three"
DATA "fifty-four","fifty-five","fifty-six","fifty-seven","fifty-eight","fifty-nine"
Second:
DATA "one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen"
DATA "fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty","twenty-one","twenty-two","twenty-three","twenty-four"
DATA "twenty-five","twenty-six","twenty-seven","twenty-eight","twenty-nine","thirty","thirty-one","thirty-two","thirty-three"
DATA "thirty-four","thirty-five","thirty-six","thirty-seven","thirty-eight","thirty-nine","forty","forty-one","forty-two","forty-three"
DATA "forty-four","forty-five","forty-six","forty-seven","forty-eight","forty-nine","fifty","fifty-one","fifty-two","fifty-three"
DATA "fifty-four","fifty-five","fifty-six","fifty-seven","fifty-eight","fifty-nine"
MonthTable:
DATA 0,3,3,6,1,4,6,2,5,0,3,5
So just remember "monospace" is needed to make the fonts fixed width, as well as to get the _FONTWIDTH function to return a value other than zero.
Pete
If eggs are brain food, Biden takes his scrambled.