コマンド

24. CVTDAT 日付形式変換コマンドの利用 (2)

CVTDAT を利用した日付計算の例を示す。
この例では本日から2週間後の日付を計算する例である。
サンプル・ソースでは System i の日付形式が YMD であっても、または MDY, DMY であっても
正しく動作するように配慮されている。

【サンプル: TESTDCVT4】
----------------------------------------------------------------------------------
0001.00              PGM                                                          
0002.00 /*---------------------------------------------------------*/             
0003.00 /*   TESTDCVT4 :   日付の変換テスト 4:                     */             
0004.00 /*       本日から2週間後の日付を算出する                  */             
0005.00 /*---------------------------------------------------------*/             
0006.00              DCL        VAR(&DATE6) TYPE(*CHAR) LEN(6)                    
0007.00              DCL        VAR(&TODATE10) TYPE(*CHAR) LEN(10)                
0008.00              DCL        VAR(&DATFMT) TYPE(*CHAR) LEN(3)                   
0009.00              DCL        VAR(&QDATFMT) TYPE(*CHAR) LEN(4)                  
0010.00              DCL        VAR(&DAYSU) TYPE(*CHAR) LEN(8)                    
0011.00              DCL        VAR(&DEC08) TYPE(*DEC) LEN(8 0)                   
0012.00                                                                           
0013.00              RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE6)                      
0014.00              RTVSYSVAL  SYSVAL(QDATFMT) RTNVAR(&DATFMT)                   
0015.00              CHGVAR     VAR(&QDATFMT) VALUE('*' *CAT &DATFMT)             
0016.00              CVTDAT     DATE(&DATE6) TOVAR(&DAYSU) FROMFMT(&QDATFMT) +    
0017.00                           TOFMT(*JUL) TOSEP(*NONE)                        
0018.00              CHGVAR     VAR(&DEC08) VALUE(&DAYSU)                         
0019.00              CHGVAR     VAR(&DEC08) VALUE(&DEC08 + 14)                    
0020.00              CHGVAR     VAR(&DAYSU) VALUE(&DEC08)                         
0021.00  ZEROS:      IF         COND(%SST(&DAYSU 1 1) *EQ '0') THEN(DO)           
0022.00              CHGVAR     VAR(&DAYSU) VALUE(%SST(&DAYSU 2 7) *CAT ' ')      
0023.00              GOTO       ZEROS                                             
0024.00              ENDDO                                                        
0025.00              CVTDAT     DATE(&DAYSU) TOVAR(&TODATE10) FROMFMT(*JUL) +     
0026.00                           TOFMT(*YYMD) TOSEP(/)                           
0027.00              SNDPGMMSG  MSG(' 本日 ' *CAT &DATE6 *CAT +                   
0028.00                           ' から2週間後は ' *CAT &TODATE10 *TCAT +       
0029.00                           ' です。 ') MSGTYPE(*DIAG)                      
0030.00              ENDPGM                                                       
----------------------------------------------------------------------------------
【実行】
  > CALL TESTDCVT4                               
     本日 120529 から2週間後は 2012/06/12 です。
【解説】

System i が どのような日付形式で登録されていたとしても

0014.00              RTVSYSVAL  SYSVAL(QDATFMT) RTNVAR(&DATFMT)                      
0015.00              CHGVAR     VAR(&QDATFMT) VALUE('*' *CAT &DATFMT) 

によって元の日付形式を取得してから

0016.00              CVTDAT     DATE(&DATE6) TOVAR(&DAYSU) FROMFMT(&QDATFMT) +       
0017.00                           TOFMT(*JUL) TOSEP(*NONE) 

で、元の日付形式を指定して日数に変換しているので、どのような場合でも正しく日数を
取得することができる。
次に、

0018.00              CHGVAR     VAR(&DEC08) VALUE(&DAYSU)                            
0019.00              CHGVAR     VAR(&DEC08) VALUE(&DEC08 + 14)                       
0020.00              CHGVAR     VAR(&DAYSU) VALUE(&DEC08)  

によって 日数に +14 して2週間後の日数(*JUL)を計算している。

0021.00  ZEROS:      IF         COND(%SST(&DAYSU 1 1) *EQ '0') THEN(DO)              
0022.00              CHGVAR     VAR(&DAYSU) VALUE(%SST(&DAYSU 2 7) *CAT ' ')         
0023.00              GOTO       ZEROS                                                
0024.00              ENDDO 

によって先行のゼロを消去している。これによって正しい日数が取得できたので

0025.00              CVTDAT     DATE(&DAYSU) TOVAR(&TODATE10) FROMFMT(*JUL) +     
0026.00                           TOFMT(*YYMD) TOSEP(/) 

によって日数( *JUL ) から *YYMD で日付セパレータ / を使って 2012/06/12 のように
表現するようにしている。