• 0
Sign in to follow this  
Beraldo

Classe Calendário

Question

Essa semana desenvolvi um calendário para um cliente e resolvi postar o código-fonte básico do funcionamento dele. :D

Além dos feriados fixos, também são exibidos os móveis. ;)

Vocês verão que há a função MostrarCalendario() e MontarCalendario(). O motivo pelo qual essas duas funções existem é que o cliente pediu para exibir o mês atual e o próximo, então eu MontarCalendario() duas vexzes em MostrarCalendario(). Mantive dessa forma para, caso alguém pecise fazer isso, já está no meio do caminho. :D

Adicionei a opção de mostrar o calendário em português ou inglês, porém ainda falta traduzir os feriados. Mas isso fica para outra hora. :P

Lembrando que desenvolvi para PHP 5.0 ou superior. ;)

<?php

#############################################
#                                           #
#  Autor: Roberto Beraldo Chaiben (Beraldo) #
#    E-Mail: rbchaiben[arroba]gmail.com     #
#                                           #
#############################################

/*******************************************/
/*  Desenvolvido para PHP 5.0 ou superior  */
/******************************************/

/*
   Classe para mostrar o calendário de qualquer mês e ano em língua portuguesa ou inglesa.
*/

class Calendario
{
    
    //firiados fixos
    protected $feriados = array (
                                "01/01" => "Confraternização Universal",
                                "21/04" => "Tiradentes",
                                "01/05" => "Dia do Trabalho",
                                "07/09" => "Independência do Brasil",
                                "12/10" => "Nossa Senhora Aparecida",
                                "02/11" => "Finados",
                                "15/11" => "Proclamação da República",
                                "25/12" => "Natal"
                               );
    
    
    
    /*
       Função __construct()
       Esta função é chamada automaticamente aqo instanciar o objeto Calendario. Ela adiciona à variável $feriados as datas dos feriados móveis e seus respectivos nomes.
       
       O parâmetro 'ano' existe para que sejam geradas corretamente as datas dos feriados móveis. Se ele não for passado, o ano corrente será considerado.
    */
    public function __construct($ano = NULL)
    {
        $ano = ($ano == NULL) ? date("Y") : $ano;
        
        //adição de feriados móveis ao calendário
        
        //Páscoa
        $data_pascoa = date ("d/m/Y", easter_date($ano));
        list ($dia_pascoa, $mes_pascoa, $ano_pascoa) = explode ("/", $data_pascoa);
        $this->feriados[$dia_pascoa . "/" . $mes_pascoa] = "Páscoa";
        
        //carnaval => Páscoa - 47 dias
        $data_carnaval = $this->SubtrairDias ($data_pascoa, 47);
        list ($carnaval_dia, $carnaval_mes, $carnaval_ano) = explode ("/", $data_carnaval);
        $this->feriados[$carnaval_dia . "/" . $carnaval_mes] = "Carnaval";
    
        //Corpus Christi => Páscoa + 60 dias
        $data_corpus = $this->SomarDias ($data_pascoa, 60);
        list ($corpus_dia, $corpus_mes, $corpus_ano) = explode ("/", $data_corpus);
        $this->feriados[$corpus_dia . "/" . $corpus_mes] = "Corpus Christi";
        
        //Paixão de Cristo (Sexta-feira Santa) => Páscoa - 2 dias
        $data_paixao_cristo = $this->SubtrairDias ($data_pascoa, 2);
        list ($paixao_cristo_dia, $paixao_cristo_mes, $paixao_cristo_ano) = explode ("/", $data_paixao_cristo);
        $this->feriados[$paixao_cristo_dia . "/" . $paixao_cristo_mes] = "Paixão de Cristo";
        
        /*
           O cálculo da data do Dia das Mães está como comentário, por não se tratar de um feriado. Caso queira que ele seja exibido no caléndário, basta descomentar esta parte do código,retirando o '\/*' da linha 71 e o '*\/' da linha 85. 
        */
        
        /*
        //Dia Das Mães => Segundo Domingo de Maio
        //para encontrar a data do Dia Das mães, procura-se o primeiro domingo de maio e soma-se 7 unidades ao dia encontrado. 
        
        for ($m = 1; $m <= 15; $m++)
        {
             if (date ("w", mktime (0, 0, 0, 5, $m, $ano)) == 0)
            {
                //soma 7 dias ao primeiro domingo
                $dia_maes = $m + 7;
                break;
            }
        }
        $this->feriados[$dia_maes . "/05"] = "Dia das Mães";
        */
        
        
        /*
           O cálculo da data do Dia dos Pais está como comentário, por não se tratar de um feriado. Caso queira que ele seja exibido no caléndário, basta descomentar esta parte do código,retirando o '\/*' da linha 92 e o '*\/' da linha 106. 
        */
        
        /*
        //Dia Dos Pais => Segundo Domingo de Agosto
        //para encontrar a data do Dia Dos Pais, procura-se o primeiro domingo de agosto e soma-se 7 unidades ao dia encontrado. 
        
        for ($m = 1; $m <= 15; $m++)
        {
             if (date ("w", mktime (0, 0, 0, 8, $m, $ano)) == 0)
            {
                //soma 7 dias ao primeiro domingo
                $dia_pais = $m + 7;
                break;
            }
        }
        $this->feriados[$dia_pais . "/08"] = "Dia dos Pais";
        */
        
    }//fim da função __construct()
    
    
    /*
       Função MostrarCalendario()
       Exibe o calendário na tela.
       O parâmetro 'mês' corresponde ao mês exibido no calendério. Se nenhum parâmetro for passado, o mês corrente será considerado. Esse parâmetro deve ser um inteiro entre 1 e 12.
       O parâmetro 'ano' corresponde ao ano exibido no calendário. Se não for especificado, será considerado o ano corrente. 'ano' deve ser especificado com quatro dígitos.
       O parêmetro 'lang' define a língua em que o calendário será exibido. 'pt' exibe o calendário em português; 'en', em inglês. Se esse parâmetro não for informado, será exibido em português.
    */
    
    public function MostrarCalendario($mês = NULL, $ano = NULL, $lang = "pt")
    {
        $lang = strtolower ($lang);
        //verifica o valor de $lang, para definir setlocale()
        switch ($lang)
        {
            case "pt":
                setlocale (LC_TIME, "pt_BR", "ptb", "portuguese-brazil", "bra");
                break;
            case "en":
                setlocale (LC_TIME, "en_US", "en");
                break;
            default:
                setlocale (LC_TIME, "pt_BR", "ptb", "portuguese-brazil", "bra");
                break;
        }
        
        //verificação do mês
        if ($mês != NULL)
        {
            if (!is_int ($mês) || $mês < 1 || $mês > 12)
            {
                echo "<p>Função <strong>". __FUNCTION__ ."</strong>: Valor incorreto para o parâmetro \"mês\".</p>";
                return false;
            }
        }
        else
        {
            $mês = strftime ("%m");
        }
        
        //verificação do ano
        if ($ano != NULL)
        {
            if (!is_int ($ano) || strlen($ano) != 4)
            {
                echo "<p>Função <strong>". __FUNCTION__ ."</strong>: Valor incorreto para o parâmetro \"ano\"</p>";
                return false;
            }
        }
        else
        {
            $ano = strftime ("%Y");
        }
        
                //exibe o calendário    
        $this->MontarCalendario ($mês, $ano);
        
                
        
    }
    
    
    /*
       Função MontarCalendario()
       Monta o calendário, para que seja exibido quando a função for chamada pela MostrarCalendario().
    */
    protected function MontarCalendario($mês, $ano)
    {
        //dia de hoje
        $dia = strftime ("%d");
        
        //nome do mês
        $nome_mes = strftime ("%B", mktime (0, 0, 0, $mês, 1, $ano));
        
        //total de dias do mês corrente
        $dias_mes = date("t", mktime (0, 0, 0, $mês, 1, $ano));
        
        //tabela que exibe o calendário
        echo "
        <table width=\"210\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" style=\"border: solid 1px #000;\">
          <tr>
            <td colspan=\"7\" style=\"text-align: center; background: #ccc;\">
              ". ucwords ($nome_mes) ." - ". $ano ."
            </td>
          </tr>
          <tr>\r\n";
        
        //mostra os dias da semana abreviadamente (Dom a Sáb ou Sun a Sat)
        for ($i = 1; $i <= 7; $i++)
        {
           //escolhe-se o mês de julho, pois ele se inicia em um domingo
           $abrev_dia = ucwords (strftime ("%a", mktime (0, 0, 0, 7, $i, 2007)));
           echo "<td style=\"border-bottom: solid 1px #000;". (($abrev_dia == "Dom") ? " color: red;" : "") ."\">". $abrev_dia ."</td>\r\n";
        }
        echo "</tr>\r\n";

        $k = 1;
        for ($i = 1; $i <= 6; $i++)
        {
               echo "<tr>\r\n";
            for ($j = 0; $j < 7; $j++)
            {
                 $dias = date("w", mktime(0, 0, 0, $mês, $k, $ano));
                 
                if ($dias == $j AND $k <= $dias_mes)
                {
                       
                         $domingo = "";
                         $feriado = "";
                      if ($dias == 0)
                             $domingo = " color: red;";
                         
                         //verifica os feriados
                         foreach ($this->feriados as $data_feriado => $nome_feriado)
                         {
                          list ($dia_feriado, $mes_feriado) = explode ("/", $data_feriado);
                          if ($k == $dia_feriado AND $mês == $mes_feriado)
                          {
                              $feriado = " color: red; cursor: help;";
                              $feriado_nome = $nome_feriado;    
                          }
                      }
                      
                      
                     $hoje = "";
                     if ($k == $dia AND $mês == strftime("%m") AND $ano == strftime("%Y"))
                         $hoje = " background: #ccc;";
                   
                   echo "<td style=\"text-align: center;". ($feriado . $domingo . $hoje . "\"")  . (($feriado != '') ? " title=\"". $feriado_nome ."\"" : "") .">" . sprintf("%02d", $k) . "</td>\r\n";
                       
                      $k++;
                }
                else
                    echo "<td> </td>\r\n";
                    
            }   
            echo "</tr>"; 
        }
        echo "</table>\r\n";
    }
    
    
    /*
       Função SomarDias()
       Usada para calcular a data de feriados móveis.
       Esta função adiciona 'n_dias' à data 'data', passado como argumento, a qual deve estar no formato dd/mm/yyyy ou yyyy-mm-dd.
       O argumento 'forma' serve para especificar o formato da data retornada. Ele pode conter os seguintes valores:
       
       "pt" => Retornará a data no formato DD/MM/YYYY
       "en" => Retornará a data no formato YYYY-MM-DD
       
       Se 'forma' não for especificada, adotar-se-á a forma brasileira (pt).
    */
    public function SomarDias ($data, $n_dias, $forma = "pt")
    {
        if (!is_int ($n_dias))
        {
            echo "<p>Função <strong>". __FUNCTION__ ."</strong>: o argumento \"n_dias\" deve ser um número inteiro.</p>";
            return false;
        }
        
        $forma = strtolower ($forma);
        if ($forma != "en" AND $forma != "pt")
            $forma = "pt";
        
        if (preg_match ("/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/", $data))
            list ($dia, $mês, $ano) = explode ("/", $data);
        elseif (preg_match ("/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $data))
            list ($ano, $mês, $dia) = explode ("-", $data);
        else
        {
            echo "<p>Função <strong>". __FUNCTION__ ."</strong>: Formato de data inválido (". $data .").</p>";
            return false;
        }
        
        //transforma $n_dias em segundos
        //86400 = 60 * 60 * 24
        $segs_n_dias = $n_dias * 86400;
        
        // tranforma $data em timestamp
        $segs_data = strtotime ($ano . "-" . $mês . "-" . $dia);
        
        $segs_nova_data = $segs_data + $segs_n_dias;
        
        $nova_data = ($forma == "pt") ? date("d/m/Y", $segs_nova_data) : date("Y-m-d", $segs_nova_data);
        
        return $nova_data;
        
        
    }
    
    
    
    /*
       Função SubtrairDias()
       Usada para calcular a data de feriados móveis.
       Esta função subtrai 'n_dias' da data 'data', passado como argumento, a qual deve estar no formato dd/mm/yyyy ou yyyy-mm-dd.
       O argumento 'forma' serve para especificar o formato da data retornada. Ele pode conter os seguintes valores:
       
       "pt" => Retornará a data no formato DD/MM/YYYY
       "en" => Retornará a data no formato YYYY-MM-DD
       
       Se 'forma' não for especificada, adotar-se-á a forma brasileira (pt).
    */
    public function SubtrairDias ($data, $n_dias, $forma = "pt")
    {
        if (!is_int ($n_dias))
        {
            echo "<p>Função <strong>". __FUNCTION__ ."</strong>: O argumento \"n_dias\" deve ser um número inteiro.</p>";
            return false;
        }
        
        $forma = strtolower ($forma);
        if ($forma != "en" AND $forma != "pt")
            $forma = "pt";
        
        if (preg_match ("/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/", $data))
            list ($dia, $mês, $ano) = explode ("/", $data);
        elseif (preg_match ("/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $data))
            list ($ano, $mês, $dia) = explode ("-", $data);
        else
        {
            echo "<p>Função <strong>". __FUNCTION__ ."</strong>: Formato de data inválido (". $data .").</p>";
            return false;
        }
        
        //transforma $n_dias em segundos
        //86400 = 60 * 60 * 24
        $segs_n_dias = $n_dias * 86400;
        
        // tranforma $data em timestamp
        $segs_data = strtotime ($ano . "-" . $mês . "-" . $dia);
        
        $segs_nova_data = $segs_data - $segs_n_dias;
        
        $nova_data = ($forma == "pt") ? date("d/m/Y", $segs_nova_data) : date("Y-m-d", $segs_nova_data);
        
        return $nova_data;
        
        
    }
    
}

?>
Forma de usar:
$Cal = new Calendario;
$Cal->MostrarCalendario();
$Cal->MostrarCalendario(2, 2008);
$Cal->MostrarCalendario(2, 2007, "en");
$Cal->MostrarCalendario(2, 2008, "en");

O código está bem comentado, mas se alguém tiver dúvidas, pode postá-las!

Abraços

Share this post


Link to post
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this