Como configurar o fuso horário do MySQL por nomes.

Se você pretende usar time zones ou fusos horários no MySQL, pelo nome, é bom ter certeza de que as tabelas contendo estas informações estão atualizadas e povoadas — prontas para uso.
Se você não tem certeza de que os nomes das zonas de fusos horários estão disponíveis — tanto para a configuração do servidor, quanto para uso dos clientes (que pretendem ajustar seus próprios fusos), — faça o seguinte teste, dentro do console do cliente MySQL:

SELECT COUNT(*) FROM mysql.time_zone_name;
+----------+
| COUNT(*) |
+----------+
|        0 |
+----------+

No exemplo, acima, a função COUNT() retornou o valor 0 — o que indica a impossibilidade de se referenciar às zonas de fuso horário pelos seus nomes.
O segundo caso, do exemplo abaixo, fica evidenciado que a tabela de nomes de zonas de fusos horários está presente:

SELECT COUNT(*) FROM mysql.time_zone_name;
+----------+
| COUNT(*) |
+----------+
|     1790 |
+----------+

Neste texto, vamos nos debruçar sobre uma solução para o primeiro caso.
Fusos horários no MySQL

O processo de instalação do MySQL cria as tabelas de fusos horários (time zone tables), mas não carrega os valores para dentro delas — ou seja, não as povoa. Você precisa fazer isto manualmente, caso queira se referir aos fusos horários por nome.


  • Sistemas operacionais, como Linux, FreeBSD, Solaris e OSX têm sua própria base de dados zoneinfo, que consiste em um conjunto de arquivos descritores dos fusos horários. Neste caso, você pode usar o utilitário mysql_tzinfo_to_sql para preencher as tabelas de zonas de fusos.
    Para usuários Windows, é possível fazer o download do pacote de banco de dados de zonas de fusos horários para MySQL em http://dev.mysql.com/downloads/timezones.html.
    Neste texto, uso como exemplo, o sistema operacional GNU/Linux Ubuntu 14.04 LTS — portanto, o procedimento deve ser o mesmo para qualquer sistema baseado no Debian.

No Ubuntu 14.04 os arquivos zoneinfo, pode ser encontrados em /usr/share/zoneinfo/:

ls /usr/share/zoneinfo/
Africa      Chile    Factory    Iceland      MET       posix       UCT
America     CST6CDT  GB         Indian       Mexico    posixrules  Universal
Antarctica  Cuba     GB-Eire    Iran         MST       PRC         US
Arctic      EET      GMT        iso3166.tab  MST7MDT   PST8PDT     UTC
Asia        Egypt    GMT0       Israel       Navajo    right       WET
Atlantic    Eire     GMT-0      Jamaica      NZ        ROC         W-SU
Australia   EST      GMT+0      Japan        NZ-CHAT   ROK         zone.tab
Brazil      EST5EDT  Greenwich  Kwajalein    Pacific   Singapore   Zulu
Canada      Etc      Hongkong   Libya        Poland    SystemV
CET         Europe   HST        localtime    Portugal  Turkey

Veja, a seguir, como trabalhar com estes arquivos.

Como povoar o banco de dados usando o mysql_tzinfo_to_sql

Este processo é muito simples e rápido. Use a seguinte linha de comando:

mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql -u root -p mysql

O que o comando acima faz é “jogar” todos os arquivos do diretório /usr/share/zoneinfo/ (pode variar de acordo com o seu sistema), bem como de seus subdiretórios, dentro do banco de dados mysql, nas tabelas apropriadas.
Uma vez feito este procedimento, já é possível se referir aos fusos horários, dentro do MySQL, por seus nomes.

A documentação oficial do MySQL (link ao final do tópico), adverte para não baixar e usar pacotes, caso seu sistema operacional já tenha um banco de dados zoneinfo. Use o aplicativo utilitário mysql_tzinfo_to_sql.

Após a execução do comando mysql_tzinfo_to_sql, é recomendável reiniciar o servidor de banco de dados, para evitar que ele use dados de fusos horários contidos na cache:

sudo service mysql restart

Como ajustar o fuso horário no MySQL

Veja como é possível ajustar o fuso, referindo-se ao nome:

SELECT * FROM mysql.time_zone_name WHERE Name LIKE '%Fortaleza%';
_
+-------------------------+--------------+
| Name                    | Time_zone_id |
+-------------------------+--------------+
| America/Fortaleza       |          113 |
| posix/America/Fortaleza |          710 |
| right/America/Fortaleza |         1307 |
+-------------------------+--------------+
3 rows in set (0.00 sec)
SET time_zone='America/Fortaleza';
Query OK, 0 rows affected (0.00 sec)

SELECT @@time_zone;
_
+-------------------+
| @@time_zone       |
+-------------------+
| America/Fortaleza |
+-------------------+
1 row in set (0.00 sec)

No artigo Como ajustar o fuso horário ou a timezone no MySQL, você pode encontrar uma relação completa de fusos horários do Brasil e de outros países de língua portuguesa — além disto, há outros exemplos de uso e ajuste dos fusos horários no MySQL.

Referências: https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html#time-zone-installation.

Como ajustar o fuso horário ou timezone no MySQL

O MySQL vai usar as datas e horas do sistema, caso não seja instruído a proceder de outra maneira. Se você estiver rodando um aplicativo cliente em uma zona com fuso horário diferente do do servidor MySQL, pode alterar manualmente a hora, com a função DATE_ADD().
Linguagens de script, como PHP, Python ou Perl, têm suas próprias funções para ajustar o fuso horário no cliente.
Neste artigo vamos abordar uma técnica manual, que pode ser útil para resolver o problema rapidamente e outras voltadas para quem deseja “resolver e esquecer” — ou seja, usar uma solução definitiva.

O sistema operacional, sobre o qual o servidor MySQL está rodando, afeta os valores usados pelo banco de dados — se seu fuso horário estiver ajustado para SYSTEM. Neste caso, o ajuste pode ser feito no sistema operacional.
Se você substituir o arquivo de sistema de definição de fuso horário, /etc/localtime por outro que tenha regras diferentes, será necessário reiniciar o mysqld para que suas informações sejam atualizadas no servidor MySQL.

fusos horários - mysql

Ajuste o fuso horário com DATE_ADD()

Esta pode ser uma forma rápida de obter uma solução — em que basta adicionar ou deduzir a quantidade de horas necessárias para obter o valor de data/hora correto.
Veja como acrescentar 2 horas a todos os horários de uma coluna em uma tabela (CadastroClientes):

SELECT NomeCliente AS Cliente,
    ->  TIME(DataCadastroCliente) AS "Check in time",
    ->  TIME(DATE_ADD(DataCadastroCliente, INTERVAL +2 HOUR)) AS "Hora local do Check in"
    ->  FROM CadastroClientes LIMIT 10;
+--------------------+---------------+------------------------+
| Cliente            | Check in time | Hora local do Check in |
+--------------------+---------------+------------------------+
| Christen Wiggins   | 10:03:39      | 12:03:39               |
| Justine Howard     | 21:44:49      | 23:44:49               |
| Brenda Ellis       | 11:58:30      | 13:58:30               |
| Hayfa Mendoza      | 20:52:29      | 22:52:29               |
| Kylie Mckay        | 09:43:57      | 11:43:57               |
| Fredericka Fuller  | 15:33:51      | 17:33:51               |
| Gretchen Bartlett  | 17:02:54      | 19:02:54               |
| Fiona Chen         | 20:28:20      | 22:28:20               |
| Lacy Holland       | 02:00:29      | 04:00:29               |
| Karleigh Contreras | 01:06:55      | 03:06:55               |
+--------------------+---------------+------------------------+
10 rows in set (0.00 sec)

O artigo Como converter horas em segundos minutos e dias aborda a função TIME() e dá outros exemplos de operações aritméticas envolvendo as horas.
Esta abordagem não é a melhor, quando a carga de serviço é grande. Além disso, fazer “trabalho manual e repetitivo” vai contra a nossa cultura hacker. 😉
Veja, nos próximos tópicos, algumas formas de solucionar o problema mais eficientemente.

Ajuste a variável time_zone de fuso horário no MySQL

Captura de tela - MySQL set global time_zone
Clique para ver detalhes.

A variável time_zone pode ser ajustada direto no console do cliente MySQL.
Verifique a sua hora atual com a função NOW(), antes de começar a brincar:

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2015-07-02 19:37:57 |
+---------------------+
1 row in set (0.01 sec)

Em seguida, altere a variável global de fuso horário e desconecte do servidor:

SET @@global.time_zone = '+3:00';
QUIT

Você precisa sair e entrar de novo na sua sessão MySQL para poder ver os efeitos.
Assim que reiniciar a sessão do MySQL, verifique novamente a hora atual:

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2015-07-02 22:38:29 |
+---------------------+
1 row in set (0.00 sec)

Se você tiver o banco de dados de nomes de zonas de fusos horários adequadamente configurado, pode se referir às zonas pelos seus nomes. Veja um exemplo:

SET time_zone='America/Sao_Paulo';
Query OK, 0 rows affected (0.01 sec)
SELECT @@time_zone;
+-------------------+
| @@time_zone       |
+-------------------+
| America/Sao_Paulo |
+-------------------+
1 row in set (0.00 sec)

Para poder se referir a um nome de zona de fuso horário, como ‘Brazil/DeNoronha’, você precisa estar com o banco de dados de nomes de timezones corretamente configurado. Se você tiver dúvidas sobre este assunto, ou não estiver conseguindo usar os nomes das zonas de fusos, leia este artigo.
Para ver todos os fusos válidos para o Brazil, por exemplo, use a seguinte query:

SELECT * FROM mysql.time_zone_name WHERE Name LIKE '%Brazil%';
+------------------------+--------------+
| Name                   | Time_zone_id |
+------------------------+--------------+
| Brazil/Acre            |          360 |
| Brazil/DeNoronha       |          361 |
| Brazil/East            |          362 |
| Brazil/West            |          363 |
| posix/Brazil/Acre      |          957 |
| posix/Brazil/DeNoronha |          958 |
| posix/Brazil/East      |          959 |
| posix/Brazil/West      |          960 |
| right/Brazil/Acre      |         1554 |
| right/Brazil/DeNoronha |         1555 |
| right/Brazil/East      |         1556 |
| right/Brazil/West      |         1557 |
+------------------------+--------------+
12 rows in set (0.00 sec)

Ajuste o arquivo de configuração my.cnf

Você pode selecionar um fuso horário pro servidor MySQL diferente do usado pelo sistema no qual ele se encontra instalado. Para isto, indique o fuso horário desejado, dentro do arquivo /etc/mysql/my.cnf, sob a variável default-time-zone.
Veja um exemplo:

[mysqld]
default-time-zone = Europe/Lisbon

Para que o comando acima funcione adequadamente, é necessário que as tabelas de timezones estejam completas e preenchidas.
Há outros valores, para quem se encontra em país de língua portuguesa:

  • Africa/Luanda
  • America/Campo_Grande
  • America/Bahia
  • America/Belem
  • America/Boa_Vista
  • America/Cuiaba
  • America/Fortaleza
  • America/Manaus — Brazil/West
  • America/Noronha — Brazil/DeNoronha
  • America/Porto_Acre — Brazil/Acre
  • America/Porto_Velho
  • America/Recife
  • America/Rio_Branco — Brazil/Rio_Branco
  • America/Santarem
  • America/Sao_Paulo — Brazil/East
  • Brazil/Acre
  • Brazil/DeNoronha
  • Brazil/East
  • Brazil/Rio_Branco
  • Brazil/West
  • Athlantic/Cape_Verde

Se você usa Ubuntu ou outra distro GNU/Linux baseada no Debian, pode encontrar uma relação completa de zonas de fusos horários em /usr/share/zoneinfo.
Depois de alterar o arquivo my.cnf, reinicie o servidor MySQL:

sudo service mysql stop
sudo service mysql start

mysql start/running, process 11885

Entre novamente no cliente MySQL e verifique o seu novo fuso horário:

NOW();

ou

select @@time_zone;
+------------------+
| @@time_zone      |
+------------------+
| Europe/Stockholm |
+------------------+
1 row in set (0.00 sec)

Como você pode perceber, no exemplo acima, alterei o fuso horário para o de Estocolmo (Suécia).
Quando você cansar de brincar, basta remover (ou comentar, com um ‘#’) a referência ao fuso horário no arquivo my.cnf e reiniciar o servidor MySQL — e este voltará a usar o fuso horário do sistema:

select @@time_zone;
+-------------+
| @@time_zone |
+-------------+
| SYSTEM      |
+-------------+

Se você quiser entender melhor o uso do arquivo de configuração my.cnf, leia o artigo Use um arquivo de configuração pessoal para se conectar ao MySQL.

Referẽncias:
https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
http://stackoverflow.com/questions/930900/how-to-set-time-zone-of-mysql

Saytime, o relógio falante no Linux

Saiba como ouvir a hora, no Linux, com um relógio que sintetiza a voz humana.
O saytime informa a hora atual, no seu sistema, oralmente, usando arquivos de áudio pré-gravados e tem flexibilidade para ser configurado.
ícone de alto falante.

Como instalar e usar o saytime

No Ubuntu, no Debian ou em qualquer outra distro derivada, use o apt-get:

sudo apt-get install saytime

Após a instalação, execute o programa:

saytime

Se o seu áudio estiver ativo, vai ouvir uma voz natural masculina, informando a hora.
Se você estiver insatisfeito com o volume, pode dobrar seu valor com -v:

saytime -v 2

O valor 3, triplica; 4, quadruplica etc.
O relógio, por padrão, informa a hora no formato 12h — acrescentando AM ao horário da manhã e PM ao horário da tarde.
Quando a hora e os minutos são “redondos”, o locutor acrescenta “exactly” (exatamente) ao final da frase.
No tópico seguinte, vou mostrar como formatar a saída da hora.

Como formatar a saída do saytime

Os caracteres de formatação são os seguintes:

  • %k — informa a hora no padrão 24 horas.
  • %l — usa o padrão 12 horas.
  • %M — informa os minutos.
  • %S — informa os segundos.
  • %P — frase introdutória. Se você não quiser que o “locutor” comece a dar informação sobre a hora, com um “The time is“, suprima estes caracteres.

O padrão do programa é %P%l%M%S.
Veja um exemplo de formatação para dizer a hora, sem informar minutos e segundos, no formato 24 horas:

saytime -f %k

Acrescente a informação de horas e minutos à saída do saytime:

saytime -f %k%M%S

Como automatizar a informação de hora no sistema

A opção -r envia o programa pros bastidores (background) e passa a informar a cada intervalo de tempo a hora certa pra você.
No exemplo que segue, o saytime irá informar a hora, a cada 6 segundos, com o volume de áudio triplicado (3x), no formato HH:MM (hora e minuto):

saytime -r 6 -v 3 -f %k%M

Se quiser interromper o processo, use o comando pkill:

pkill -9 saytime

Como alterar a voz do saytime

Os arquivos de áudio do saytime ficam armazenados em /usr/share/saytime:

ls /usr/share/saytime
0.au   14.au  19.au  3.au   6.au   and.au      minutes.au  seconds.au
10.au  15.au  1.au   40.au  7.au   exactly.au  oclock.au   the_time_is.au
11.au  16.au  20.au  4.au   8.au   hour.au     oh.au
12.au  17.au  2.au   50.au  9.au   hours.au    pm.au
13.au  18.au  30.au  5.au   am.au  minute.au   second.au

Estes arquivos podem ser substituídos por outros, com os mesmos nomes e os mesmos formatos de áudio (.au).
Recomendo, fazer um backup dos arquivos originais antes —, após o quê, é possível, por exemplo, regravá-los com a sua voz, falando em português.
Supondo que você grave novos arquivos e os armazene no diretório ~/audio/, execute o saytime com a opção -d ~/audio/, para informar ao programa onde buscar seus arquivos de áudio. Veja como fica:

saytime -d ~/audio/

Espero que você se divirta e não perca mais a hora 😉