Uso eficiente Zend_Date

Zend_Locale, Zend_Date, Zend_Calendar, Zend_Translate, Zend_Currency, Zend_Measure

Moderador: diegotremper

Uso eficiente Zend_Date

Mensagempor kaleu » Qua Jul 23, 2008 9:43 am

Olá pessoal, gostaria de iniciar este tópico para que possamos compartilhar dicas de como utilizar com eficiência o Zend_Date.

Por Exemplo, para imprimir a data atual basta fazer:
Código: Selecionar tudo
$date = new Zend_Date();
$data = $date->toString("dd/MM/yyyy");
echo $data;


Simples, mas não utiliza "timezones"...além de existirem outras opções para impressão das datas em formatos como "ISO", "W3C", etc.
Acho que seria interessante discutirmos qual a melhor maneira de trabalharmos com datas.

Obrigado.
kaleu
Membro
 
Mensagens: 16
Data de registro: Seg Jun 30, 2008 11:14 am
Localização: Florianópolis, SC

Re: Uso eficiente Zend_Date

Mensagempor lucasm » Qui Jul 24, 2008 8:41 am

Kaleu,

Estou na fase de estudo da framework, com bastante dificuldade para usar datas.

Eu quero exibí-las no formato do usuário, usando Zend_Locale. Mas o banco de dados que estou utilizando (MySql) exige data no formato W3C.

A solução que estou usando (não sei se é a melhor): antes de salvar um registro, criei um método converteDatas nas classes que herdam Zend_Db_Table. Esse método pega as datas no formato do usuário e converte para o formato W3C. Ainda não resolvi o problema na hora de recuperar uma data do banco: exibo uma data recuperada do MySql no formato W3C e não no formato do usuário (como deveria ser).

Gostaria da opinião de colegas com mais experiência em Zend.

abraços,
Lucas Mauricio C. e Martins
Gigante da Colina, a maior paixão!

Ajude a Combater o Spam! - Help fighting spam!
lucasm
Membro
 
Mensagens: 10
Data de registro: Seg Abr 07, 2008 11:14 am

Re: Uso eficiente Zend_Date

Mensagempor iagoeiro » Dom Ago 03, 2008 5:31 pm

Prezado Lucasm,

Como a configuração de seu banco de dados exige que a data esteja no formato W3C, para trabalhar com datas no ZF você precisar fazer o seguinte:

Vamos supor que seu formulário post datas nos seguintes formatos '3/8/2008' ou '03/08/2008' .
Ambos os formatos são agradáveis ao usuario mas não compatível com sua base de dados mysql, então no ZF você deve criar um objeto Zend_Date e adicionar a data que recebeu no post, da seguinte forma:

Código: Selecionar tudo
require_once 'Zend/Date.php';
$dataPostada = '03/08/2008'; //data recuperada via $_GET | $_POST.
$date = new Zend_Date($dataPostada, 'pt_BR');


Pronto você acaba de criar um objeto ZF de data, nesse objeto não importa o formato de data que você postou ou vai precisar ter de saída pois ele
é um objeto do tipo Zend_Date e nesse tipo de objeto todas as datas são timestamp Unix que é um tipo inteiro contendo o número de segundos entre a Era Unix (January 1 1970 00:00:00 GMT) e o tempo especificado.
exemplo:
echo('<pre>');
print_r($date);

Código: Selecionar tudo
Zend_Date Object
(
    [_Locale:private] => Zend_Locale Object
        (
            [_Locale:private] => pt_BR
            [_Codeset:private] =>
        )

    [_Fractional:private] => 0
    [_Precision:private] => 3
    [_unixTimestamp:private] => 1217732400
    [_timezone:private] => America/Sao_Paulo
    [_offset:private] => 10800
    [_syncronised:private] => 0
    [_dst:protected] => 1
)


Para você recuperar a data no formato W3C necessário para armazenar no seu banco de dados, você deve usar o metodo:
$date->get(Zend_Date::W3C);
que irá lhe retornar:
2008-08-03T00:00:00-03:00

Até esse ponto conseguimos receber a data do usuário e converter para o formato exigido pelo mysql.

Vamos agora então criar o processo inverso, recuperar a data do mysql e mostrar para o usuário em um padrão amigável.

Já sabemos que a data é guardada no mysql no formato W3C
2008-08-03T00:00:00-03:00.
Para que possamos manipular essa data e a recuperar nos mais variados formatos precisamos novamente criar um objeto
Zend_Date e passar como argumento a data que recuperamos do banco de dados, da seguinte forma:

$dataRecuperadaMYSQL = '2008-08-03T13:53:25-03:00';
$date = new Zend_Date($dataRecuperadaMYSQL, 'pt_BR');

e podemos recuperar a data no formato que desejamos usando o metodo get():

$date->get(Zend_Date::DATES); = 03/08/2008
$date->get(Zend_Date::DATE_FULL) = domingo, 3 de agosto de 2008;

Veja mais opções de constantes para manipular Datas:
http://framework.zend.com/manual/en/zend.date.constants.html#zend.date.constants.list.table-8

Bom, até aqui acho que deu para entender o funcionamento básico do objeto Zend_Date, pois conseguimos receber uma data e a converter para o padrão W3C e guarda-lo na base de dados e fazer o processo inverso também, vamos ver agora como proceder para tratar hora:

Existe muitas maneiras que se pode fazer isso, vou mostar a mais simples e o que mais normalmente acontece de se ter a data separada da hora no cadastro, então para adicionar um tempo (hora:minutos:segundos) a uma data você deve utilizar o metodo set() da seguinte forma:

$date->set('13:53:25', Zend_Date::TIMES);

Código: Selecionar tudo
$date = new Zend_Date('03/08/2008', 'pt_BR');
$date->set('13:53:25', Zend_Date::TIMES);
echo($date->get(Zend_Date::W3C));


Para recuperar a hora use também o get():
$date->get(Zend_Date::TIMES) = 13:53:25

Veja mais opções de constantes para manipular Time:
http://framework.zend.com/manual/en/zend.date.constants.html#zend.date.constants.list.table-5


Agora vamos falar um pouco sobre timezone e locale:

Muitas pessoas se confundem muito com essas duas questões, o time zone trata da diferença de horários no mundo e o locale trata da forma como as informações são mostradas pelo mundo a afora, por exemplo:

$date = new Zend_Date('03/08/2008', 'pt_BR'); = 03/08/2008
$date = new Zend_Date('03/08/2008', 'de_AT'); = 03.08.2008
$date = new Zend_Date('03/08/2008', 'en_US'); = Mar 8, 2008

Para entender um pouco mais sobre locale, de uma lida em outro post que fiz tratando dessa questão
http://www.zfbrasil.com/forum/viewtopic.php?f=49&t=68#p285

Vamos então voltar a questão do timezone.
Nosso planeta é dividido em muitas partes e cada uma dessas divisões tem um fuso horário diferente veja o mapa para entender melhor:
http://www.lib.utexas.edu/maps/world_maps/timezones_2001.jpg

Para configurar o timezone adequado a seu projeto você pode fazer de duas maneiras:
Primeira opção seria adicionar no bootstrap o metodo php date_default_timezone_set('America/Rio_Branco');

A segunda opção seria tratar a questão em nível de objeto que pode ser feito através do metodo setTimeZone():
$date = new Zend_Date('03/08/2008', 'pt_BR');
$date->setTimezone('America/Sao_Paulo');

O Brasil tem varias regiões defininas no como ponto de referência para timezone, segue algumas:
America/Sao_Paulo
America/Rio_Branco
America/Recife
America/Bahia
America/Boa_Vista
America/Campo_Grande
America/Manaus
America/Cuiaba
America/Belem
America/Porto_Acre
America/Porto_Velho

Veja as listas de todas as regiões do mundo:
http://br.php.net/manual/pt_BR/timezones.php

Bom acho que isso ajuda um pouco, sei que tem outras questões que posteriormente e conforme a necessidade podemos tratar também, tais como
horário de verão no mundo, amanhecer e entardecer, cálculo de tempo entre duas datas e outras coisinhas mais.

Por hora um forte abraços a todos,
Israel Agoeiro
Avatar de usuário
iagoeiro
Participante
 
Mensagens: 94
Data de registro: Seg Fev 25, 2008 1:38 am
Localização: São Paulo - Brasil

Re: Uso eficiente Zend_Date

Mensagempor yhayho » Sex Ago 14, 2009 2:50 am

Blz
yhayho
Membro
 
Mensagens: 9
Data de registro: Dom Dez 21, 2008 9:41 am

Re: Uso eficiente Zend_Date

Mensagempor mmsweb » Sex Ago 21, 2009 9:35 pm

E ai iagoeiro! ótima resposta...

coloca ela la no forum de tutoriais!!!

abraços!
Abçs,

MMSWEB Internet - Soluções Interativas, Inteligentes e Eficientes.
Avatar de usuário
mmsweb
Participante
 
Mensagens: 45
Data de registro: Qui Dez 11, 2008 7:05 pm

Re: Uso eficiente Zend_Date

Mensagempor tsantos » Qua Fev 03, 2010 1:49 pm

Sei que estou ressuscitando o tópico mas deixo aqui a minha contribuicao.

Segue abaixo um trecho de código para calcular a idade do usuario e se hoje é aniversário dele:

Código: Selecionar tudo
        //YYYY-dd-mm
       $age = new Zend_Date('1984-28-11'); //data de nascimento
       $now = new Zend_Date();

       if ($now->compareMonth($age) == 0 && $now->compareDay($age) == 0) {
          $this->view->isBirthday = 'Happy birthday to you!';
       }

       $yearsOld = (int) $now->sub($age, Zend_Date::YEAR);

       /**
        * Deverá diminuir um ano na data calculada se:
        *
        * o mês atual é menor do que o mês da data de aniversário OU
        * o mês atual é igual ao mês do aniversário E o dia atual é menor do
        * que o dia da data de aniversário.
        */
        if ($now->compareMonth($age) == -1 || ($now->compareMonth($age) == 0 && $now->compareDay($age) == -1)) {
          $yearsOld--;
       }


Essa foi a maneira que encontrei de fazer as operações. Portanto, se existirem meios mais agradáveis não deixem de postar.

:)
tsantos
Membro
 
Mensagens: 5
Data de registro: Qua Ago 27, 2008 12:35 am


Retornar para Internacionalização (i18n) e Localização (l10n)

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 0 visitantes