ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Passing Date Parameters of Different Formats

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Passing Date Parameters of Different Formats

    Hi all,

    I am facing the unpleasant situation to having to pass parameters from the calling program to procedures in two service programs--one datfmt(*iso) the other datfmt(*eur).
    Passing date parameters to the procedures will fail in one or the other service program if the caller’s datfmt doesn’t match the service program’s.

    I’m afraid, the best practice would be to have the same date format everywhere, but I did miss that in the past and I am not able to change the service programs now. Until today, I thought was it was okay to mix formats if they are both 10-digits, so the compiler would do the conversion. Seems like I was wrong or I don’t draw the right conclusions from that.

    So, what is the best way to call procedures with date parameters that differ from the caller’s date format?

    Thanks
    Markus

    Last edited by Scholli2000; March 19, 2022, 01:25 PM.

  • #2
    I circumvented the problem by passing %Date(%Char(datefield):*EUR) to the *EUR service program.
    Now the parameters are passed but the embedded SQL insert won’t play along and throws RNX0112.

    In the service program, SQL is switched to *EUR by
    Code:
    exec sql set option datfmt = *EUR;


    Edit:
    What I wrote above was not the essence of what is happening.
    In RDi’s debugger I can see that the procedure in the datfmt(*EUR) service program receives the date in *EUR format, even though I created *EUR date fields in the callling program and I pass these.

    Caller
    Code:
    ctl-opt datfmt(*iso);
    ...
    dcl-s dat1_EUR date(*EUR);
    dcl-s dat2_EUR date(*EUR);
    ...
    dat1_EUR = %Date;
    dat2_EUR = %Date('1970-01-01');
    
    callp procedure( dat1_EUR: dat2_EUR);
    Service Program
    Code:
    ctl-opt datfmt(*eur);
    ...
    dcl-proc procedure export;
    
      dcl-pi procedure int(10);
        dat1 date const;            // Debugger shows dat1 in *ISO format!
        dat2 date const;
      end-pi;
    
      // Using the date fields will throw an error

    Last edited by Scholli2000; March 20, 2022, 06:22 AM.

    Comment


    • #3
      Try adding date(*EUR) to the dat1 and dat2 parameter definitions in the "dcl-pr procedure" definition the calling program uses, and the "dcl-pi procedure" definition in the called program.

      The data type the called program receives is based on the data type in the dcl-pr definition the calling program uses - i.e. the calling program converts the data into the expected type as defined by the dcl-pr definition. I don't know for a fact that the date() keyword counds in that but it's worth a try

      Comment


      • #4
        If you have the prototype in a /copy file, make sure you either specify the format explicitly for all DATE and TIME parameters, or use the /SET directive at the beginning of the copy file to set defaults for any definitions within the copy file.

        Copy file:
        Code:
        /SET DATFMT(*ISO)
        
        dcl-pr procedure int(10);
           dat1 date const; 
           dat2 date const; /
        end-pr;
        The compiler will do an implicit /RESTORE when it reaches the end of the copy file.
        /RESTORE DATFMT

        /SET, compiler directives, CCSID, temporarily changing the default, date data format, temporarily changing the default format, DATFMT keyword, temporarily changing the default format, DATE keyword, temporarily changing the default format, time data format, TIMFMT keyword, TIME keyword, CCSID keyword, definition specification, DATFMT keyword, definition specification, DATE keyword, definition specification, TIMFMT keyword, definition specification, TIME keyword, definition specification

        Comment


        • Vectorspace
          Vectorspace commented
          Editing a comment
          I didn't know that. That's better than my suggestion!

      • #5
        imho, for an exported procedure, its much better to have the date format directly on the parameter definition. I think relying on the ctl-opt is poor programming. /SET is better, but its still easy for someone to make changes, or copy the definition to create some new routine, or something like that and omit the /SET. Just put the DATFMT keyword on the parameters, it isn't that hard.

        In general, making sure your interface is explicit and used consistently is crucial.

        Relying on things such as default values (where a different program could have a different default) or external definitions (where a different program could be compiled from a different library list) is poor practice and defeats the whole point of prototypes.

        Comment


        • #6
          Thanks to you all!

          Of course, it works and calls from *EUR callers still work, too.
          I had a look at compiler directives in the past, but didn’t really see what /SET DATFMT() might be applicable for.

          Comment

          Working...
          X