Easy Date Converter Advanced Version
Subroutines
 

This page explains how to write and call subroutines defined in terms of EDC statements.

A subroutine definition is any set of contiguous program statements (one per line as usual, possibly with intervening blank lines) which begins with a statement of the form:

sub {subroutine name}([{arg1}[, {arg2}[, ...]]])

and ends with endsub. For example:

call ShowDate(today)

sub ShowDate(d)
if d = today then
    output: Today's date is:;
else
    output: The date is:;
endif
output: DateVal(d,CE)
endsub

Exit from a subroutine before the end is done via return: (with no return value, since subroutines do not return anything).

Properties of subroutines:

There are some restrictions on the use of subroutines:

Now follow some sample programs illustrating the use of subroutines.


Example E1

Here is an example of a subroutine which calls a defined function.

Input file Result in output window
//  Example E1

date = today
do 60
    call subr(date)
    date += 1
enddo

sub subr(d)
tv = DaySameAsMonth(d)
if tv = 1
    output: DateVal(d,CE)
endif
endsub

function DaySameAsMonth(d)
if  DayOf(d,CE) = MonthOf(d,CE)
    return: 1
else
    return: 0
endif
endfunction
2007-04-04 CE
2007-05-05 CE

Note that built-in functions can be used in IF statements but not defined functions, so if DayOf(d,CE) = MonthOf(d,CE) is valid but if DaySameAsMonth(d) = 1 is not.


Example E2

This example shows how an EDC program can be used in calendrical studies.

In March 2007 the U.S. introduced new rules for the start and end of Daylight Savings Time, as follows: DST begins on the 2nd Sunday in March and ends on the 1st Sunday in November. (Formerly DST began in the U.S. on the 1st Sunday of April and ended on the last Sunday of October.)

The question was raised on the CALNDR-L discussion group as to when, under the new rules, DST started and ended in the ISO Week Calendar. On 2007-03-08 Robert van Gent gave this answer:

U.S. Daylight Saving Time will always start on Sunday ISO week 10 and end on Sunday ISO week 44, except in leap years (such as 2032 and 2060) when 29 February is a Sunday when the begin and end will be in ISO weeks 11 and 45.

Given below is an EDC program which solves the following problem: If DST starts on the n1th Sunday in month m1 and ends on the n2th Sunday in month m2, what are the ISO Week dates of the start and end of DST over a given range of years? (Where a zero value for n1 and n2 means 'last'.)

In this program the values of n1, m1, etc. are set appropriately for the new DST rules, and w1 and w2 are set according to Robert van Gent's statement, which, by computation, is found to be confirmed. This program uses the same defined functions NumDaysInMonthCE(m,y) and DateOfNthSundayInMonthCE(n,m,y) which were used in Example D4.

Input file Result in output window
//  Example E2

n1 = 2
m1 = 3
w1 = 10

n2 = 1
m2 = 11
w2 = 44

output: The hypothesis to be tested is that
output: if DST begins on Sunday #;;
output: val(n1);
output: in month #;;
output: val(m1)
output: and ends on Sunday #;;
output: val(n2);
output: in month #;;
output: val(m2)
output: then in almost all years DST will
output: begin on the Sunday of ISO week #;;
output: val(w1);
output: and
output: end on the Sunday of ISO week #;;
output: val(w2);;
output: .
bl

start_year = 2007
end_year = 2100

output: For the period of years;
output: val(start_year);
output: through;
output: val(end_year)
output: this proposition is *not* true as follows:
bl

year = start_year
count = 0

do
    tv = ShowSundayIfNotISOWeek(n1,m1,w1,year)
    if tv = 1 then
        count += 1
    endif
    tv = ShowSundayIfNotISOWeek(n2,m2,w2,year)
    if tv = 1 then
        count += 1
        bl
    endif

    year += 1
    if year > end_year then
        exitdo
    endif

enddo

if count = 0 then
    output: So there are no exceptions to this
    output: proposition in this period of years.
endif

function ShowSundayIfNotISOWeek(n,m,w,y)
date = DateOfNthSundayInMonthCE(n,m,y)
ifnot WeekOf(date,ISO) = w then
    call DisplayLine(date,n,m)
    return: 1
else
    return: 0
endif
endfunction

sub DisplayLine(date,n,m)
output: DoW(date);
output: #;;
output: val(n);
output: in;
output: MonthName(m,CE);
output: YearOf(date, CE);
output: is;
output: dateval(date,CE);
output: =;
output: dateval(date,ISO);;
output: .
endsub

function NumDaysInMonthCE(m,y)
date1 = Date(CE,y,m,1)
if m < 12 then
    m += 1
    date2 = Date(CE,y,m,1)
else
    y += 1
    date2 = Date(CE,y,1,1)
endif
return: Subtract(date1,date2)
endfunction

function DateOfNthSundayInMonthCE(n,m,y)
num_days_in_month = NumDaysInMonthCE(m,y)
if n >= 1 then
    k = 0
    date1 = Date(CE,y,m,1)
    do
        if DoW(date1) = Sunday then
            k += 1
            if k = n then
                return: date1
            endif
        endif
        if DayOf(date1,CE) = num_days_in_month then
            return: 0
            //  n too large.
        endif
        date1 += 1
    enddo
elseif n = 0 then
    //  Seeking last Sunday in the month.
    date1 = Date(CE,y,m,num_days_in_month)
    do
        if DoW(date1) = Sunday then
            return: date1
        endif
        date1 -= 1
    enddo
else
    return: 0
    //  n < 0
endif
return: date1
endfunction
The hypothesis to be tested is that
if DST begins on Sunday #2 in month #3
and ends on Sunday #1 in month #11
then in almost all years DST will
begin on the Sunday of ISO week #10 and
end on the Sunday of ISO week #44.

For the period of years 2007 through 2100
this proposition is *not* true as follows:

Sunday #2 in March 2032 is 2032-03-14 CE = 2032-W11-7 ISO.
Sunday #1 in November 2032 is 2032-11-07 CE = 2032-W45-7 ISO.

Sunday #2 in March 2060 is 2060-03-14 CE = 2060-W11-7 ISO.
Sunday #1 in November 2060 is 2060-11-07 CE = 2060-W45-7 ISO.

Sunday #2 in March 2088 is 2088-03-14 CE = 2088-W11-7 ISO.
Sunday #1 in November 2088 is 2088-11-07 CE = 2088-W45-7 ISO.

By changing the values assigned to n1, m1, etc., this program may be used to show the following:

1. Under the old rules, and the rules still used by almost all other countries in the world, DST almost always ends with the Sunday of Week 43 in the ISO Week Calendar, but it begins about half the time on the Sunday of ISO Week 13 and the rest of the time with the Sunday of ISO Week 14.

2. If DST begins on the last Sunday in March then there is also an even division of ISO Week beginnings (Weeks 12 and 13), but if it begins on the 1st, 2nd, 3rd or 4th Sunday in March then it always begins on the same ISO Sunday (in Week 9, 10, 11 or 12 respectively) with exceptions in years 2032, 2060 and 2088 (in the period 2007-2100).


Example E3

After seeing the example above Karl Palmen asked:

Can it [EDC] show that European DST begins on Sunday ISO week 14, if there are five Sundays in either February or March, else Sunday ISO week 13.

The following program tests this hypothesis, which is found to be true for the years 1800 through 2201. Since the structure of the Common Era Calendar and the ISO Week Calendar (which is defined in terms of the former) repeats every 400 years, the hypothesis is true for all years.

This program uses the two defined functions in the previous example, and uses a new defined function, NumSundaysInMonthCE(). The program outputs a '.' for each year when there is no exception to the hypothesis; most of these have been omitted from the output given below.

Input file Result in output window
//  Example E3

output: The hypothesis to be tested is that if there
output: are five Sundays in either February or March
output: then European DST begins on Sunday ISO week 14
output: else it begins on Sunday ISO week 13.
bl

start_year = 1800
end_year = 2201

output: For the period of years;
output: val(start_year);
output: through;
output: val(end_year)
output: this hypothesis is *not* true as follows:
bl

year = start_year

do
    date = DateOfNthSundayInMonthCE(1,4,year)
    //  Date on which European DST begins.
    iso_week = WeekOf(date,ISO)
    //  ISO week number.

    num_sun_feb = NumSundaysInMonthCE(2,year)
    num_sun_mar = NumSundaysInMonthCE(3,year)

    exception = 0
    if num_sun_feb = 5 then
        ifnot iso_week = 14 then
            exception = 1
        endif
    elseif num_sun_mar = 5 then
        ifnot iso_week = 14 then
            exception = 1
        endif
    elseifnot iso_week = 13 then
        exception = 1
    endif

    if exception = 1 then
        output: The hypothesis is not true of year;
        output: val(year);;
        output: .
        stop
    else
        output: .;
    endif

    year += 1
    if year > end_year then
        exitdo
    endif
enddo

bl
bl
output: So there are no exceptions to this
output: hypothesis in this period of years.

function NumSundaysInMonthCE(m,y)
date = DateOfNthSundayInMonthCE(1,m,y)
//  This is the date of the 1st Sunday.
num_sundays = 1
do
    date = Add(7,date)
    if m = 12 then
        if MonthOf(date,CE) = 1 then
            exitdo
        endif
    elseif MonthOf(date,CE) > m then
        exitdo
    else
        num_sundays += 1
    endif
enddo
return: num_sundays
endfunction

function NumDaysInMonthCE(m,y)
date1 = Date(CE,y,m,1)
if m < 12 then
    m += 1
    date2 = Date(CE,y,m,1)
else
    y += 1
    date2 = Date(CE,y,1,1)
endif
return: Subtract(date1,date2)
endfunction

function DateOfNthSundayInMonthCE(n,m,y)
num_days_in_month = NumDaysInMonthCE(m,y)
if n >= 1 then
    k = 0
    date1 = Date(CE,y,m,1)
    do
        if DoW(date1) = Sunday then
            k += 1
            if k = n then
                return: date1
            endif
        endif
        if DayOf(date1,CE) = num_days_in_month then
            return: 0
            //  n too large.
        endif
        date1 += 1
    enddo
elseif n = 0 then
    //  Seeking last Sunday in the month.
    date1 = Date(CE,y,m,num_days_in_month)
    do
        if DoW(date1) = Sunday then
            return: date1
        endif
        date1 -= 1
    enddo
else
    return: 0
    //  n < 0
endif
return: date1
endfunction
The hypothesis to be tested is that if there
are five Sundays in either February or March
then European DST begins on Sunday ISO week 14
else it begins on Sunday ISO week 13.

For the period of years 1800 through 2201
this hypothesis is *not* true as follows:

. . . . . [snip]

So there are no exceptions to this
hypothesis in this period of years.


Easy Date Converter Advanced Version Main Page
Date/Calendar Software Hermetic Systems Home Page