【问题标题】:How to get the last day of month in a CL如何在 CL 中获取月份的最后一天
【发布时间】:2015-10-22 17:33:11
【问题描述】:

我需要获取上个月的最后一天。所以这个 CL 可以在新月的第三天运行。 我可以在 CL 中做一个 Select 语句吗(我们在 7.1 中)

或者,如果不是,还需要哪些步骤来编码并将此日期保存在一个小表格中。

【问题讨论】:

  • 您需要the last day 以便this CL can run on a 3rd day ???为什么不查找一个月的第 1、第 2 或第 3 天?

标签: ibm-midrange db2-400 rpgle


【解决方案1】:

这是一个使用 CL 计算上个月最后一天的简单示例。

PGM                                                                       

DCL        VAR(&CYMD) TYPE(*CHAR) LEN(7)                                  
DCL        VAR(&JUL) TYPE(*CHAR) LEN(5)                                   
DCL        VAR(&JUL#) TYPE(*DEC) LEN(5)                                   

RTVJOBA    CYMDDATE(&CYMD)                                                
CHGVAR     VAR(%SST(&CYMD 6 2)) VALUE('01')                               
CVTDAT     DATE(&CYMD) TOVAR(&JUL) FROMFMT(*CYMD) TOFMT(*JUL) TOSEP(*NONE)                                     
CHGVAR     VAR(&JUL#) VALUE(&JUL)                                         
CHGVAR     VAR(&JUL#) VALUE(&JUL# - 1)                                    
CHGVAR     VAR(&JUL) VALUE(&JUL#)                                         
CVTDAT     DATE(&JUL) TOVAR(&CYMD) FROMFMT(*JUL) TOFMT(*CYMD) TOSEP(*NONE)

ENDPGM

【讨论】:

  • 对于 1 月的日期应该失败(例如,'1160101'),因为 16000 在减去 1 天后无效。
【解决方案2】:

CL 实际上并不支持日期数据类型。所以它不像 SQL 或 RPGLE 那样支持日期算术。

如果您只需要确保作业在每月 3 日运行,为什么不使用作业调度程序?基本作业调度程序包含在操作系统中,或者您可能拥有高级作业调度程序 (AJS)。

对于基本的作业调度程序:

ADDJOBSCDE JOB(MTH3RDDAY) CMD(CALL PGM(MYPGM)) FRQ(*MONTHLY) 
   SCDDATE(110315) SCDTIME('08:00')  

FRQ(*MONTHLY) SCDDATE(110315) 是在每个月的 3 号重复工作的关键。

如果您选择继续让 CL 确定它是否应该运行;我建议一个 RPGLE 程序,它只返回月份中的日期。这样,返回值是一个简单的整数,您的 CL 不必尝试从日期的字符或数字表示中解析日期。

如果您需要有关该程序的帮助,请发布一个新问题并将其标记为 RPGLE。

【讨论】:

    【解决方案3】:

    从技术上讲,可能在 CL 中执行 SELECT;但它需要对 SQL CLI API 进行编码才能做到这一点。不适合没有经验且不值得努力的人。不过,CL 可以运行 INSERT 或 UPDATE 语句,然后使用 RCVF 检索插入的值。调用用 RPG、COBOL 或 C 编写的模块来执行 SQL 要容易得多。如果这些语言看起来遥不可及,那么 REXX 可以轻松执行 SQL 并将值传递给 CL。

    没有 SQL,日期数学似乎是最好的。如果您想通过 CL 获得当月的“最后一天”,最简单的方法可能是设置为下个月的第一天并减去“1 天”。下面是一个使用一对CEE* Date and TIME APIs的例子:

    pgm
    
       dcl   &fromDate1     *char        6
       dcl   &fromDate2     *char        8
       dcl   &resultDate    *char        8
    
       dcl   &qyear         *char        2
       dcl   &qmonth        *char        2
    
    
       dcl   &rtnVal1       *int
       dcl   &rtnVal2       *int
       dcl   &picStr1       *char        6   value( 'YYMMDD' )
       dcl   &picStr2       *char        8   value( 'YYYYMMDD' )
    
    
       rtvsysval   sysval( QYEAR ) rtnvar( &qyear )
       rtvsysval   sysval( QMONTH ) rtnvar( &qmonth )
    
    /* Set to a day near month-end... */
       chgvar      &fromDate1   ( &qyear *cat &qmonth *cat '28' )
    
       callprc      CEEDAYS      ( +
                                   &fromDate1     +
                                   &picStr1       +
                                   &rtnVal1       +
                                   *omit          +
                                 )
    
    /* Add enough days to guarantee in "next month"... */
       chgvar             &rtnVal2        ( &rtnVal1 + 4 )
    
       callprc      CEEDATE      ( +
                                   &rtnVal2       +
                                   &picStr2       +
                                   &fromDate2     +
                                   *omit          +
                                 )
    
    /* Set to 1st day of next month... */
       chgvar %sst( &fromDate2 7 2 )     '01'
    
       callprc      CEEDAYS      ( +
                                   &fromDate2     +
                                   &picStr2       +
                                   &rtnVal1       +
                                   *omit          +
                                 )
    
    /* Subtract 1 day to get to "last day"... */
       chgvar             &rtnVal2        ( &rtnVal1 - 1 )
    
       callprc      CEEDATE      ( +
                                   &rtnVal2       +
                                   &picStr2       +
                                   &resultDate    +
                                   *omit          +
                                 )
    
    /* Dump to show &resultDate is last-day of this month... */
    dmpclpgm
    
       return
    
    endpgm
    

    它首先将日期设置为当月的 28 日,然后添加 4 天。使用这些值可确保第一个计算日期始终在“下个月”之内。然后它获取该日期并将日期编号设置为“01”。从中减去“1 天”。

    这两个 API 使用称为“Lilian day”的表示。这只是一个整数值,表示自 1582 年 10 月 14 日以来的天数。日期可以转换为 Lilian 天数,然后简单的整数数学可以添加或减去所需的天数。生成的整数可以转换回日期值。

    您可以指定一个“图片字符串”来描述输入和输出日期的日期格式。我使用 6 字符格式作为初始输入,但使用 8 字符格式作为输出。您可以根据需要修改格式。最后,它只是简单地运行 DMPCLPGM 来显示结果。您可以设置一个 PARM() 变量以将结果返回给调用它的任何对象。

    示例代码中的结果是当前月份的 LastDay。稍作改动,可以很容易地简化为返回下个月的第 3 天。

    我考虑过在 SYSIBM.SYSDUMMY1 上创建一个表示 LAST_DAY(); 的视图但是,虽然 VIEW 在 SELECT 语句中运行良好,但它在 i 6.1 中使 RUNQRY 崩溃。尝试使它与 RCVF for CL 一起工作似乎不值得。

    我还测试了添加一个在月末运行的虚拟作业调度程序条目。然后我使用适当的 API 从条目中检索 NextSubmissionDate。这工作得很好,但太晦涩难懂,不是一个好的解决方案。当然,如果整个目的是调度一个作业,那么简单地为它添加一个调度器条目可能就是应该做的。检索 NextSubmissionDate 只是将 LastDayOfMonth 放入任何 CL 程序的一种方式。

    但如果这是目的,那么简单地拥有一个计算最后一天的 CL 模块是最直接的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 2011-11-24
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      相关资源
      最近更新 更多