--- name: API e App Professor — timezone Brasília description: API retorna timestamps em horário Brasília (naive, sem Z). App NÃO deve forçar UTC nem usar toLocal() — bug recorrente. type: feedback originSessionId: 8c104d25-bcaf-4cab-ad1d-ce60d0ba9c33 --- ## Convenção de timezone na API do app professor A API (`ApiProfessorController`) retorna **todos os timestamps em horário de Brasília**, formato `Y-m-d H:i:s` **sem sufixo de timezone** (não vem `Z`, não vem `+00:00`, não vem `-03:00`). Origem: `ApiProfessorController::agoraBrasilia()` usa `new \DateTime('now', new \DateTimeZone('America/Sao_Paulo'))`. Campos afetados: - `professor_presente_em` - `inicio_real` - `fim_real` - `created_at`/`updated_at` ### Regra para o app Flutter **NÃO fazer:** ```dart DateTime.parse('${str}Z').toLocal() // ❌ trata como UTC, subtrai 3h ``` **Fazer:** ```dart DateTime.parse(str) // ✅ parsea como local naive ``` ### Bug histórico (2026-04-28) `aula_screen.dart::_utcToLocal` concatenava `Z` ao final, fazendo o app exibir 3h a menos no card "Detalhes" (Professor Presente, Início Real, Fim Real). Corrigido removendo o `Z` e o `toLocal()`. **Why:** A API já manda em horário local Brasília. Forçar UTC + toLocal() subtrai 3h. Como a UI mostra HH:mm, o erro de 3 horas é visível imediatamente. **How to apply:** Em qualquer tela nova do app que receba timestamp da API, parsear direto com `DateTime.parse(str)`. Se precisar formatar, usar `intl.DateFormat` sobre o DateTime parseado, sem conversão de timezone. Se um dia a API for migrada para retornar UTC com `Z`, atualizar essa convenção em todas as telas de uma vez. ### Bug crítico backend (2026-05-05) — PHP em UTC + strtotime() em string Brasília **PHP do servidor de produção está em `date.timezone = UTC`** (não foi alterado). Datas salvas no banco estão em horário Brasília (via `agoraBrasilia()`). Mas `strtotime("2026-05-05 11:11:55")` interpreta a string como UTC, gerando offset de 3h. **Sintoma**: cronômetro do app mostrava `03:40:52` em vez de `00:40:52` numa aula iniciada há 40 min — diferença exata de 3h. Endpoint `/api/professor/aulas/{id}` retornava `segundos_efetivos = ~13000` (3h40 em segundos) em vez de `~2400` (40 min). **Correção**: criado helper `ApiProfessorController::timestampBrasilia($datetime)` que usa `new DateTime($datetime, new DateTimeZone('America/Sao_Paulo'))` para interpretar corretamente. Substituídas TODAS as chamadas de `strtotime($aula['inicio_real'/'fim_real'/'professor_presente_em'])` e `strtotime($aula['data_aula'].' '.$aula['horario_inicio'/'horario_fim'])` por esse helper. **Why:** Não dá pra alterar `date.timezone` global do PHP no servidor compartilhado. Solução é blindar todos os pontos onde `strtotime()` recebe string que veio de `agoraBrasilia()`. **How to apply:** ao adicionar nova rota na API que faça aritmética de tempo com campos do banco (`inicio_real`, `fim_real`, etc), SEMPRE usar `$this->timestampBrasilia(...)` em vez de `strtotime()` direto. O `time()` puro (timestamp UTC do "agora") continua OK.