任何日期都应该转换为 cobol 中的月末日期吗?

发布于 2024-11-23 21:53:54 字数 86 浏览 3 评论 0 原文

我有一个要求,任何日期 (DD.MM.YYYY) 应转换为该月的最后一个日期(例如:如果日期是 20.01.1999 那么它应转换为 31.01.1999)?

I have a requirement where any date (DD.MM.YYYY) should be converted to last date of month (ex: If date is 20.01.1999 then it should convert into 31.01.1999) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

许你一世情深 2024-11-30 21:53:54

您到底遇到什么麻烦了? COBOL 还是算法?我猜是 COBOL。

我不会直接给你答案,因为你
显然倾向于语言,并且制定具体细节是有价值的
为了你自己。

这里有一些提示:

WORKING-STORAGE 中定义一个日期字段,以便您可以将日、月和年作为单独的项目挑选出来。类似于:

01 TEST-DATE.
   05 TEST-DAY     PIC 99.
   05              PIC X.
   05 TEST-MONTH   PIC 99.
   05              PIC X.
   05 TEST-YEAR    PIC 9999.

注意未命名的 PIC X 字段。它们包含日/月/年分隔符。不需要为它们提供数据名称,因为
您不需要引用它们。有时会给出这种类型的数据项
名称 FILLER,但名称是可选的。

阅读 EVALUATE 语句。这是链接
IBM Enterprise COBOL 手册。 EVALUATE 的描述在所有版本的 COBOL 中都应该类似。

移动感兴趣的日期TO TEST-DATE。现在,您可以将年、月和日作为单独的项目进行引用:TEST-DAYTEST-MONTHTEST-YEAR

使用 EVALUATE 测试月份 (TEST-MONTH)。如果该月有 30 天,则MOVE 30 到TEST-DAY。做同样的事情
每月 31 天。由于闰年,二月是一个特例。一旦确定该月份是二月,
测试 TEST-YEAR确定是否是闰年
并根据测试结果将MOVE 28 或29 移至TEST-DAY

现在,TEST-DATE 将包含您要查找的日期。将其移动到任何需要的地方。

Exactly what are you having trouble with? COBOL or the algorithm? I'm guessing its COBOL.

I'm not going to give you a direct answer because you are
obviously leaning the language and there is value in working out the specific details
for yourself.

Here are a couple of hints:

Define a date field in WORKING-STORAGE so that you can pick out the day, month and year as separate items. Something like:

01 TEST-DATE.
   05 TEST-DAY     PIC 99.
   05              PIC X.
   05 TEST-MONTH   PIC 99.
   05              PIC X.
   05 TEST-YEAR    PIC 9999.

Note the unnamed PIC X fields. These contain the day/month/year delimiters. They do not need to be given data names because
you do not need to reference them. Sometimes this type of data item is given
the name FILLER, but the name is optional.

Read up on the EVALUATE statement. Here is a link to
the IBM Enterprise COBOL manual. This description of EVALUATE should be similar in all versions of COBOL.

MOVE the date of interest TO TEST-DATE. Now you can reference the year, month and day as individual items: TEST-DAY, TEST-MONTH and TEST-YEAR.

Use EVALUATE to test the month (TEST-MONTH). If the month is a 30 day month then MOVE 30 to TEST-DAY. Do the same for
31 day months. February is a special case because of leap years. Once you have determined that the month is February,
test TEST-YEAR to determine if it is a leap year
and MOVE 28 or 29 TO TEST-DAY depending on the outcome of the test.

Now TEST-DATE will contain the date you are looking for. MOVE it to wherever it is needed.

半步萧音过轻尘 2024-11-30 21:53:54

您可以使用函数integer-of-date,它返回与任何日期相对应的整数值。假设您的输入日期采用 ddmmyyyy 格式,并且您希望输出采用相同的格式。假设日期是 20011999,而您想要的日期是 31011999。您可以按照以下步骤操作。

  • 将输入日期的月份加一。 (20*02*1999)
  • 将日期设置为 01 并使用函数 integer-of-date (*01*021999)
  • 从返回的整数中减一。
  • 使用函数 date-of-integer 它将为您提供所需的结果。

请注意,您必须再添加一张支票来处理 12 月。

You can use function integer-of-date which gives returns an integral value corresponding to any date. Assuming your input date is in ddmmyyyy format and you expect hte output in the same format. Lets say date is 20011999 and you want as 31011999. You can follow the below steps.

  • Increase the month of the input date by one. (20*02*1999)
  • Make the day as 01 and use function integer-of-date (*01*021999)
  • subtract one from the integer returned.
  • use function date-of-integer which will give you the required result.

Note here you will have to add one more check for handling December month.

明媚殇 2024-11-30 21:53:54

干得好!在此处运行代码

IDENTIFICATION DIVISION.                               
PROGRAM-ID. STACK2.                                    
DATA DIVISION.                                         
WORKING-STORAGE SECTION.                               
01 WS-DATE        PIC X(10).                           
01 WORK-DATE.                                          
   05 WORK-DAY    PIC 9(2).                            
   05             PIC X.                               
   05 WORK-MONTH  PIC 9(2).                            
   05             PIC X.                               
   05 WORK-YEAR   PIC 9(4).                            
01 MONTH-31 PIC 9(2).                                  
   88 IS-MONTH-31 VALUES 01, 03, 05, 07, 08, 10, 12.   
   88 IS-MONTH-30 VALUES 04, 06, 09, 11.               
01 WS-C           PIC 9(4) VALUE 0.                    
01 WS-D           PIC 9(4) VALUE 0.                    
PROCEDURE DIVISION.                                    
    ACCEPT WS-DATE.                                    
    MOVE WS-DATE TO WORK-DATE.                         
    DISPLAY 'ACTUALE TEST-DATE: ' WORK-DATE.             
    MOVE WORK-MONTH TO MONTH-31.                       
    EVALUATE TRUE                                      
    WHEN IS-MONTH-31                                   
    MOVE 31 TO WORK-DAY                                             
    WHEN IS-MONTH-30                                    
    MOVE 30 TO WORK-DAY                                              
    WHEN OTHER                                          
    DIVIDE WORK-YEAR BY 4 GIVING WS-C REMAINDER WS-D    
    IF WS-D NOT EQUAL 0                                 
    MOVE 28 TO WORK-DAY                                 
    ELSE                                                
    MOVE 29 TO WORK-DAY                                 
    END-IF                                              
    END-EVALUATE.  
    DISPLAY 'MODIFIED TEST-DATE: ' WORK-DATE                                     
    STOP RUN.                                           

此解决方案与@NealB的答案密切相关。

Here you go! Run the code here

IDENTIFICATION DIVISION.                               
PROGRAM-ID. STACK2.                                    
DATA DIVISION.                                         
WORKING-STORAGE SECTION.                               
01 WS-DATE        PIC X(10).                           
01 WORK-DATE.                                          
   05 WORK-DAY    PIC 9(2).                            
   05             PIC X.                               
   05 WORK-MONTH  PIC 9(2).                            
   05             PIC X.                               
   05 WORK-YEAR   PIC 9(4).                            
01 MONTH-31 PIC 9(2).                                  
   88 IS-MONTH-31 VALUES 01, 03, 05, 07, 08, 10, 12.   
   88 IS-MONTH-30 VALUES 04, 06, 09, 11.               
01 WS-C           PIC 9(4) VALUE 0.                    
01 WS-D           PIC 9(4) VALUE 0.                    
PROCEDURE DIVISION.                                    
    ACCEPT WS-DATE.                                    
    MOVE WS-DATE TO WORK-DATE.                         
    DISPLAY 'ACTUALE TEST-DATE: ' WORK-DATE.             
    MOVE WORK-MONTH TO MONTH-31.                       
    EVALUATE TRUE                                      
    WHEN IS-MONTH-31                                   
    MOVE 31 TO WORK-DAY                                             
    WHEN IS-MONTH-30                                    
    MOVE 30 TO WORK-DAY                                              
    WHEN OTHER                                          
    DIVIDE WORK-YEAR BY 4 GIVING WS-C REMAINDER WS-D    
    IF WS-D NOT EQUAL 0                                 
    MOVE 28 TO WORK-DAY                                 
    ELSE                                                
    MOVE 29 TO WORK-DAY                                 
    END-IF                                              
    END-EVALUATE.  
    DISPLAY 'MODIFIED TEST-DATE: ' WORK-DATE                                     
    STOP RUN.                                           

This solution goes hand in hand with @NealB's answer.

时光清浅 2024-11-30 21:53:54

过程“计算月结束日期”不需要对闰年或十二月进行任何检查。

   identification division.
   program-id. last-day.
   data division.
   working-storage section.
   1 test-date.
    88 test-1 value "20.01.1999".
    88 test-2 value "20.02.2004".
    88 test-3 value "20.12.2005".
     2 dd pic 99.
     2 pic x.
     2 mm pic 99.
     2 pic x.
     2 yyyy pic 9999.

   1 month-end-date binary pic 9(8) value 0.

   procedure division.
   begin.
       set test-1 to true
       perform run-test
       set test-2 to true
       perform run-test
       set test-3 to true
       perform run-test
       stop run
       .

   run-test.
       display test-date " to " with no advancing
       perform test-date-to-iso
       perform compute-month-end-date
       perform iso-to-test-date
       display test-date
       .

   compute-month-end-date.

       *> get date in following month
       compute month-end-date = function
           integer-of-date (month-end-date) + 32
           - function mod (month-end-date 100)
       compute month-end-date = function
           date-of-integer (month-end-date)

       *> get last day of target month
       compute month-end-date = function
           integer-of-date (month-end-date)
           - function mod (month-end-date 100)
       compute month-end-date = function
           date-of-integer (month-end-date)
       .

   test-date-to-iso.
       compute month-end-date = yyyy * 10000
           + mm * 100 + dd
       .

   iso-to-test-date.
       move month-end-date to dd
       .
   end program last-day.

结果:

20.01.1999 to 31.01.1999
20.02.2004 to 29.02.2004
20.12.2005 to 31.12.2005

虽然这对于新手 COBOL 程序员来说可能有点令人畏惧,但有一个简单的解释。过程“compute-month-end-date”由两个相同的部分组成,但“+32”除外。

首先考虑第二部分,它从日期整数中减去月份中的某一天,给出该月“第 0”天的整数值。这正是上个月最后一天的整数值。以下计算给出“yyyymmdd”格式的日期。

第一部分的作用相同,只是它添加 32 以获取下个月的日期,从 1 号到 4 号,具体取决于原始月份的天数。

综合起来19990120先改为19990201,再改为19990131。然后从 2004022020040303,然后是 200402292005122020060101,然后是 20051231

The procedure "compute-month-end-date" does not require any checks for leap year or December.

   identification division.
   program-id. last-day.
   data division.
   working-storage section.
   1 test-date.
    88 test-1 value "20.01.1999".
    88 test-2 value "20.02.2004".
    88 test-3 value "20.12.2005".
     2 dd pic 99.
     2 pic x.
     2 mm pic 99.
     2 pic x.
     2 yyyy pic 9999.

   1 month-end-date binary pic 9(8) value 0.

   procedure division.
   begin.
       set test-1 to true
       perform run-test
       set test-2 to true
       perform run-test
       set test-3 to true
       perform run-test
       stop run
       .

   run-test.
       display test-date " to " with no advancing
       perform test-date-to-iso
       perform compute-month-end-date
       perform iso-to-test-date
       display test-date
       .

   compute-month-end-date.

       *> get date in following month
       compute month-end-date = function
           integer-of-date (month-end-date) + 32
           - function mod (month-end-date 100)
       compute month-end-date = function
           date-of-integer (month-end-date)

       *> get last day of target month
       compute month-end-date = function
           integer-of-date (month-end-date)
           - function mod (month-end-date 100)
       compute month-end-date = function
           date-of-integer (month-end-date)
       .

   test-date-to-iso.
       compute month-end-date = yyyy * 10000
           + mm * 100 + dd
       .

   iso-to-test-date.
       move month-end-date to dd
       .
   end program last-day.

Results:

20.01.1999 to 31.01.1999
20.02.2004 to 29.02.2004
20.12.2005 to 31.12.2005

While this might be a bit daunting to the novice COBOL programmer, there is a simple explanation. The procedure "compute-month-end-date" consists of two identical parts with the exception of the "+32".

Taking the second part first, it subtracts the day of month from the integer of a date giving the integer value for the 'zeroth' day of the month. This is precisely the integer value for the last day of the prior month. The following compute gives the date in 'yyyymmdd' format.

The first part does the same, except that it adds 32 to get a date in the following month, the 1st through the 4th, depending on the number of days in the original month.

Taken togther 19990120 is first changed to 19990201, then changed to 19990131. And 20040220 to 20040303, then 20040229. 20051220 to 20060101, then 20051231.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文