Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to increment month in a date keeping 2 digits? 4

Status
Not open for further replies.

Dan01

Programmer
Jun 14, 2001
439
US
If you have 20020101 as an initial date, how would you increment the date one month at a time, while maintaining the "0" if the month is 01 through 09? I've thought of this approach, but there may be a simpler way:

01 TEST-DATE.
05 D-YEAR PIC X(4).
05 D-MONTH PIC X(2).
05 D-DAY PIC X(2).

EVALUATE TRUE
WHEN D-MONTH = "01"
MOVE "02" TO D-MONTH
WHEN D-MONTH = "02"
MOVE "03" TO D-MONTH
WHEN D-MONTH = "03"
MOVE "04" TO D-MONTH
ETC...
END-EVALUATE

Thanks, Dan.
 

01 TEST-DATE.
05 D-YEAR PIC 9(4).
05 D-MONTH PIC 9(2).
05 D-DAY PIC 9(2).

add 1 to d-month.

If you definately need the field in x-format, then add the
following

01 TEST-NUM-DATE REDEFINES TEST-DATE.
05 NUM-D-YEAR PIC 9(4).
05 NUM-D-MONTH PIC 9(2).
05 NUM-D-DAY PIC 9(2).

ADD 1 TO NUM-D-MONTH.

 
Thanks krulle. So the 0 is maintained during the add if the final number is 9 or less? Dan.
 
Presumably the initial date is never going to be the end of a month. If it is, you'll need something a little more complex.

Marc
 
Thanks Marc. The day won't change, only the month. Dan.
 
Dan01:
How about something like this...

01 TEST-DATE PIC 9(08).
01 FILLER REDEFINES TEST-DATE.
05 D-YEAR PIC 9(4).
05 D-MONTH PIC 9(2).
05 D-DAY PIC 9(2).

ADD 100 TO TEST-DATE.

You only talked about months 01-09. Is that all you need to worry about? If you have the chance of starting out with December you'll need to add something like this after you add 100.

IF D-MONTH = 13
ADD 1 TO D-YEAR
MOVE 1 TO D-MONTH
END-IF.

I don't know how particular you want to be, but you need to realize that if your starting date is 20030131 and you increment the month you're going to get a date of 20030231 which is an invalid date. You didn't say anything about being concerned if the day was correct.
 
Sorry Lunker. I wasn't complete in laying out the background of the issue. The date will be taken from a job using ACCEPT. Only the month will be changed in that date by a looping process. Thanks, Dan.
 
Thanks krulle. Worked like a charm. Dan.
 
Dan -

Glad you resolved your problem.

I often remind students and others that a COBOL group item is by definition an ALPHANUMERIC item. So you can define a date this way:
Code:
01 TEST-DATE.             
  05 D-YEAR.
     10 D-YEAR-NUM  PIC 9(4).
  05 D-MONTH.
     10 D-MONTH-NUM PIC 9(2).
  05 D-DAY.
     10 D-DAY-NUM   PIC 9(2).
01 TEST-DATE-NUM REDEFINES TEST-DATE PIC 9(08).
[\CODE]

I understand the need to have an elementary item that defines the whole field.  It would be necessary/useful to have if, for instance, you're moving it to an edited field (e.g. XXXX/XX/XX).  I'm not sure why you would need both ALPHANUMERIC and NUMERIC definitions of the year, month, and day.  PIC 9 is USAGE DISPLAY in this case and can be moved to PIC X fields just fine.

Can anyone further my education and give me a real-life situation where both are truly necessary?

Regards.

Glenn
 
Glenn:
You're looking for a reason to have both a pic 9 and pic x definition right.

I teach COBOL to new programmers at our site and as a general rule I tell them never to mix pic x and pic 9. The reason is that numeric and alphanumeric data is handled differently. I agree with you that moving pic 9(08) to pic x(08) will work fine. But what I find when people do that is they don't pay attention and then later they try to move pic 9(09) to pic x(08) assuming that it will truncate on the left. But the receiving field dictates the move and it does an alpha move truncating on the left.

Moves also work differently when working with group items. Even though they are assumed to be pic x they don't always work the same as an elementary field when you're mixing with pic 9 - especially if the pic 9 is packed.

So as a general rule I teach not to mix modes just so they don't get themselves into trouble without knowing it.
 
Glenn:
I'm having a hard time typing today. In the second paragraph where I was giving an example of moving a pic 9(09) to pic x(08) I meant to say the move is alphanumeric which means it will fill from left to right and truncate on the right. So if you had a value 123456789 in a Pic 9(09) field and moved it to pic x(08) you would end up with 12345678 in the pic x(08) field.

I have seen people do this in programs ready for production and they thought the receiving field would have 23456789. If the receiving field were defined as 9(08), they would have.

That's why we recommend not mixing modes.
 
Lunker -

I agree; mixing modes is not a good thing and I generally avoid it. But I do think it is useful for people to understand these issues, especially if they have to maintain code written by others.

I'm always careful to remind folks that it's not the alphanumeric/numeric that gets folks into trouble when moving an ALPHANUMERIC field to a numeric, computational field. The problem is when it's a GROUP to ELEMENTARY move. COBOL does NOT convert or do insertion editing on those moves, only on elementary moves.

Code:
 01  WS-NUM  PIC S9(5) COMP-3.
 01  WS-ALPHA-GROUP.
     05  WS-ALPHA PIC X(4) VALUE "1234".
...
     MOVE WS-ALPHA-GROUP TO WS-NUM
     MOVE WS-ALPHA       TO WS-NUM
[\CODE]
The first move doesn't work as expected, the second one does.

Of course, if you don't mix modes, these questions don't come up.

Regards.

Glenn
 
Glenn:
I agree. It is always good to understand what is happening. It makes for a better debugger when they know how it works and can then figure out what's going on.

The example you show is a good one. I've seen people try that because they think a group is ppic x so it should work the same way as an elementary pic x but does not.

Sounds like we're in agreement.
 
my 2 cents

01 alphadate.
05 filler pic x(8).
01 numdate redefines alhpdate.
05 filler pic x(2).
05 numyr pic 99.
05 nummo pic 99.
05 filler pic x(2).

add 1 to nummo.
if numo > 12
add 1 to numyr
move 01 to nummo.

good code for 97 more years.
Enjoy
Bob
 
Bob:
Why not eliminate the 2 byte filler at the beginning and make year 9(04)? Then it's good until the year 9999.
 
Hi Dan,

One addition to all the excellent advice you've gotten to date.

Since you're relying on a user to input the date, it's your reponsiblity to validate that date. You have to ask:

What is the result if the date contains an alpha digit? The month, or day contains an invalid numeric value? The result of my add creates an invalid month value?

Regards, Jack.
 
Thanks Jack. You are right. I've gotten a lot of excellent advice in this post. Everyone's generosity is most appreciated including your own. Actually the date will come automatically from a job, and will not be manually entered. So thankfully that won't be an issue. Dan.
 
Glenn, Lunker,

regarding the discussion of mixing modes in Cobol, I generally agree that if possible doing so should be avoided, but...

sometimes it is useful. So, if you must do it, then I believe that it is good to call attention to the fact that you are treating the same entity in different ways by defining multiple versions of the same thing (i.e. alphanumeric group item for an elementary numeric item) AND using the appropriate definition in the correct context.

Taking the date example that started this discussion, in some circumstances you may wish to represent that some part of the date is "out of range" or "masked". In such cases, you would not be able to do the following:

Code:
MOVE SPACES TO D-YEAR-NUM
or
Code:
MOVE "**" TO D-DAY-NUM

but you could do...

Code:
MOVE SPACES TO D-YEAR
and
Code:
MOVE "**" TO D-DAY

So, sometimes I think the group level definition of elementary item is called for. "Code what you mean,
and mean what you code!
But by all means post your code!"

Razalas
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top