Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Por que a configuração de fuso horário do Django afeta o tempo de época?


Eu não sou nenhum guru de python ou Django, então talvez alguém possa responder melhor do que eu. Mas vou arriscar mesmo assim.

Você disse que estava armazenando em um Django DateTimeField , que de acordo com os documentos que você fez referência , armazena-o como um Python datetime .

Examinando os documentos para datetime , acho que a chave é entender a diferença entre os valores "ingênuos" e "conscientes".

E pesquisando mais, encontrei esta excelente referência . Certifique-se de ler a segunda seção, "Objetos de data e hora ingênuos e cientes". Isso dá um pouco de contexto de quanto disso está sendo controlado pelo Django. Basicamente, definindo USE_TZ = true , você está pedindo ao Django para usar aware datetimes em vez de ingênuo uns.

Então eu olhei de volta para sua pergunta. Você disse que estava fazendo o seguinte:
dt = datetime.fromtimestamp(secs)
dt = dt.replace(tzinfo=utc)

Examinando o fromtimestamp documentação da função, encontrei este pedaço de texto:

Então eu acho que você poderia fazer isso:
dt = datetime.fromtimestamp(secs, tz=utc)

Então, novamente, logo abaixo dessa função, os documentos mostram utcfromtimestamp função, então talvez deva ser:
dt = datetime.utcfromtimestamp(secs)

Eu não sei o suficiente sobre python para saber se eles são equivalentes ou não, mas você pode tentar ver se faz alguma diferença.

Esperemos que um destes vai fazer a diferença. Se não, por favor me avise. Estou intimamente familiarizado com data/hora em JavaScript e em .Net, mas estou sempre interessado em saber como essas nuances se comportam de maneira diferente em outras plataformas, como Python.

Atualizar


Em relação à parte MySQL da pergunta, dê uma olhada este violino .
CREATE TABLE foo (`date` DATETIME);
INSERT INTO foo (`date`) VALUES (FROM_UNIXTIME(1371131402));

SET TIME_ZONE="+00:00";
select `date`, UNIX_TIMESTAMP(`date`) from foo;

SET TIME_ZONE="+01:00";
select `date`, UNIX_TIMESTAMP(`date`) from foo;

Resultados:
DATE                           UNIX_TIMESTAMP(`DATE`)
June, 13 2013 13:50:02+0000    1371131402
June, 13 2013 13:50:02+0000    1371127802

Parece que o comportamento de UNIX_TIMESTAMP função é realmente afetada pelo MySQL TIME_ZONE contexto. Isso não é tão surpreendente, já que está na documentação. O que é surpreendente é que a saída de string do datetime tem o mesmo valor UTC independentemente da configuração.

Aqui está o que eu acho que está acontecendo. Nos documentos do UNIX_TIMESTAMP função, diz:

Observe que não diz que pode ser um DATETIME - diz que pode ser um DATETIME sequência . Então, acho que o valor real está sendo convertido implicitamente em uma string antes de ser passado para a função.

Então agora veja este violino atualizado que converte explicitamente.
SET TIME_ZONE="+00:00";
select `date`, convert(`date`, char), UNIX_TIMESTAMP(convert(`date`, char)) from foo;

SET TIME_ZONE="+01:00";
select `date`, convert(`date`, char), UNIX_TIMESTAMP(convert(`date`, char)) from foo;

Resultados:
DATE                           CONVERT(`DATE`, CHAR)  UNIX_TIMESTAMP(CONVERT(`DATE`, CHAR))
June, 13 2013 13:50:02+0000    2013-06-13 13:50:02    1371131402
June, 13 2013 13:50:02+0000    2013-06-13 13:50:02    1371127802

Você pode ver que, quando converte em dados de caracteres, remove o deslocamento. Então, é claro, agora faz sentido que quando UNIX_TIMESTAMP recebe esse valor como entrada, está assumindo a configuração do fuso horário local e, assim, obtendo um carimbo de data/hora UTC diferente.

Não tenho certeza se isso vai te ajudar ou não. Você precisa se aprofundar em exatamente como o Django está chamando o MySQL tanto para leitura quanto para gravação. Ele realmente usa o UNIX_TIMESTAMP função? Ou foi só isso que você fez nos testes?