Skip to main content
Recently a support case came in asking if there was an OCONV option to determine the week of the year of a passed date. OCONV won't do that, so I wrote a subroutine:

subroutine weekOfYear.sub(inDate, weekNo)
*
* Pass: inDate ( 5-digit internal date format )
* Return: weekNo ( 1-53 )
* Calculates which Sunday-Saturday week#
* within the year. Week 1 is only 7 days
* if January 1st is a Sunday.
*
if not(assigned(inDate)) then inDate=date()
if inDate matches "5n" else inDate=iconv(inDate,"d")
if inDate matches "5n" else inDate=date()
inYear=oconv(inDate,"dy")
begOfYear=iconv("1/1/":inYear,"d")
firstYearDay=oconv(begOfYear,"dw")
daysToSun=7-firstYearDay
weekNo=int(((oconv(inDate,"dj")-daysToSun)+6)/7)+(daysToSun>0)
return

As the comments state, you pass a date in Pick internal format, which has been a 5-digit number since May of 1995, and you receive a number from 1 to 53 indicating which week of the year contains that date. This assumes that the week you seek starts on a Sunday and ends on a Saturday. It will result in week 1 only being 7 days long if January 1st is a Sunday, and although popular perception thinks of a year being 52 weeks, there will always be a week 53 that contains December 31st at the bare minimum.

Anybody out there got anything to add or that they did differently? And more importantly, if you've done something similar that solves some other problem that you want to share with your Forum pals, please start a new thread and show us what you've got!!

------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------
Recently a support case came in asking if there was an OCONV option to determine the week of the year of a passed date. OCONV won't do that, so I wrote a subroutine:

subroutine weekOfYear.sub(inDate, weekNo)
*
* Pass: inDate ( 5-digit internal date format )
* Return: weekNo ( 1-53 )
* Calculates which Sunday-Saturday week#
* within the year. Week 1 is only 7 days
* if January 1st is a Sunday.
*
if not(assigned(inDate)) then inDate=date()
if inDate matches "5n" else inDate=iconv(inDate,"d")
if inDate matches "5n" else inDate=date()
inYear=oconv(inDate,"dy")
begOfYear=iconv("1/1/":inYear,"d")
firstYearDay=oconv(begOfYear,"dw")
daysToSun=7-firstYearDay
weekNo=int(((oconv(inDate,"dj")-daysToSun)+6)/7)+(daysToSun>0)
return

As the comments state, you pass a date in Pick internal format, which has been a 5-digit number since May of 1995, and you receive a number from 1 to 53 indicating which week of the year contains that date. This assumes that the week you seek starts on a Sunday and ends on a Saturday. It will result in week 1 only being 7 days long if January 1st is a Sunday, and although popular perception thinks of a year being 52 weeks, there will always be a week 53 that contains December 31st at the bare minimum.

Anybody out there got anything to add or that they did differently? And more importantly, if you've done something similar that solves some other problem that you want to share with your Forum pals, please start a new thread and show us what you've got!!

------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------

Hi Brian,

I see that OCONV(nnnnn,"DW")  gives a Friday as day 5 of the week.
That is why my brain is convinced that the week begins on a Monday.  Sunday is day 7.

My code would differ from yours and would start with OCONV(nnn or -nnn,"DJ") to give me the Julian day of the year for every (not just recent) dates, then onwards to follow your code:

*Variables
$internaldate = what ever is input
$weeknumber = 1

*Calculation
$
firstsundayoftheyear = your calculation :-)
IF
Julian day of the year > 7 THEN $weeknumber = ( (INT(OCONV($internaldate, "DJ") - $firstsundayoftheyear)/7 ) + 2) 

Take care mate, and thank you for all your help over the years, much appreciated.

Merry



------------------------------
Merry Player
Pick Multivalue Person since CMC (1978) /Microdata/McD/Northgate and onwards Reality/Zebra/Mentor/Ultimate/Universe/Unidata into Pick, Pick AP, and so on up until 2021 on mvBase/D3 - so far ....
Isle of Wight England
------------------------------

Hi Brian,

I see that OCONV(nnnnn,"DW")  gives a Friday as day 5 of the week.
That is why my brain is convinced that the week begins on a Monday.  Sunday is day 7.

My code would differ from yours and would start with OCONV(nnn or -nnn,"DJ") to give me the Julian day of the year for every (not just recent) dates, then onwards to follow your code:

*Variables
$internaldate = what ever is input
$weeknumber = 1

*Calculation
$
firstsundayoftheyear = your calculation :-)
IF
Julian day of the year > 7 THEN $weeknumber = ( (INT(OCONV($internaldate, "DJ") - $firstsundayoftheyear)/7 ) + 2) 

Take care mate, and thank you for all your help over the years, much appreciated.

Merry



------------------------------
Merry Player
Pick Multivalue Person since CMC (1978) /Microdata/McD/Northgate and onwards Reality/Zebra/Mentor/Ultimate/Universe/Unidata into Pick, Pick AP, and so on up until 2021 on mvBase/D3 - so far ....
Isle of Wight England
------------------------------
Very nice to see your contribution. and yes, from a Pick perspective, the week does run from Monday to Sunday. My code is the way it is because the view of a week by the people who asked for this was Sunday to Saturday, just like most ( actually all ) of the printed calendars hanging in my home and office.

Got anything else you've solved that you'd like to post for others to enjoy?

------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------
Very nice to see your contribution. and yes, from a Pick perspective, the week does run from Monday to Sunday. My code is the way it is because the view of a week by the people who asked for this was Sunday to Saturday, just like most ( actually all ) of the printed calendars hanging in my home and office.

Got anything else you've solved that you'd like to post for others to enjoy?

------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------

Hi Brian,

Just Googled 1st day of week, and Europe has Monday, US, Canada, and Japan has Sunday.
Here's my calendar - please crop as necessary:

Merry



------------------------------
Merry Player
Pick Multivalue Person since CMC (1978) /Microdata/McD/Northgate and onwards Reality/Zebra/Mentor/Ultimate/Universe/Unidata into Pick, Pick AP, and so on up until 2021 on mvBase/D3 - so far ....
Isle of Wight England
------------------------------
Very nice to see your contribution. and yes, from a Pick perspective, the week does run from Monday to Sunday. My code is the way it is because the view of a week by the people who asked for this was Sunday to Saturday, just like most ( actually all ) of the printed calendars hanging in my home and office.

Got anything else you've solved that you'd like to post for others to enjoy?

------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------

Hi Brian,

Yes, I know we shouldn't but I still do use "U".

Just a thought, when using U1193 or even U7193 (the same as U1193 but with 2 digit dates), does this also change the start date of the week?

It could be a very useful part of the switch US/International switch used by set-date/set-date-std/set-date-eur/set... to not only switch the date format from American to/from International, but at the same time switch the value of day 1 of the week if the US has a different week-start-day from International as well as different date formatting - subtle hint. Else we developers can do anything anyway :-)

All in all, I still think that the finance departments who use different start dates for the week, the year and even the number of months in a year (12 or 13) are the root cause of much mischief when setting out their requirements for us lot.

Take case,   Merry



------------------------------
Merry Player
Pick Multivalue Person since CMC (1978) /Microdata/McD/Northgate and onwards Reality/Zebra/Mentor/Ultimate/Universe/Unidata into Pick, Pick AP, and so on up until 2021 on mvBase/D3 - so far ....
Isle of Wight England
------------------------------
Recently a support case came in asking if there was an OCONV option to determine the week of the year of a passed date. OCONV won't do that, so I wrote a subroutine:

subroutine weekOfYear.sub(inDate, weekNo)
*
* Pass: inDate ( 5-digit internal date format )
* Return: weekNo ( 1-53 )
* Calculates which Sunday-Saturday week#
* within the year. Week 1 is only 7 days
* if January 1st is a Sunday.
*
if not(assigned(inDate)) then inDate=date()
if inDate matches "5n" else inDate=iconv(inDate,"d")
if inDate matches "5n" else inDate=date()
inYear=oconv(inDate,"dy")
begOfYear=iconv("1/1/":inYear,"d")
firstYearDay=oconv(begOfYear,"dw")
daysToSun=7-firstYearDay
weekNo=int(((oconv(inDate,"dj")-daysToSun)+6)/7)+(daysToSun>0)
return

As the comments state, you pass a date in Pick internal format, which has been a 5-digit number since May of 1995, and you receive a number from 1 to 53 indicating which week of the year contains that date. This assumes that the week you seek starts on a Sunday and ends on a Saturday. It will result in week 1 only being 7 days long if January 1st is a Sunday, and although popular perception thinks of a year being 52 weeks, there will always be a week 53 that contains December 31st at the bare minimum.

Anybody out there got anything to add or that they did differently? And more importantly, if you've done something similar that solves some other problem that you want to share with your Forum pals, please start a new thread and show us what you've got!!

------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------
The ISO begining of the week is Monday.

Here is a routine in basic:
SUBROUTINE DVP.WEEKYR(DATE,WKYR)
* DETERMINES THE WEEK OF THE YEAR THE DATE IS IN (WEEK STARTS ON MONDAY)
WKYR=''
YEAR=OCONV(DATE,'D4Y')
BOY=ICONV('1-1-':YEAR,'D');* JAN 1 OF YEAR
DOW=OCONV(BOY,'DW');* DAY OF THE WEEK ON JAN 1
GOSUB 20
WKYR=INT(((DATE-WDATE)/7)+1)
IF DATE<WDATE THEN
YEAR=YEAR-1
GOSUB 20
END ELSE
IF WKYR=53 THEN
YEAR=YEAR+1
GOSUB 20
IF WDATE GE BOY THEN
WKYR = 1
END
END
END
RETURN
20 * CALCULATE
IF DOW <4 THEN
ADD=1
END ELSE
ADD=8
END
WDATE=BOY-DOW+ADD
RETURN
END

------------------------------
Frank Diaz
Consultant
Compucot Inc
Doral FL US
------------------------------
The ISO begining of the week is Monday.

Here is a routine in basic:
SUBROUTINE DVP.WEEKYR(DATE,WKYR)
* DETERMINES THE WEEK OF THE YEAR THE DATE IS IN (WEEK STARTS ON MONDAY)
WKYR=''
YEAR=OCONV(DATE,'D4Y')
BOY=ICONV('1-1-':YEAR,'D');* JAN 1 OF YEAR
DOW=OCONV(BOY,'DW');* DAY OF THE WEEK ON JAN 1
GOSUB 20
WKYR=INT(((DATE-WDATE)/7)+1)
IF DATE<WDATE THEN
YEAR=YEAR-1
GOSUB 20
END ELSE
IF WKYR=53 THEN
YEAR=YEAR+1
GOSUB 20
IF WDATE GE BOY THEN
WKYR = 1
END
END
END
RETURN
20 * CALCULATE
IF DOW <4 THEN
ADD=1
END ELSE
ADD=8
END
WDATE=BOY-DOW+ADD
RETURN
END

------------------------------
Frank Diaz
Consultant
Compucot Inc
Doral FL US
------------------------------
I've noticed when posting code that the forum seems to remove any leading spaces thereby eliminating any code indentation in IF END statements and the like. I'll look into how to avoid this. Meanwhile, everybody know that it's not the kind contributor's fault.

I was able to find a work-around: HTML. Hit the 3 dots, then hit "HTML", then use this window to PRE-tag your source with BR tags for line feeds:
IF SOMETHING THEN
   DO THIS
   DO THAT
END


------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------
I've noticed when posting code that the forum seems to remove any leading spaces thereby eliminating any code indentation in IF END statements and the like. I'll look into how to avoid this. Meanwhile, everybody know that it's not the kind contributor's fault.

I was able to find a work-around: HTML. Hit the 3 dots, then hit "HTML", then use this window to PRE-tag your source with BR tags for line feeds:
IF SOMETHING THEN
   DO THIS
   DO THAT
END


------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------
This is my 50 cents contribuiton hahah
i use this to find week of month, the year and the bimester of the year
      SUBROUTINE RETORNA.SEMANA(WEEK, DATE,TIPO)
      PRECISION 0
      PROMPT ""
*****************************************************************
* NOME : RETORNO SEMANA DO ANO/MES OU BIMESTE PELA DATA         *
*  POR : ALBERTO                                                *
*   EM : 06/08/2021                                             *
*****************************************************************
      WEEK = 0
*     WEEK VARIAVLE OUTPUT COM 2 DIGITS
*     DATE = DIA (DATA INTERNA)
*     TIPO = 1 WEEK OF THE YEAR
*            2 WEEK OF THE MONTH
*            3 BIMESTER OF THE YEAR

      BEGIN CASE
         CASE TIPO EQ "1"
            GOSUB CALC1
         CASE TIPO EQ "2"
            GOSUB CALC2
         CASE TIPO EQ "3"
            GOSUB CALC3
         CASE 1
            WEEK = 0
      END CASE
      WEEK = OCONV(WEEK,"MR%2")
      RETURN
CALC1:
      YEAR = OCONV(DATE, 'D4Y')
      GOSUB CALC
      WEEK = INT((DATE - DAY1) / 7) + 1
      IF DATE < DAY1 THEN
         YEAR -= 1
         GOSUB CALC
         WEEK = INT((DATE - DAY1) / 7) + 1
      END ELSE
         IF WEEK = 53 THEN
            YEAR += 1
            GOSUB CALC
            IF DAY1 >= DD0101 THEN WEEK = 1
         END
      END
      RETURN
*---------------------------------------
CALC:
      DATE0101 = ICONV('01.01.' : YEAR, 'D4.') ;
* DATE OF FIRST JANUARY
      DD0101 = OCONV(DATE0101, 'DW') ;
* DAY OF WEEK OF FIRST JANUARY
      IF DD0101 < 4 THEN SHIFT = 1 ELSE SHIFT = 8
      DAY1 = DATE0101 - DD0101 + SHIFT
      RETURN

CALC2:
      WEEK = INT( OCONV(DATE,'DD') / 7 ) + 1
      RETURN
CALC3:
      WEEK = OCONV(DATE,"DQ")
      RETURN​


------------------------------
Alberto Leal
System Analyst
Millano Distribuidora de Auto Pecas Ltda
Varzea Grande MT BR
------------------------------