LB Booster
« Nth Day of Month »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 03:57am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Nth Day of Month  (Read 703 times)
Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Nth Day of Month
« Thread started on: Sep 2nd, 2016, 3:45pm »

This program provides a function definition that returns the date of any occurrence of a day in any given month and year. For example, the first Monday in August or the fourth Thursday in November, etc. It should be useful for developing calendar programs. Those who have taken a look at my Remember-It program in the Showcase Section will know just exactly where I'm going with this function.

Code:
NoMainWin
WindowWidth = 800 : WindowHeight = 600
statictext #win.Title, "Find the nth day of any month...", 135, 150, 287, 31
stylebits #win.textbox4, _ES_NUMBER, 0, 0, 0
textbox #win.textbox4, 50, 198, 85, 30
statictext #win.caption, "1901 to 2099", 54, 230, 85, 30
combobox #win.combobox6, MonthArray$(), click, 180, 200, 120, 210
combobox #win.combobox7, WeekArray$(), click, 340, 200, 120, 210
combobox #win.combobox8, DayArray$(), click, 500, 200, 120, 210
button #win.button7, "Find", [find], ul, 650, 200, 100, 30
button #win.button8, "Quit", [quit], ul, 650, 300, 100, 30
statictext #win.Date, "", 350, 350, 97, 75
open "Nth Day of Month" for dialog_nf as #win
#win "TrapClose [quit]"
#win "Font Ariel 12"
#win.caption, "!Font Arial 10"
#win.Title "!Font Arial 14 bold"
#win.Date "!Font Arial 24 bold"
call SetTextLimit hwnd(#win.textbox4), 4
#win.textbox4 "Year (yyyy)"
#win.textbox4 "!SetFocus"
#win.textbox4 "!SelectAll"
call SetUpArrays
wait

[find]
#win.textbox4 "!Contents? Year$": Year=val(Year$)
#win.combobox6 "Selection? Month$": Month=Month(Month$)
#win.combobox7 "Selection? Week$" 
#win.combobox8 "Selection? Day$": nDa$=nDa$(Week$, Day$)
x=NthDayOfMonth(Year, Month, nDa$)
if x>0 then #win.Date x else #win.Date ""
wait

[quit]
close #win
end

function NthDayOfMonth(yyyy, mm, nda$)
' nda$ is a two part code. The first character is the occurance in the 
' month -- first, second, third, fourth, or last -- denoted by 1, 2, 3, 4 or 5.
' The last two characters is the day of the week denoted by Su, Mo, Tu, We, Th,
' Fr, or Sa.
    if yyyy<1901 or yyyy>2099 or mm<1 or mm>12 then
        NthDayOfMonth=0: exit function
    end if
    nda$=lower$(trim$(nda$))
    if len(nda$)<>3 then NthDayOfMonth=0: exit function
    n$=left$(nda$,1)
    nC$="1234l"
    da$=right$(nda$,2)
    daC$="tuwethfrsasumotuwethfrsasumo"
    if not(instr(nC$,n$)) or not(instr(daC$,da$)) then
        NthDayOfMonth=0
        exit function
    end if
    NthDayOfMonth=1
    mm$=str$(mm): if mm<10 then mm$="0"+mm$ 
    db$=DayOfDate$(str$(yyyy)+mm$+"01")
    if da$<>db$ then
        x=instr(daC$,db$): y=instr(daC$,da$,x): NthDayOfMonth=1+(y-x)/2
    end if
    dim MD(12)
    MD(1)=31: MD(2)=28: MD(3)=31: MD(4)=30: MD(5)=31: MD(6)=30 
    MD(7)=31: MD(8)=31: MD(9)=30: MD(10)=31: MD(11)=30: MD(12)=31 
    if yyyy mod 4 = 0 then MD(2)=29
    if n$<>"1" then
        if n$<>"l" then
            NthDayOfMonth=NthDayOfMonth+((val(n$)-1)*7)
        else
            if NthDayOfMonth+28<MD(mm)+1 then
                NthDayOfMonth=NthDayOfMonth+28
            else
                NthDayOfMonth=NthDayOfMonth+21
            end if
        end if
    end if
end function

function DayOfDate$(ObjectDate$) 'yyyymmdd format
    if ObjectDate$="" then 'today
        DaysSince1900 = date$("days")
    else
        DaysSince1900 = date$(mid$(ObjectDate$,5,2)+"/"+right$(ObjectDate$,2)_
                +"/"+left$(ObjectDate$,4))
    end if
    DayOfWeek = DaysSince1900 mod 7
    select case DayOfWeek
        case 0: DayOfDate$="tu"
        case 1: DayOfDate$="we"
        case 2: DayOfDate$="th"
        case 3: DayOfDate$="fr"
        case 4: DayOfDate$="sa"
        case 5: DayOfDate$="su"
        case 6: DayOfDate$="mo"
    end select
end function

sub SetUpArrays
dim MonthArray$(12)
MonthArray$(1)="January"
MonthArray$(2)="February"
MonthArray$(3)="March"
MonthArray$(4)="April"
MonthArray$(5)="May"
MonthArray$(6)="June"
MonthArray$(7)="July"
MonthArray$(8)="August"
MonthArray$(9)="September"
MonthArray$(10)="October"
MonthArray$(11)="November"
MonthArray$(12)="December"

WeekArray$(1)="First"
WeekArray$(2)="Second"
WeekArray$(3)="Third"
WeekArray$(4)="Fourth"
WeekArray$(5)="Last"

DayArray$(1)="Sunday"
DayArray$(2)="Monday"
DayArray$(3)="Tuesday"
DayArray$(4)="Wednesday"
DayArray$(5)="Thursday"
DayArray$(6)="Friday"
DayArray$(7)="Saturday"

#win.combobox6 "Reload"
#win.combobox6 "!month"
#win.combobox7 "Reload"
#win.combobox7 "!Occurance"
#win.combobox8 "Reload"
#win.combobox8 "!Day"
end sub

function Month(Month$)
    select case Month$
        case "January": Month=1
        case "February": Month=2
        case "March": Month=3
        case "April": Month=4
        case "May": Month=5
        case "June": Month=6
        case "July": Month=7
        case "August": Month=8
        case "September": Month=9
        case "October": Month=10
        case "November": Month=11
        case "December": Month=12
    end select
end function

function nDa$(Week$, Day$)
    select case Week$
        case "First": n$="1"
        case "Second": n$="2"
        case "Third": n$="3"
        case "Fourth": n$="4"
        case "Last": n$="L"
    end select
    select case Day$
        case "Sunday": Da$="Su"
        case "Monday": Da$="Mo"
        case "Tuesday": Da$="Tu"
        case "Wednesday": Da$="We"
        case "Thursday": Da$="Th"
        case "Friday": Da$="Fr"
        case "Saturday": Da$="Sa"
    end select
    nDa$=n$+Da$
end function

sub SetTextLimit TextBoxHwnd, Limit
    CallDll #user32, "SendMessageA",_
                     TextBoxHwnd as ulong,_
                     _EM_SETLIMITTEXT as long,_
                     Limit as long,_
                     0 as long,_
                     SetTextLimit as long
end sub

sub click handle$
end sub
 
« Last Edit: Sep 5th, 2016, 11:31am by Jack Kelly » User IP Logged

tsh73
Full Member
ImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 210
xx Re: Nth Day of Month
« Reply #1 on: Sep 5th, 2016, 07:48am »

Hello Jack
your program have some issues
1) wikipedia says 2000 is leap year
Quote:
Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 are not leap years, but the years 1600 and 2000 are.[5]

Windows calendar agrees (your program says last Tue of February 2000 is 22nd, should be 29th).

2) Last parameter in combobox is "high".
LB help says
Quote:
wide & high

These parameters determine the width and height (in pixels) of the combobox. "Height" in this case refers to the length of the selection list when the combobox's button is clicked, not to the size of the initial selection window, which is dependant upon the size of the font.

so apparently 21 is too small - in LB list just don't drop down at all
(it looks like LBB ignores it, so it works?)

3) Also your program sets handle for comboboxes to be sub "click", but there no such sub in code.
So it makes LB to die silently after selecting from combobox (after any second select in my test)
You really might not care but adding
Code:
sub click handle$
end sub
 

fixes this.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Nth Day of Month
« Reply #2 on: Sep 5th, 2016, 08:47am »

on Sep 5th, 2016, 07:48am, tsh73 wrote:
LB help says '"Height" in this case refers to the length of the selection list when the combobox's button is clicked'.

The LB Help is wrong - or at least very out-of-date. Before Common Controls version 6.0 (so called 'Windows XP Visual Styles') what it says was true, but since then the height parameter of a combobox has been ignored.

So as long as you are targeting your program to Windows XP or later, and Common Controls v6 are enabled by the program's manifest (which they are in LBB), it is not necessary to set the height parameter to the size of the drop-down box. The comboboxes in Jack's program work fine here in LB 4.04 and LB 4.5.0 (Windows 10).

But the Year 2000 bug is shocking, well spotted. wink

Richard.
User IP Logged

joker
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 157
xx Re: Nth Day of Month
« Reply #3 on: Sep 5th, 2016, 09:47am »

on Sep 5th, 2016, 08:47am, Richard Russell wrote:
... But the Year 2000 bug is shocking, well spotted. wink


Too funny, Richard! Wasn't that the year that we were all supposed to be slung off the Earth never to be heard from again? Perhaps I exaggerate a bit? cheesy
User IP Logged

Jack Kelly
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 106
xx Re: Nth Day of Month
« Reply #4 on: Sep 5th, 2016, 11:37am »

I have corrected the issues in the original post, code section. Sorry about the Y2K leap year error. Endless confusion is my normal state-of-mind. Thank you for your feedback. It's always appreciated!
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Nth Day of Month
« Reply #5 on: Sep 5th, 2016, 12:02pm »

on Sep 5th, 2016, 09:47am, pnlawrence wrote:
Wasn't that the year that we were all supposed to be slung off the Earth never to be heard from again?

In all seriousness this conditional test in Jack's program is surprising:

Code:
if yyyy mod 4 = 0 and yyyy<>2000 then 

It was/is quite fortuitous that 2000 (being a multiple-of-400 year) fitted in with the simple leap-year rule because it meant that programs written carelessly, or with an expectation that they wouldn't still be in use by then, nevertheless worked correctly. But there's no accounting for somebody inserting a special test for 2000, when it wasn't special!

If the test had said year<>2100 it would have been correct, and we would have been congratulating Jack for his optimism!

Richard.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls