From: got@asl1.sta.sub.org (Gerhard Otte)
Newsgroups: biz.sco.general
Subject: a little calendar problem
Date: 27 Jan 93 08:47:42 GMT
Organization: ASL Regensburg,Germany


A week ago i had the following  little calendar problem:

>>> I'm developing an application on SCO Unix and Informix 4GL and have
>>> a little problem in determing the number of the last week of the
>>> year. For example: in 1992 the last week (starting at 12/28/92) is
>>> said to be the 53rd week of 1992; in 1991 the last week of the year
>>> (starting at 12/30/91) was said to be the first week of 1992...??
>>> 
>>> So what's going on? Does it depend on the weekday of the 1/1?
>>> If someone could give me a hint or perhaps a lille algorithm or a
>>> piece of code?     

Some days later i got the following solution from 
Simon Ellefsen <stoffer@proinf.dk>:

GLOBALS
	DEFINE
		days_in_month	ARRAY[12] OF INTEGER
END GLOBALS

MAIN
	DEFINE week INTEGER
	DEFINE dummy CHAR(1)

	LET days_in_month[1] = 31
	LET days_in_month[2] = 29
	LET days_in_month[3] = 31
	LET days_in_month[4] = 30
	LET days_in_month[5] = 31
	LET days_in_month[6] = 30
	LET days_in_month[7] = 31
	LET days_in_month[8] = 31
	LET days_in_month[9] = 30
	LET days_in_month[10] = 31
	LET days_in_month[11] = 30
	LET days_in_month[12] = 31

	LET week = weekno (1991,  1,  1)
	MESSAGE "Week no. of 910101: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1991,  6, 30)
	MESSAGE "Week no. of 910630: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1991, 12, 31)
	MESSAGE "Week no. of 911231: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1992,  1,  1)
	MESSAGE "Week no. of 920101: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1992,  6, 30)
	MESSAGE "Week no. of 920630: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1992, 12, 31)
	MESSAGE "Week no. of 921231: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1993,  1,  1)
	MESSAGE "Week no. of 930101: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1993,  6, 30)
	MESSAGE "Week no. of 930630: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1993, 12, 31)
	MESSAGE "Week no. of 931231: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
	LET week = weekno (1994,  1,  1)
	MESSAGE "Week no. of 940101: ", week
	PROMPT "Hit any Key to continue" FOR CHAR dummy
END MAIN

FUNCTION weekno( pyear, pmonth, pday )
	DEFINE
		pday, pmonth, pyear,
		week INTEGER

	LET week = rawweekno (pyear, pmonth, pday)
	IF week = 0 THEN
		# Then the weekno has to be the same as the
		# last week from previous year
		LET week = rawweekno (pyear - 1, 12, 31)
	END IF
	IF week = 53 THEN
		# Then the week might be the same as Jan. 1st
		# of next year.
		LET week = rawweekno (pyear + 1, 1, 1)
		IF week = 0 THEN
			# Then 53 has to be the right answer
			LET week = 53
		END IF
	END IF

	RETURN week

END FUNCTION # weekno ()

FUNCTION rawweekno( pyear, pmonth, pday )
	# This function will calculate the weekno to be
	# between the values [0; 53].
	# The calling program then has to decide what to
	# do with the values 0 and 53.

	DEFINE
		pday, pmonth, pyear,
		fwday, week, sumofdays, i INTEGER

	IF pday IS NULL OR pmonth IS NULL OR pyear IS NULL THEN
		RETURN -1
	END IF

	IF pmonth > 12 THEN
		RETURN -1
	END IF

	IF pyear MOD 400 = 0 OR (pyear MOD 4 = 0 AND pyear MOD 100 != 0) THEN
		LET days_in_month[2] = 29
	ELSE
		LET days_in_month[2] = 28
	END IF

	IF pday > days_in_month[pmonth] THEN
		RETURN -1
	END IF

	# What is this years first weekday
	# I hope that INFORMIX haven't messed with this function ....
	LET fwday = WEEKDAY( MDY( 1, 1, pyear ) ) - 1

	# Rename Sunday (put it last among the week)
	IF fwday < 0 THEN
		LET fwday = 6
	END IF

	# Align this year, as if it had started on a monday.
	LET sumofdays = fwday

	# Sum up the number of days
	FOR i = 1 TO pmonth-1
		LET sumofdays = sumofdays + days_in_month[i]
	END FOR
	LET sumofdays = sumofdays + pday

	# Substract 1 day, cause I want year to start with day 0.
	LET sumofdays = sumofdays - 1

	# That way I can calculate the weekno much easilier.
	LET week = (sumofdays / 7) + 1

	# If the year started on a Friday, Saturday or Sunday
	# - Then the first can't be numbered as 1.
	IF fwday > 3 THEN
		# Then the first week of the year is not numbered 1.
		LET week = week - 1
	END IF

	RETURN week

END FUNCTION # rawweekno()

Many thanks to Simon who saved me a lot of time !
Gerhard

-- 
       ____  _____   _    Gerhard Otte 
      /    | | ___| | |   phone: ++49 941 75081 
    /  /_| | |_|__  | |   fax:   ++49 941 75084 
  /  /___| |  __| | | |__ got@asl1.sta.sub.org
Newsgroups: biz.sco.general