View previous topic :: View next topic
|
Author |
Message |
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
Hi everyone:
Someone can provide me a source of code to calculate the week number for a given date (Is very hard to find it .)
For example :
For Today's date November 6th, 2006,
the week number is : 45
Thanks |
|
Back to top |
|
|
priyesh.agrawal
Senior Member
Joined: 28 Mar 2005 Posts: 1448 Location: Chicago, IL
|
|
|
|
Quote: |
(Is very hard to find it .) |
Not really...
I am just pasting logic... It should work... just convert it into code...
Code: |
1> COMPUTE TEMP-2 = FUNCTION INTEGER-OF-DATE(INPUT-DATE). (I/O FORMAT YYYYMMDD)
2> MOVE INPUT-DATE(1:4) TO FIRST-DATE(1:4).
3> MOVE 0101 TO FIRST-DATE(5:4).
4> COMPUTE TEMP-1 = FUNCTION INTEGER-OF-DATE(FIRST-DATE).
5> COMPUTE DIFF-IN-DAYS = TEMP-1 - TEMP-2.
6> DIVIDE DIFF-IN-DAYS BY 7 GIVING WS-NUMBER REMAINDER WS-REMAIN.
7> COMPUTE WS-OUTPUT = WS-NUMBER + 1.
8> DISPLAY "WEEK : " WS-OUTPUT. |
|
|
Back to top |
|
|
sivaprasad_kode
New User
Joined: 07 Nov 2006 Posts: 1 Location: Hyderabad
|
|
|
|
I dont think the below logic will work out. because When we use FUNCTION KEYWORD then we will not use COMPUTE statement as i thought. Please refer once for ensure.
priyesh.agrawal wrote: |
Quote: |
(Is very hard to find it .) |
Not really...
I am just pasting logic... It should work... just convert it into code...
Code: |
1> COMPUTE TEMP-2 = FUNCTION INTEGER-OF-DATE(INPUT-DATE). (I/O FORMAT YYYYMMDD)
2> MOVE INPUT-DATE(1:4) TO FIRST-DATE(1:4).
3> MOVE 0101 TO FIRST-DATE(5:4).
4> COMPUTE TEMP-1 = FUNCTION INTEGER-OF-DATE(FIRST-DATE).
5> COMPUTE DIFF-IN-DAYS = TEMP-1 - TEMP-2.
6> DIVIDE DIFF-IN-DAYS BY 7 GIVING WS-NUMBER REMAINDER WS-REMAIN.
7> COMPUTE WS-OUTPUT = WS-NUMBER + 1.
8> DISPLAY "WEEK : " WS-OUTPUT. |
|
|
|
Back to top |
|
|
priyesh.agrawal
Senior Member
Joined: 28 Mar 2005 Posts: 1448 Location: Chicago, IL
|
|
|
|
Quote: |
I dont think the below logic will work out. because When we use FUNCTION KEYWORD then we will not use COMPUTE statement as i thought. Please refer once for ensure. |
You can use FUNCTION with COMPUTE. |
|
Back to top |
|
|
die7nadal
Active User
Joined: 23 Mar 2005 Posts: 156
|
|
|
|
If you can do it in DB2 you just need to use WEEK function and it will give you an integer 1 to 54 that represents the week of the year. |
|
Back to top |
|
|
DavidatK
Active Member
Joined: 22 Nov 2005 Posts: 700 Location: Troy, Michigan USA
|
|
|
|
Toney01,
When calculating the week number, what constitutes the first week. Does the first day of the first week start on January 1, or is the week defined as Monday ? Sunday, Sunday ? Saturday? If January 1 falls on a Friday, is this in the first week of this year, or the last week of last year?
Dave |
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
Hi DavidatK:
I use Week numbers= ISO 8601 (week starts Monday), week 1 is the first week with Thursday.
For example, In year 1999, janaury 1st, falls on a friday;
and the week number for an input date = January 3th of 1999,
is week number = 53 of the last year (1998).
Look here the calendar for year 1999 and see "weekno" column:
www.timeanddate.com/calendar/custom.html?year=1999&country=27&lang=en&hol=4194329&wno=2&moon=on
So, If I use the sivaprasad_kode code to calculate week numeber for
an input date = January 3th of 1999,
I get week number = 1, which is incorrect.
So as I said before it is very tricky to find the solution.
Regards. |
|
Back to top |
|
|
karnataka
New User
Joined: 15 Sep 2006 Posts: 20 Location: bangalore
|
|
|
|
hi,
here i am sending source code . check it out with required date if its wrong or not meeting your requirement plz let me know
IDENTIFICATION DIVISION.
PROGRAM-ID. COMP3TST.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATE PIC X(10) VALUE '06/11/2006'.
01 RED-DATE REDEFINES WS-DATE.
02 DD PIC 9(2).
02 FILLER PIC X.
02 MM PIC 9(2).
02 FILLER PIC X.
02 YY PIC 9(4).
01 I PIC 99 VALUE ZERO.
01 NUM-DAYS PIC 999 VALUE ZERO.
01 NUM-WEEKS PIC 999 VALUE ZERO.
01 REM-DAYS PIC 999 VALUE ZERO.
01 REM PIC 99 VALUE ZERO.
01 CHECK-LEAP PIC 99 VALUE ZERO.
01 LEAP-YEAR PIC X(3) VALUE 'NO'.
PROCEDURE DIVISION.
100-MAIN-PARA.
DIVIDE YY BY 4 GIVING REM REMAINDER CHECK-LEAP
IF CHECK-LEAP = ZERO
MOVE 'YES' TO LEAP-YEAR
END-IF.
PERFORM VARYING I FROM 1 BY 1 UNTIL I = MM
IF I = 1 OR 3 OR 5 OR 7 OR 9 OR 10 OR 12
ADD 31 TO NUM-DAYS
END-IF
IF I = 2 AND LEAP-YEAR NOT EQUAL 'YES'
ADD 28 TO NUM-DAYS
END-IF
IF I = 2 AND LEAP-YEAR = 'YES'
ADD 29 TO NUM-DAYS
END-IF
IF I = 4 OR 6 OR 8 OR 11
ADD 30 TO NUM-DAYS
END-IF
END-PERFORM.
ADD DD TO NUM-DAYS.
DIVIDE NUM-DAYS BY 7 GIVING NUM-WEEKS REMAINDER REM-DAYS.
DISPLAY "NUM-WEEKS1=>" NUM-WEEKS.
IF REM-DAYS > ZERO
ADD 1 TO NUM-WEEKS
END-IF.
DISPLAY "WS-DATE===>" WS-DATE.
DISPLAY "RED-DATE==>" RED-DATE.
DISPLAY "DD=======>" DD.
DISPLAY "MM=======>" MM.
DISPLAY "YY=======>" YY.
DISPLAY "NUM-DAYS=>" NUM-DAYS.
DISPLAY "NUM-WEEKS=>" NUM-WEEKS.
DISPLAY "REM-DAYS=>" REM-DAYS.
STOP RUN.
output:
NUM-WEEKS1=>044
WS-DATE===>06/11/2006
RED-DATE==>06/11/2006
DD=======>06
MM=======>11
YY=======>2006
NUM-DAYS=>310
NUM-WEEKS=>045
REM-DAYS=>002
week number for a date 06/11/2006 is 45
thanks |
|
Back to top |
|
|
priyesh.agrawal
Senior Member
Joined: 28 Mar 2005 Posts: 1448 Location: Chicago, IL
|
|
|
|
Toney01 wrote: |
So as I said before it is very tricky to find the solution. |
Thanks a lot... I appreciate.
Please check it out... whether it serves the purpose... note, adjustment needs... to accomodate future dates too...
Code: |
1> COMPUTE TEMP-2 = FUNCTION INTEGER-OF-DATE(INPUT-DATE). (I/O FORMAT YYYYMMDD)
2> COMPUTE TEMP-1 = FUNCTION INTEGER-OF-DATE(CURRENT-DATE).
3> ACCEPT TODAYS-DAY FROM DAY-OF-WEEK.
3> COMPUTE DIFF-IN-DAYS = TEMP1 - TEMP2.
4> DIVIDE DIFF-IN-DAYS BY 7 GIVING WS-NUMBER REMAINDER WS-REMAIN.
5> EVALUATE WS-REMAIN
WHEN 0
MOVE TODAYS-DAY TO FINAL-DAY
WHEN 1
IF TODAYS-DAY <= 1
MOVE TODAYS-DAY + 6 TO FINAL-DAY
ELSE
MOVE TODAYS-DAY - 1 TO FINAL-DAY
END-IF
WHEN 2
IF TODAYS-DAY <= 2
MOVE TODAYS-DAY + 5 TO FINAL-DAY
ELSE
MOVE TODAYS-DAY - 2 TO FINAL-DAY
END-IF
WHEN 3
IF TODAYS-DAY <= 3
MOVE TODAYS-DAY + 4 TO FINAL-DAY
ELSE
MOVE TODAYS-DAY - 3 TO FINAL-DAY
END-IF
WHEN 4
IF TODAYS-DAY <= 4
MOVE TODAYS-DAY + 3 TO FINAL-DAY
ELSE
MOVE TODAYS-DAY - 4 TO FINAL-DAY
END-IF
WHEN 5
IF TODAYS-DAY <= 5
MOVE TODAYS-DAY + 2 TO FINAL-DAY
ELSE
MOVE TODAYS-DAY - 5 TO FINAL-DAY
END-IF
WHEN 6
IF TODAYS-DAY <= 6
MOVE TODAYS-DAY + 1 TO FINAL-DAY
ELSE
MOVE TODAYS-DAY - 6 TO FINAL-DAY
END-IF
WHEN OTHER
DISPLAY 'THROW ERROE'
6> EVALUATE FINAL-DAY
WHEN 1 DISPLAY 'MONDAY'
WHEN 2 DISPLAY 'TUESDAY'
WHEN 3 DISPLAY 'WEDNESDAY'
WHEN 4 DISPLAY 'THURSDAY'
WHEN 5 DISPLAY 'FRIDAY'
WHEN 6 DISPLAY 'SATURDAY'
WHEN 7 DISPLAY 'SUNDAY'
WHEN OTHER DISPLAY 'ERROR' |
|
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
Hi karnataka :
Your code gives me the same result as priyesh.agrawal code.
But priyesh.agrawal is funny becuase his code is not for calculating
week number . I don't know he tries to do.
I am still looking for a working code to calculate week number.
Thanks. |
|
Back to top |
|
|
priyesh.agrawal
Senior Member
Joined: 28 Mar 2005 Posts: 1448 Location: Chicago, IL
|
|
|
|
Quote: |
But priyesh.agrawal is funny becuase his code is not for calculating |
Really... ... I love working that way...
Quote: |
I don't know he tries to do. |
My fault... I preassumed you'ld be capable enough to analyze & consolidate both of the codes given earlier, as the second one is logic for the year when 1st Jan is not a Monday.
Anyway... Try the code below... It would give you week# for an INPUT DATE ... (not tested for FUTURE DATE).
Code: |
01 CURRENT-DATE PIC X(10).
01 PA-CURRENT-DATE PIC 9(8).
01 PA-INPUT-DATE PIC 9(8).
01 PA-TEMP-2 PIC 9(8).
01 PA-FIRST-DATE PIC 9(8).
01 PA-TEMP-1 PIC 9(8).
01 PA-DIFF-IN-DAYS PIC 9(8).
01 PA-NUMBER PIC 9(8).
01 PA-REMAIN PIC 9(8).
01 PA-OUTPUT PIC 9(8).
01 PARA-TEMP2 PIC 9(8).
01 PARA-TEMP1 PIC 9(8).
01 PARA-INP PIC 9(8).
01 PARA-TODAYS-DAY PIC 9(1).
01 PARA-DIFF-IN-DAYS PIC 9(8).
01 PARA-WS-NUMBER PIC 9(8).
01 PARA-WS-REMAIN PIC 9(8).
01 PARA-FINAL-DAY PIC 9(1).
PROCEDURE DIVISION.
EXEC SQL
SELECT CURRENT DATE INTO :CURRENT-DATE
FROM SYSIBM.SYSDUMMY1
END-EXEC
DISPLAY 'CURRENT DATE ACCEPTED: ' CURRENT-DATE.
MOVE CURRENT-DATE(1:4) TO PA-CURRENT-DATE(1:4).
MOVE CURRENT-DATE(6:2) TO PA-CURRENT-DATE(5:2).
MOVE CURRENT-DATE(9:2) TO PA-CURRENT-DATE(7:2).
DISPLAY 'CURRENT DATE EDITED: ' PA-CURRENT-DATE.
MOVE 'YOUR INPUT DATE' TO PA-INPUT-DATE. /* YYYYMMDD FORMAT
DISPLAY 'INPUT DATE : 'PA-INPUT-DATE.
COMPUTE PA-TEMP-2 = FUNCTION INTEGER-OF-DATE(PA-INPUT-DATE).
MOVE PA-INPUT-DATE(1:4) TO PA-FIRST-DATE(1:4).
MOVE PA-INPUT-DATE(1:4) TO PARA-INP(1:4).
MOVE '0101' TO PARA-INP(5:4).
PERFORM PA-PARA.
COMPUTE PA-TEMP-1 = FUNCTION INTEGER-OF-DATE(PA-FIRST-DATE).
COMPUTE PA-DIFF-IN-DAYS = PA-TEMP-1 - PA-TEMP-2.
DIVIDE PA-DIFF-IN-DAYS BY 7
GIVING PA-NUMBER REMAINDER PA-REMAIN.
IF PA-NUMBER = 0
MOVE 52 TO PA-OUTPUT
ELSE
COMPUTE PA-OUTPUT = PA-NUMBER + 1
END-IF.
DISPLAY "WEEK : " PA-OUTPUT.
GOBACK.
PA-PARA.
DISPLAY 'PARA-INP: 'PARA-INP.
COMPUTE PARA-TEMP2 = FUNCTION INTEGER-OF-DATE(PARA-INP).
DISPLAY 'INP DATE AFTER FUNC: 'PARA-TEMP2.
COMPUTE PARA-TEMP1 =
FUNCTION INTEGER-OF-DATE(PA-CURRENT-DATE).
DISPLAY 'CUR DATE AFTER FUNC: 'PARA-TEMP1.
ACCEPT PARA-TODAYS-DAY FROM DAY-OF-WEEK.
DISPLAY 'TODAYS DAY: 'PARA-TODAYS-DAY.
COMPUTE PARA-DIFF-IN-DAYS = PARA-TEMP1 - PARA-TEMP2.
DISPLAY 'DIFFE IN TODAYS & INP: 'PARA-DIFF-IN-DAYS
DIVIDE PARA-DIFF-IN-DAYS BY 7
GIVING PARA-WS-NUMBER REMAINDER PARA-WS-REMAIN.
DISPLAY 'REMAINDER : 'PARA-WS-REMAIN.
EVALUATE PARA-WS-REMAIN
WHEN 0
MOVE PARA-TODAYS-DAY TO PARA-FINAL-DAY
WHEN 1
IF PARA-TODAYS-DAY <= 1
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY + 6
ELSE
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY - 1
END-IF
WHEN 2
IF PARA-TODAYS-DAY <= 2
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY + 5
ELSE
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY - 2
END-IF
WHEN 3
IF PARA-TODAYS-DAY <= 3
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY + 4
ELSE
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY - 3
END-IF
WHEN 4
IF PARA-TODAYS-DAY <= 4
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY + 3
ELSE
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY - 4
END-IF
WHEN 5
IF PARA-TODAYS-DAY <= 5
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY + 2
ELSE
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY - 5
END-IF
WHEN 6
IF PARA-TODAYS-DAY <= 6
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY + 1
ELSE
COMPUTE PARA-FINAL-DAY = PARA-TODAYS-DAY - 6
END-IF
WHEN OTHER
DISPLAY 'THROW ERROR'
END-EVALUATE.
DISPLAY 'PARA-FINAL-DAY: 'PARA-FINAL-DAY.
EVALUATE PARA-FINAL-DAY
WHEN 1 DISPLAY '1 MONDAY'
MOVE '0101' TO PA-FIRST-DATE(5:4)
WHEN 2 DISPLAY '1 TUESDAY'
MOVE '0107' TO PA-FIRST-DATE(5:4)
WHEN 3 DISPLAY '1 WEDNESDAY'
MOVE '0106' TO PA-FIRST-DATE(5:4)
WHEN 4 DISPLAY '1 THURSDAY'
MOVE '0105' TO PA-FIRST-DATE(5:4)
WHEN 5 DISPLAY '1 FRIDAY'
MOVE '0104' TO PA-FIRST-DATE(5:4)
WHEN 6 DISPLAY '1 SATURDAY'
MOVE '0103' TO PA-FIRST-DATE(5:4)
WHEN 7 DISPLAY '1 SUNDAY'
MOVE '0102' TO PA-FIRST-DATE(5:4)
WHEN OTHER DISPLAY 'ERROR'
END-EVALUATE.
DISPLAY 'PA-FIRST-DATE: ' PA-FIRST-DATE.
EXIT. |
|
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
Hi priyesh.agrawal :
This is much better , your code works almost perfect, but I have small problem, when I test your code with these parameters :
Input date, Jan 3th, 1999 :
MOVE 19990103 TO PA-INPUT-DATE
Todays day from day of the week: Wednesday :
MOVE 3 TO PARA-TODAYS-DAY
Current date : November 8th, 2006 :
COMPUTE PA-CURRENT-DATE = 20061108
I got week number 52 , which is incorrect, should be 53, see the calendar:
www.timeanddate.com/calendar/custom.html?year=1999&country=27&lang=en&hol=4194329&wno=2&moon=on
Can you please, fix this small problem?
Thanks so much for your help.
Regards |
|
Back to top |
|
|
priyesh.agrawal
Senior Member
Joined: 28 Mar 2005 Posts: 1448 Location: Chicago, IL
|
|
|
|
Yes man... I realised that later...
If JANUARY 1ST of YEAR (INPUT-DATE) is not a MONDAY
AND
Your INPUT DATE is also in that hanging week (prior to 1st monday of the year)
This code would not work for 53rd week, but for 52nd (which is hard coded).
To include this logic also, I'll have to do the same calculation for the previous years initial dates and which causes an iteration/loop.
Anyway, some more thoughts and it should be done. for now, I m sorry, it doesnt fulfill 100%. |
|
Back to top |
|
|
sreenatha
New User
Joined: 21 Dec 2005 Posts: 7
|
|
|
|
tony01,
try this logic:
1) lnput date say 1999-jan-03 ( this is a sunday , hence it has to be counted as a day in 53rd week of previous year)
2) check the first day of the given year i.e 1999-jan-01 and this turns out to be friday
hence the logic will be as follws;
evaluate first-day
when 'monday'
no change in first day
when 'tuesday'
add +6 days to first-day
when 'wednesday'
add +5 days to first-day
when 'thursday'
add +4 days to first-day
when 'friday'
add +3 days to first-day
when 'saturday'
add +2 days to first-day
when 'sunday'
add+1 days to first-day
end-evaluate
hence in this case, as 1999-jan-01 was friday , the date we have to consider for calculating week is 1999-jan-04
3) now find the integer difference between the input date and first-date
i.e integer-of-date(input-date)-integer-of-date(first-date)
4) if result of step-3 is negative
week = 53
else
week=(result of step-3/7) + 1
end-if
didn't check it but hope this should work fine |
|
Back to top |
|
|
DavidatK
Active Member
Joined: 22 Nov 2005 Posts: 700 Location: Troy, Michigan USA
|
|
|
|
*
* THIS ROUTINE WILL CALCULATE THE WEEK NUMBER OF THE YEAR.
* THE WEEK IS DEFINED AS MOMDAY - SUNDAY. THE FIRST WEEK IS
* THE WEEK JANUARY 4 OF THE YEAR FALLS INTO. (JANUARY 1 FALLS
* ON A MONDAY - THURSDAY)
*
* IF THE INPUT DATE FALLS BEFORE THE START OF THE FIRST WEEK,
* THEN THE DATE WILL FALL INTO THE LAST WEEK OF THE PREVIOUS YEAR.
*
* IF THE INPUT DATE FALLS AFTER THE END OF THE LAST WEEK, THEN
* THE DATE WILL FALL INTO THE FIRST WEEK OF THE NEXT YEAR.
*
Code: |
WORKING-STORAGE SECTION.
01 INPUT-DATE-YYYYMMDD PIC 9(8).
01 FILLER REDEFINES INPUT-DATE-YYYYMMDD.
05 INPUT-YYYY PIC 9(4).
05 INPUT-MM PIC 9(2).
05 INPUT-DD PIC 9(2).
01 JAN01-CURR-YEAR PIC 9(8) VALUE 99990101.
01 FILLER REDEFINES JAN01-CURR-YEAR.
05 JAN01-YYYY PIC 9(4).
05 FILLER PIC 9(4).
01 DEC31-CURR-YEAR PIC 9(8) VALUE 99991231.
01 FILLER REDEFINES DEC31-CURR-YEAR.
05 DEC31-YYYY PIC 9(4).
05 FILLER PIC 9(4).
01 INTEGER-DATE PIC 9(8) COMP.
01 INTEGER-OF-INPUT-DATE PIC 9(8) COMP.
01 INTEGER-OF-JAN01-CURRYEAR PIC 9(8) COMP.
01 INTEGER-OF-MON-FIRSTWEEK PIC 9(8) COMP.
01 INTEGER-OF-DEC31-CURRYEAR PIC 9(8) COMP.
01 INTEGER-OF-SUN-LASTWEEK PIC 9(8) COMP.
01 INTEGER-DAYS-YTD PIC 9(8) COMP.
01 WS-WEEK-OF-YEAR PIC 9(2) COMP-3.
01 WS-DAY-OF-WEEK PIC 9 COMP-3.
01 WS-JAN01-DAY-OF-WEEK PIC 9 COMP-3.
01 WS-CURR-YYYYWW.
05 WS-CURR-YYYY PIC 9(4).
05 FILLER PIC X VALUE '-'.
05 WS-CURR-WW PIC 9(2).
01 WS-PREV-YYYY PIC 9(4) COMP-3.
01 DAY-OF-FIRST-WEEK-OFFSETS.
05 MON-OFFSET.
10 DAY-NAME PIC X(3) VALUE 'MON'.
10 JAN01-CURR-OFFSET PIC S9 VALUE +0 COMP-3.
10 DEC31-CURR-OFFSET PIC S9 VALUE -1 COMP-3.
05 FILLER.
10 FILLER PIC X(3) VALUE 'TUE'.
10 FILLER PIC S9 VALUE -1 COMP-3.
10 FILLER PIC S9 VALUE -2 COMP-3.
05 FILLER.
10 FILLER PIC X(3) VALUE 'WED'.
10 FILLER PIC S9 VALUE -2 COMP-3.
10 FILLER PIC S9 VALUE -3 COMP-3.
05 FILLER.
10 FILLER PIC X(3) VALUE 'THR'.
10 FILLER PIC S9 VALUE -3 COMP-3.
10 FILLER PIC S9 VALUE +3 COMP-3.
05 FILLER.
10 FILLER PIC X(3) VALUE 'FRI'.
10 FILLER PIC S9 VALUE +3 COMP-3.
10 FILLER PIC S9 VALUE +2 COMP-3.
05 FILLER.
10 FILLER PIC X(3) VALUE 'SAT'.
10 FILLER PIC S9 VALUE +2 COMP-3.
10 FILLER PIC S9 VALUE +1 COMP-3.
05 FILLER.
10 FILLER PIC X(3) VALUE 'SUN'.
10 FILLER PIC S9 VALUE +1 COMP-3.
10 FILLER PIC S9 VALUE +0 COMP-3.
01 FILLER REDEFINES DAY-OF-FIRST-WEEK-OFFSETS.
05 FILLER OCCURS 7 TIMES.
10 WS-DAY-OF-WEEK-NUM PIC X(3).
10 CURR-JAN01-OFFSET PIC S9 COMP-3.
10 CURR-DEC31-OFFSET PIC S9 COMP-3.
01 TABLE-2.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
10 FILLER PIC S9(3) COMP-3 VALUE 0.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 53.
10 FILLER PIC S9(3) COMP-3 VALUE 53.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 53.
10 FILLER PIC S9(3) COMP-3 VALUE 52.
05 FILLER.
10 FILLER PIC S9(3) COMP-3 VALUE 52.
10 FILLER PIC S9(3) COMP-3 VALUE 52.
01 TABLE-2R REDEFINES TABLE-2.
05 FILLER OCCURS 7 TIMES.
10 LST-YY-NLY-WW-VAL PIC S9(3) COMP-3.
10 LST-YY-LY-WW-VAL PIC S9(3) COMP-3.
01 MISC.
05 DIV PIC S9(4) COMP-3.
05 REM PIC S9(4) COMP-3.
LINKAGE SECTION.
01 PARM-DATA.
05 PARM-LENGTH PIC S9(4) COMP.
05 PARM-DATE PIC 9(8).
05 FILLER PIC X(92).
PROCEDURE DIVISION USING PARM-DATA.
PROGRAM-START.
MOVE PARM-DATE TO INPUT-DATE-YYYYMMDD.
MOVE INPUT-YYYY TO JAN01-YYYY,
DEC31-YYYY,
WS-CURR-YYYY.
MOVE INPUT-DATE-YYYYMMDD TO INTEGER-DATE.
COMPUTE INTEGER-OF-INPUT-DATE
= FUNCTION INTEGER-OF-DATE (INTEGER-DATE).
MOVE JAN01-CURR-YEAR TO INTEGER-DATE.
COMPUTE INTEGER-OF-JAN01-CURRYEAR
= FUNCTION INTEGER-OF-DATE (INTEGER-DATE).
DIVIDE INTEGER-OF-JAN01-CURRYEAR
BY 7 GIVING WS-WEEK-OF-YEAR REMAINDER WS-DAY-OF-WEEK.
IF WS-DAY-OF-WEEK = 0
THEN
MOVE 7 TO WS-DAY-OF-WEEK
END-IF.
MOVE WS-DAY-OF-WEEK TO WS-JAN01-DAY-OF-WEEK.
COMPUTE INTEGER-OF-MON-FIRSTWEEK
= INTEGER-OF-JAN01-CURRYEAR + CURR-JAN01-OFFSET
(WS-DAY-OF-WEEK).
MOVE DEC31-CURR-YEAR TO INTEGER-DATE.
COMPUTE INTEGER-OF-DEC31-CURRYEAR
= FUNCTION INTEGER-OF-DATE (INTEGER-DATE).
DIVIDE INTEGER-OF-DEC31-CURRYEAR
BY 7 GIVING WS-WEEK-OF-YEAR REMAINDER WS-DAY-OF-WEEK.
IF WS-DAY-OF-WEEK = 0
THEN
MOVE 7 TO WS-DAY-OF-WEEK
END-IF.
COMPUTE INTEGER-OF-SUN-LASTWEEK
= INTEGER-OF-DEC31-CURRYEAR + CURR-DEC31-OFFSET
(WS-DAY-OF-WEEK).
IF INTEGER-OF-INPUT-DATE > INTEGER-OF-SUN-LASTWEEK
THEN
ADD +1 TO WS-CURR-YYYY
MOVE +1 TO WS-CURR-WW
ELSE
COMPUTE INTEGER-DAYS-YTD
= INTEGER-OF-INPUT-DATE
- INTEGER-OF-MON-FIRSTWEEK
DIVIDE INTEGER-DAYS-YTD
BY 7 GIVING WS-WEEK-OF-YEAR REMAINDER WS-DAY-OF-WEEK
ADD 1 TO WS-WEEK-OF-YEAR
MOVE WS-WEEK-OF-YEAR TO WS-CURR-WW
END-IF.
IF INTEGER-OF-INPUT-DATE < INTEGER-OF-MON-FIRSTWEEK
THEN
SUBTRACT 1 FROM WS-CURR-YYYY GIVING WS-PREV-YYYY
DIVIDE WS-PREV-YYYY BY 4 GIVING DIV REMAINDER REM
IF REM > 0
THEN
MOVE LST-YY-NLY-WW-VAL (WS-JAN01-DAY-OF-WEEK)
TO WS-CURR-WW
ELSE
MOVE LST-YY-LY-WW-VAL (WS-JAN01-DAY-OF-WEEK)
TO WS-CURR-WW
END-IF
SUBTRACT 1 FROM WS-CURR-YYYY
END-IF.
DISPLAY INPUT-DATE-YYYYMMDD ' = ' WS-CURR-YYYYWW.
GOBACK.
|
This is set up to be used as a subroutine. You can drive it from JCL
//JSOO100 EXEC PGM=WEEKNUM,PARM=?20061106?
OR FROM ANOTHER PROGRAM
01 parm-data.
05 parm-len pic s9(4) comp value 8.
05 parm-date pic 9(8) value 20061106.
05 filler pic x(92).
CALL ?WEEKNUM? using parm-date.
I didn?t spend very much time making it pretty, you can do that.
Dave |
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
Back to top |
|
|
DavidatK
Active Member
Joined: 22 Nov 2005 Posts: 700 Location: Troy, Michigan USA
|
|
|
|
tony01,
I retested the code and got
.SARPAGE 4
.
.19981231 = 1998-53
.19990101 = 1998-53
.19990102 = 1998-53
.19990103 = 1998-53
.19990104 = 1999-01
I'll re-check the code I posted to see if I missed anything while cut/paste.
Dave |
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
Yes please.
Let me know.
Thanks a lot for your efforts. |
|
Back to top |
|
|
DavidatK
Active Member
Joined: 22 Nov 2005 Posts: 700 Location: Troy, Michigan USA
|
|
|
|
Tony01,
I checked the code that I posted, if there is a difference, it escapes me.
This works on my processor ????????
Are you sure you ran this code?
Dave |
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
DavidatK:
I found a small BUG in your program, and this is why
I couldn't have the correct result from my input date 19990103.
BEFORE : Condition less than
IF INTEGER-OF-INPUT-DATE < INTEGER-OF-MON-FIRSTWEEK
THEN
SUBTRACT 1 FROM WS-CURR-YYYY GIVING WS-PREV-YYYY
.
.
END-IF.
AFTER : Condition MUST BE : LESS EQUAL
IF INTEGER-OF-INPUT-DATE <= INTEGER-OF-MON-FIRSTWEEK
THEN
SUBTRACT 1 FROM WS-CURR-YYYY GIVING WS-PREV-YYYY
.
.
END-IF.
Now It works like a charm, thanks a lot for your code and for your efforts.
I appreciated very much your help.
Regards |
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
DavidatK:
I tested year 2000 (leap year) for December 3th, 2000
I got weeknum = 49, which is wrong , should be weeknum = 48
December 30th, 2000
I got 2001-01, which is wrong , should be 2000-52
December 31st, 2000
I got 2001-01, which is wrong , should be 2000-52
In fact the code is NOT STABLE, I think is missing more logic, but should be tricki.
Anayway, still looking a TRUE solution.
Thanks
|
|
Back to top |
|
|
DavidatK
Active Member
Joined: 22 Nov 2005 Posts: 700 Location: Troy, Michigan USA
|
|
|
|
Tony01,
I've got to stand by this code being correct. I even backloaded the code I posted and compiled that. Results of that test are:
Code: |
.20001201 = 2000-48
.20001202 = 2000-48
.20001203 = 2000-48
.20001204 = 2000-49
.20001205 = 2000-49
.20001229 = 2000-52
.20001230 = 2000-52
.20001231 = 2000-52
.20010101 = 2001-01
|
Methinks you missed something when you copied the code
What compiler are you using?
Dave |
|
Back to top |
|
|
tony01 Currently Banned New User
Joined: 14 Sep 2005 Posts: 9
|
|
|
|
Hi Dave:
In fact, I am working with Mainframe os/390, but the problem I think is that I don't have the FUNCTION INTGER-OF-DATE , so I am using a home routine to calculate INTEGR-OF-DATE, maybe this is the problem.
I am not sure of that.
Thanks |
|
Back to top |
|
|
DavidatK
Active Member
Joined: 22 Nov 2005 Posts: 700 Location: Troy, Michigan USA
|
|
|
|
Tony01,
One of the common problems with calculating the integer-of-date is that most applications are concerned with the number of days between two given dates within a normal business environment, where you are normally not concerned with dates prior to 1901 or after 2099 and are not concerned with the day of the week. The error usually comes in when calculating leap-years. Normally we consider a leap year to be a year evenly divisible by 4, and for the year between 1901 and 2099 this is true. However, if the year is evenly divisible by 100 and not evenly divisible by 400, it is NOT a leap year. Hence, 1600, 2000, 2400 are leap years, 1700, 1800, 1900, 2100 are NOT leap years. If this is not taken into account and your base year is prior to 1901, the day of the week is thrown off. Check your home code for integer-of-year to make sure it takes this into account.
Dave |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
Dave,
excellent response, the technical was right on; i am envious of your diplomatic skills. |
|
Back to top |
|
|
|