Любая дата должна быть преобразована в дату конца месяца в кобол? - PullRequest
0 голосов
/ 12 июля 2011

У меня есть требование, когда любая дата (ДД.ММ.ГГГГ) должна быть конвертирована в последнюю дату месяца (например: если дата 20.01.1999, то она должна быть конвертирована в 31.01.1999)?

Ответы [ 4 ]

4 голосов
/ 12 июля 2011

Именно с чем у вас проблемы? Кобол или алгоритм? Я предполагаю, что это Кобол.

Я не собираюсь давать вам прямой ответ, потому что вы очевидно, опираясь на язык, и есть ценность в разработке конкретных деталей для себя.

Вот несколько подсказок:

Определите поле даты в 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.

MOVE дата интереса TO TEST-DATE. Теперь вы можете ссылаться на год, месяц и день как отдельные элементы: TEST-DAY, TEST-MONTH и TEST-YEAR.

Используйте EVALUATE для проверки месяца (TEST-MONTH). Если месяц - 30-дневный месяц, то от MOVE 30 до TEST-DAY. Сделать то же самое для 31 день месяца. Февраль - особый случай из-за високосных лет. Как только вы определили, что месяц февраль, тест TEST-YEAR до определяет, является ли это високосным годом и MOVE 28 или 29 ДО TEST-DAY в зависимости от результата теста.

Теперь TEST-DATE будет содержать дату, которую вы ищете. MOVE это туда, где это необходимо.

1 голос
/ 09 августа 2011

Вы можете использовать функцию integer-of-date, которая возвращает целое значение, соответствующее любой дате.Предполагая, что введенная вами дата имеет формат ddmmyyyy, и вы ожидаете, что она будет выводиться в том же формате.Допустим, дата - 20011999, а вы хотите 31011999. Вы можете выполнить следующие шаги:

  • Увеличить месяц введенной даты на единицу.(20 * 02 * 1999)
  • Задайте день как 01 и используйте функцию целочисленного значения даты (* 01 * 021999)
  • вычтите одно из возвращенного целого числа.
  • используйте функцию date-of-integer, которая даст вам требуемый результат.

Обратите внимание, здесь вам нужно будет добавить еще одну проверку для обработки месяца декабря.

0 голосов
/ 21 мая 2018

Вот, пожалуйста! Запустите код здесь

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.

0 голосов
/ 17 мая 2018

Процедура «вычислить дату окончания месяца» не требует каких-либо проверок для високосного года или декабря.

   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, есть простое объяснение.Процедура «вычислить дату окончания месяца» состоит из двух идентичных частей, за исключением «+32».

Принимая сначала вторую часть, она вычитает день месяца из целого числа датыдавая целочисленное значение для «нулевого» дня месяца.Это в точности целочисленное значение за последний день предыдущего месяца.Следующее вычисление дает дату в формате «ггггммдд».

Первая часть делает то же самое, за исключением того, что добавляется 32, чтобы получить дату в следующем месяце, с 1-го по 4-е, в зависимости от количествачисло дней в исходном месяце.

Совокупность 19990120 сначала изменяется на 19990201, затем изменяется на 1999013120040220 до 20040303, затем 20040229.20051220 до 20060101, затем 20051231.

...