COBOL - A história do ano bissexto e uma rotina - www.cadcobol.com.br




Desenvolvido por DORNELLES Carlos Alberto - Analista de Sistemas - Brasília DF. - cad_cobol@hotmail.com

A história do ano bissexto e uma rotina em COBOL

Se você usa a rotina de divisão por 4 e trabalha com datas entre 1901 e 2099, não terá problemas, ou seja, não tem motivos para alterar suas rotinas.

Porém, se quiser um cálculo mais preciso, continue lendo:

Em 1582, o papa Gregório XIII ordena um ajuste no calendário Juliano para conseguir determinar corretamente a data da Páscoa, a mais importante festa cristã.

No decurso dos séculos, havia se acumulado uma diferença de dez dias em relação ao ano solar.

A diferença se dá por causa do arredondamento feito pelo calendário Juliano, que adota o ano de 365 dias e seis horas, ao passo que o ano solar é de 365 dias, 5 horas, 48 minutos e 46 segundos.

Há uma divergência de 11 minutos e 14 segundos por ano.

Gregório XIII ordena que a quinta-feira 4 de outubro seja seguida da sexta-feira 15 de outubro e, assim, tira dez dias do ano.

Conserva um ano bissexto a cada quatro anos e determina que não são bissextos os anos seculares, ou seja, o último ano de cada século, terminado em dois zeros.
A exceção são os divisíveis por 400, como o ano 2000.

Com essa correção, levará 4 mil anos para que haja uma diferença de 1,132 dia em relação ao ano solar.

O calendário gregoriano foi aos poucos sendo adotado pela maioria dos países para uso civil e hoje em dia é considerado universal.

As nações não cristãs mantêm outro calendário para fins religiosos.

O ano de 1900 é divisível por 4 e não foi bissexto.

Bem, depois do citado acima, vamos a uma rotina em COBOL.

      *-----------------------------------------------------------------
       WORKING-STORAGE SECTION.                                         
      *-----------------------------------------------------------------
                                                                        
       01  WS-ANOWS-BISSEXTO.                                              
           05  WS-ANO                  PIC 9(004).        
           05  WS-RES4                 PIC 9(004).        
           05  WS-RES400               PIC 9(004).                     
           05  WS-RES100               PIC 9(004).                     
           05  WS-BISSEXTO             PIC 9(001).        
           05  WS-NAO-BISSEXTO         PIC 9(001).        
           05  WS-QUOCIENTE            PIC 9(004).        
           05  WS-RESTO                PIC 9(004).        

      *-----------------------------------------------------------------
       PROCEDURE DIVISION.                                              
      *-----------------------------------------------------------------

           INITIALIZE WS-ANOWS-BISSEXTO REPLACING
                      ALPHANUMERIC BY SPACES
                           NUMERIC BY ZEROES

      * Primeiro código - usando IF - código encontrado na NET
                                                                  
           DIVIDE WS-ANO BY 4 GIVING WS-QUOCIENTE 
                  REMAINDER WS-RESTO                                     

           IF  WS-RESTO NOT EQUAL ZEROS                            
               MOVE 1 TO WS-NAO-BISSEXTO                            
           ELSE                                                  
               DIVIDE WS-ANO BY 400 GIVING WS-QUOCIENTE 
                      REMAINDER WS-RESTO                          
               IF  WS-RESTO EQUAL ZEROS                            
                   MOVE 1 TO WS-BISSEXTO                            
               ELSE                                              
                   DIVIDE WS-ANO  BY 100 GIVING  WS-QUOCIENTE          
                          REMAINDER WS-RESTO                       
                   IF  WS-RESTO EQUAL ZEROS                        
                       MOVE 1 TO WS-NAO-BISSEXTO                    
                   ELSE                                          
                       MOVE 1 TO WS-BISSEXTO                        
                   END-IF                                        
               END-IF                                            
           END-IF     

      * Segundo código - usando EVALUATE - raciocínio lógico desenvolvido por DORNELLES Carlos Alberto

           DIVIDE WS-ANO BY 4   GIVING WS-QUOCIENTE REMAINDER WS-RES4   
           DIVIDE WS-ANO BY 400 GIVING WS-QUOCIENTE REMAINDER WS-RES400 
           DIVIDE WS-ANO BY 100 GIVING WS-QUOCIENTE REMAINDER WS-RES100 

           EVALUATE                                                    
              (WS-RES4   = 0) ALSO (WS-RES400 = 0) ALSO (WS-RES100 > 0)
                   WHEN TRUE  ALSO TRUE  ALSO ANY                       
                   WHEN TRUE  ALSO TRUE  ALSO TRUE                      
                   WHEN TRUE  ALSO ANY   ALSO TRUE                      
                        MOVE 1 TO WS-BISSEXTO                        
                   WHEN OTHER                                         
                        MOVE 1 TO WS-NAO-BISSEXTO                    
           END-EVALUATE
  • Isto explica porque 1900 não foi bissexto, porém 2000 foi.

  • Conforme a rotina acima, a primeira coisa então é testarmos a divisão por 4, como você já faz.
    Se não for divisível, com certeza não é bissexto e já sai da rotina.

  • Porém, ELSE, se for, devemos considerar mais coisas.

  • Já que ele é divisível por 4, vamos testar a divisão por 400.
    Se for divisível por 400, com certeza ele é bissexto e conseqüentemente já sai da rotina.

  • Se não for divisível por 400, ele ainda é divisível por 4, conforme o primeiro cálculo, e mesmo assim não será bissexto caso ele seja um ano divisível por 100.

  • Então, o ultimo cálculo é justamente este.
    Se for divisível por 100, não será bissexto.
    Não se esqueça que a rotina já saiu antes quando percebe se o ano é divisível por 400.

  • Caso não seja divisível por 100, ele ainda continua sendo divisível por 4 e é um ano sem final "00", ou seja, anos como 1980, 1984, 1988, 1992, 1996, 2004, 2008, etc.

Exemplo:
Ano Divisão por 4 = 0 Divisão por 400 = 0 Divisão por 100 > 0 Bissexto ou não
1600 TRUE TRUE ANY Sim
1700 TRUE ANY FALSE Não
1704 TRUE ANY TRUE Sim
1712 TRUE ANY TRUE Sim
2100 TRUE ANY FALSE Não
2112 TRUE ANY TRUE Sim
1900 TRUE ANY FALSE Não
1912 TRUE ANY TRUE Sim
1951 FALSE ANY TRUE Não
1961 FALSE ANY TRUE Não
1980 TRUE ANY TRUE Sim
1984 TRUE ANY TRUE Sim
1987 FALSE ANY TRUE Não
2000 TRUE TRUE ANY Sim
2006 FALSE ANY TRUE Não
2008 TRUE ANY TRUE Sim