Ir para conteúdo
Fórum Script Brasil
  • 0

Classe Calendário


Beraldo

Pergunta

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

Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,8k
×
×
  • Criar Novo...