' Week Number — computes ISO week number for any given date
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL year AS LONG
    LOCAL month AS LONG
    LOCAL day AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL dow AS LONG
    LOCAL weekNum AS LONG
    LOCAL jan1Dow AS LONG
    LOCAL firstWeekDay AS LONG
    LOCAL dayOfYear AS LONG
    LOCAL daysInYear AS LONG
    LOCAL isLeapVal AS LONG
    LOCAL t AS LONG
    LOCAL y AS LONG
    LOCAL m AS LONG
    LOCAL d AS LONG
    LOCAL dowName AS STRING
    LOCAL monthName AS STRING
    LOCAL dateStr AS STRING
    LOCAL lineStr AS STRING
    PRINT "============================================"
    PRINT "         ISO WEEK NUMBER CALCULATOR"
    PRINT "============================================"
    PRINT ""
    PRINT "Day of year for each month start:"
    PRINT ""
    FOR year = 2024 TO 2026
        PRINT "Year " + STR$(year) + ":"
        dayOfYear = 0
        FOR month = 1 TO 12
            IF month = 2 THEN
                isLeapVal = 0
                IF year MOD 400 = 0 THEN
                    isLeapVal = 1
                ELSE
                    IF year MOD 100 = 0 THEN
                        isLeapVal = 0
                    ELSE
                        IF year MOD 4 = 0 THEN
                            isLeapVal = 1
                        END IF
                    END IF
                END IF
                IF isLeapVal = 1 THEN
                    daysInYear = 366
                ELSE
                    daysInYear = 365
                END IF
            END IF
            IF month = 1 THEN monthName = "Jan"
            IF month = 2 THEN monthName = "Feb"
            IF month = 3 THEN monthName = "Mar"
            IF month = 4 THEN monthName = "Apr"
            IF month = 5 THEN monthName = "May"
            IF month = 6 THEN monthName = "Jun"
            IF month = 7 THEN monthName = "Jul"
            IF month = 8 THEN monthName = "Aug"
            IF month = 9 THEN monthName = "Sep"
            IF month = 10 THEN monthName = "Oct"
            IF month = 11 THEN monthName = "Nov"
            IF month = 12 THEN monthName = "Dec"
            PRINT "  " + monthName + " 1: day " + STR$(dayOfYear)
            IF month = 2 THEN
                isLeapVal = 0
                IF year MOD 400 = 0 THEN
                    isLeapVal = 1
                ELSE
                    IF year MOD 100 = 0 THEN
                        isLeapVal = 0
                    ELSE
                        IF year MOD 4 = 0 THEN
                            isLeapVal = 1
                        END IF
                    END IF
                END IF
                IF isLeapVal = 1 THEN
                    dayOfYear = dayOfYear + 29
                ELSE
                    dayOfYear = dayOfYear + 28
                END IF
            ELSE
                IF month = 4 OR month = 6 OR month = 9 OR month = 11 THEN
                    dayOfYear = dayOfYear + 30
                ELSE
                    dayOfYear = dayOfYear + 31
                END IF
            END IF
        NEXT month
    NEXT year
    PRINT ""
    PRINT "============================================"
    PRINT "     WEEK NUMBER FOR EACH DAY OF YEAR"
    PRINT "============================================"
    PRINT ""
    year = 2024
    dayOfYear = 0
    FOR month = 1 TO 12
        IF month = 2 THEN
            isLeapVal = 0
            IF year MOD 400 = 0 THEN
                isLeapVal = 1
            ELSE
                IF year MOD 100 = 0 THEN
                    isLeapVal = 0
                ELSE
                    IF year MOD 4 = 0 THEN
                        isLeapVal = 1
                    END IF
                END IF
            END IF
            IF isLeapVal = 1 THEN
                daysInYear = 366
            ELSE
                daysInYear = 365
            END IF
        END IF
        IF month = 1 THEN monthName = "Jan"
        IF month = 2 THEN monthName = "Feb"
        IF month = 3 THEN monthName = "Mar"
        IF month = 4 THEN monthName = "Apr"
        IF month = 5 THEN monthName = "May"
        IF month = 6 THEN monthName = "Jun"
        IF month = 7 THEN monthName = "Jul"
        IF month = 8 THEN monthName = "Aug"
        IF month = 9 THEN monthName = "Sep"
        IF month = 10 THEN monthName = "Oct"
        IF month = 11 THEN monthName = "Nov"
        IF month = 12 THEN monthName = "Dec"
        day = 1
        m = month
        y = year
        IF m < 3 THEN
            m = m + 12
            y = y - 1
        END IF
        t = day + (13 * (m + 1)) / 5 + y + (y / 4) - (y / 100) + (y / 400)
        dow = t MOD 7
        IF dow < 0 THEN
            dow = dow + 7
        END IF
        dow = dow + 1
        IF dow > 7 THEN
            dow = dow - 7
        END IF
        m = month
        y = year
        IF m < 3 THEN
            m = m + 12
            y = y - 1
        END IF
        t = 1 + (13 * (m + 1)) / 5 + y + (y / 4) - (y / 100) + (y / 400)
        jan1Dow = t MOD 7
        IF jan1Dow < 0 THEN
            jan1Dow = jan1Dow + 7
        END IF
        jan1Dow = jan1Dow + 1
        IF jan1Dow > 7 THEN
            jan1Dow = jan1Dow - 7
        END IF
        IF jan1Dow <= 4 THEN
            firstWeekDay = 2 - jan1Dow
        ELSE
            firstWeekDay = 9 - jan1Dow
        END IF
        weekNum = (dayOfYear - firstWeekDay + 7) / 7
        IF dayOfYear < firstWeekDay THEN
            weekNum = 0
        END IF
        IF weekNum = 0 THEN
            weekNum = 1
        END IF
        IF weekNum > 52 THEN
            weekNum = 1
        END IF
        PRINT monthName + " 1, " + STR$(year) + " -> Week " + STR$(weekNum)
        IF month = 2 THEN
            isLeapVal = 0
            IF year MOD 400 = 0 THEN
                isLeapVal = 1
            ELSE
                IF year MOD 100 = 0 THEN
                    isLeapVal = 0
                ELSE
                    IF year MOD 4 = 0 THEN
                        isLeapVal = 1
                    END IF
                END IF
            END IF
            IF isLeapVal = 1 THEN
                dayOfYear = dayOfYear + 29
            ELSE
                dayOfYear = dayOfYear + 28
            END IF
        ELSE
            IF month = 4 OR month = 6 OR month = 9 OR month = 11 THEN
                dayOfYear = dayOfYear + 30
            ELSE
                dayOfYear = dayOfYear + 31
            END IF
        END IF
    NEXT month
    PRINT ""
    PRINT "============================================"
    PRINT "     WEEK NUMBERS FOR SPECIFIC DATES"
    PRINT "============================================"
    PRINT ""
    LOCAL testDates AS LONG
    testDates = 10
    FOR i = 0 TO testDates - 1
        year = 2024
        month = i + 1
        day = 15
        m = month
        y = year
        IF m < 3 THEN
            m = m + 12
            y = y - 1
        END IF
        t = day + (13 * (m + 1)) / 5 + y + (y / 4) - (y / 100) + (y / 400)
        dow = t MOD 7
        IF dow < 0 THEN
            dow = dow + 7
        END IF
        dow = dow + 1
        IF dow > 7 THEN
            dow = dow - 7
        END IF
        dayOfYear = 0
        FOR j = 1 TO month - 1
            IF j = 2 THEN
                isLeapVal = 0
                IF year MOD 400 = 0 THEN
                    isLeapVal = 1
                ELSE
                    IF year MOD 100 = 0 THEN
                        isLeapVal = 0
                    ELSE
                        IF year MOD 4 = 0 THEN
                            isLeapVal = 1
                        END IF
                    END IF
                END IF
                IF isLeapVal = 1 THEN
                    dayOfYear = dayOfYear + 29
                ELSE
                    dayOfYear = dayOfYear + 28
                END IF
            ELSE
                IF j = 4 OR j = 6 OR j = 9 OR j = 11 THEN
                    dayOfYear = dayOfYear + 30
                ELSE
                    dayOfYear = dayOfYear + 31
                END IF
            END IF
        NEXT j
        dayOfYear = dayOfYear + day
        m = 1
        y = year
        IF m < 3 THEN
            m = m + 12
            y = y - 1
        END IF
        t = 1 + (13 * (m + 1)) / 5 + y + (y / 4) - (y / 100) + (y / 400)
        jan1Dow = t MOD 7
        IF jan1Dow < 0 THEN
            jan1Dow = jan1Dow + 7
        END IF
        jan1Dow = jan1Dow + 1
        IF jan1Dow > 7 THEN
            jan1Dow = jan1Dow - 7
        END IF
        IF jan1Dow <= 4 THEN
            firstWeekDay = 2 - jan1Dow
        ELSE
            firstWeekDay = 9 - jan1Dow
        END IF
        weekNum = (dayOfYear - firstWeekDay + 7) / 7
        IF dayOfYear < firstWeekDay THEN
            weekNum = 1
        END IF
        IF month = 1 THEN monthName = "Jan"
        IF month = 2 THEN monthName = "Feb"
        IF month = 3 THEN monthName = "Mar"
        IF month = 4 THEN monthName = "Apr"
        IF month = 5 THEN monthName = "May"
        IF month = 6 THEN monthName = "Jun"
        IF month = 7 THEN monthName = "Jul"
        IF month = 8 THEN monthName = "Aug"
        IF month = 9 THEN monthName = "Sep"
        IF month = 10 THEN monthName = "Oct"
        IF month = 11 THEN monthName = "Nov"
        IF month = 12 THEN monthName = "Dec"
        dateStr = monthName + " " + STR$(day) + ", " + STR$(year)
        PRINT " " + dateStr + " -> Week " + STR$(weekNum)
    NEXT i
    PRINT ""
    PRINT "Week number calculations complete"
    FUNCTION = 0
END FUNCTION
