✅ Cambios Implementados:
1. PostgreSQL (Base de Datos) Variables de entorno: TZ=Atlantic/Canary y PGTZ=Atlantic/Canary Configurado en todos los archivos Docker: docker-compose.yml, docker-compose.prod.yml, docker-stack.yml 2. Backend (FastAPI/Python) Configuración de zona horaria al inicio de main.py Conexión a PostgreSQL con parámetro de timezone Event listener que establece timezone en cada conexión a la BD Variable de entorno: TZ=Atlantic/Canary 3. Frontend (React) Ya estaba usando fechas locales correctamente con el constructor new Date(year, month, day) 4. Migración SQL Creado set_timezone_canary.sql para actualizar la BD existente
This commit is contained in:
209
TIMEZONE_SETUP.md
Normal file
209
TIMEZONE_SETUP.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# Configuración de Zona Horaria - Atlantic/Canary
|
||||
|
||||
## Cambios Implementados
|
||||
|
||||
Se ha configurado la zona horaria de **Atlantic/Canary (Islas Canarias, España)** en toda la aplicación:
|
||||
|
||||
### 1. Base de Datos PostgreSQL
|
||||
- **Zona horaria**: `Atlantic/Canary` (UTC+0 en invierno, UTC+1 en verano con horario de verano)
|
||||
- Variables de entorno agregadas:
|
||||
- `TZ=Atlantic/Canary`
|
||||
- `PGTZ=Atlantic/Canary`
|
||||
|
||||
### 2. Backend FastAPI
|
||||
- Configuración de zona horaria de Python al inicio de la aplicación
|
||||
- Conexión a PostgreSQL configurada con timezone
|
||||
- Event listener para establecer timezone en cada conexión
|
||||
- Variable de entorno: `TZ=Atlantic/Canary`
|
||||
|
||||
### 3. Frontend React
|
||||
- Los filtros de fecha usan el constructor de Date con zona horaria local
|
||||
- Las fechas se muestran en formato español (es-ES)
|
||||
|
||||
## Aplicar los Cambios
|
||||
|
||||
### Desarrollo Local
|
||||
|
||||
1. **Parar los contenedores actuales**:
|
||||
```powershell
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
2. **Aplicar la migración de zona horaria a la base de datos**:
|
||||
```powershell
|
||||
docker-compose up -d postgres
|
||||
|
||||
# Esperar a que PostgreSQL esté listo
|
||||
Start-Sleep -Seconds 5
|
||||
|
||||
# Aplicar migración
|
||||
docker-compose exec postgres psql -U checklist_user -d checklist_db -f /docker-entrypoint-initdb.d/../migrations/set_timezone_canary.sql
|
||||
```
|
||||
|
||||
**Alternativa manual**:
|
||||
```powershell
|
||||
# Copiar el archivo SQL al contenedor
|
||||
docker cp migrations/set_timezone_canary.sql checklist-db:/tmp/
|
||||
|
||||
# Ejecutarlo
|
||||
docker-compose exec postgres psql -U checklist_user -d checklist_db -f /tmp/set_timezone_canary.sql
|
||||
```
|
||||
|
||||
3. **Reconstruir y levantar todos los servicios**:
|
||||
```powershell
|
||||
docker-compose build
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. **Verificar la configuración**:
|
||||
```powershell
|
||||
# Verificar timezone en PostgreSQL
|
||||
docker-compose exec postgres psql -U checklist_user -d checklist_db -c "SHOW timezone;"
|
||||
|
||||
# Verificar timezone en backend
|
||||
docker-compose exec backend python -c "import time; print(time.tzname)"
|
||||
```
|
||||
|
||||
### Producción
|
||||
|
||||
#### Docker Compose Production
|
||||
|
||||
1. **Parar servicios**:
|
||||
```bash
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
```
|
||||
|
||||
2. **Aplicar migración**:
|
||||
```bash
|
||||
docker-compose -f docker-compose.prod.yml up -d postgres
|
||||
docker cp migrations/set_timezone_canary.sql syntria-db-prod:/tmp/
|
||||
docker-compose -f docker-compose.prod.yml exec postgres psql -U syntria_user -d syntria_db -f /tmp/set_timezone_canary.sql
|
||||
```
|
||||
|
||||
3. **Reconstruir imágenes y desplegar**:
|
||||
```bash
|
||||
./build-and-push.sh # o build-and-push.ps1 en Windows
|
||||
docker-compose -f docker-compose.prod.yml pull
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
#### Docker Swarm
|
||||
|
||||
1. **Aplicar migración en el nodo manager**:
|
||||
```bash
|
||||
# Encontrar el contenedor de PostgreSQL
|
||||
docker ps | grep syntria_db
|
||||
|
||||
# Copiar y ejecutar migración
|
||||
docker cp migrations/set_timezone_canary.sql <container_id>:/tmp/
|
||||
docker exec <container_id> psql -U syntria_user -d syntria_db -f /tmp/set_timezone_canary.sql
|
||||
```
|
||||
|
||||
2. **Actualizar stack**:
|
||||
```bash
|
||||
docker stack deploy -c docker-stack.yml syntria
|
||||
```
|
||||
|
||||
## Verificación Post-Despliegue
|
||||
|
||||
### 1. Verificar Zona Horaria de PostgreSQL
|
||||
```sql
|
||||
-- Debería mostrar: Atlantic/Canary
|
||||
SHOW timezone;
|
||||
|
||||
-- Verificar hora actual del servidor
|
||||
SELECT NOW();
|
||||
SELECT CURRENT_TIMESTAMP;
|
||||
```
|
||||
|
||||
### 2. Verificar Backend
|
||||
```bash
|
||||
docker-compose exec backend python -c "
|
||||
from datetime import datetime
|
||||
import time
|
||||
print('Timezone:', time.tzname)
|
||||
print('Hora actual:', datetime.now())
|
||||
print('UTC:', datetime.utcnow())
|
||||
"
|
||||
```
|
||||
|
||||
### 3. Probar en la Aplicación
|
||||
1. Crear una nueva inspección
|
||||
2. Verificar que la fecha/hora de inicio coincida con la hora local de Canarias
|
||||
3. Filtrar por fecha y verificar que el filtro funcione correctamente
|
||||
|
||||
## Comportamiento de las Fechas
|
||||
|
||||
### Fechas Existentes
|
||||
- Las fechas ya guardadas en la base de datos **no se modifican**
|
||||
- PostgreSQL las almacena internamente en UTC
|
||||
- Se mostrarán en hora de Canarias al consultarlas
|
||||
|
||||
### Nuevas Fechas
|
||||
- Se guardarán con timezone de Canarias
|
||||
- Se convertirán automáticamente a UTC para almacenamiento
|
||||
- Se mostrarán en hora de Canarias al recuperarlas
|
||||
|
||||
## Horario de Verano
|
||||
|
||||
La zona horaria `Atlantic/Canary` maneja automáticamente el horario de verano:
|
||||
- **Invierno (octubre - marzo)**: UTC+0 / WET (Western European Time)
|
||||
- **Verano (marzo - octubre)**: UTC+1 / WEST (Western European Summer Time)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Las fechas siguen mostrándose incorrectas
|
||||
|
||||
1. Verificar que los contenedores se reiniciaron después de los cambios:
|
||||
```powershell
|
||||
docker-compose restart
|
||||
```
|
||||
|
||||
2. Verificar logs del backend:
|
||||
```powershell
|
||||
docker-compose logs backend | Select-String -Pattern "timezone|TZ"
|
||||
```
|
||||
|
||||
3. Limpiar caché del navegador y recargar la aplicación
|
||||
|
||||
### Error al conectar a la base de datos
|
||||
|
||||
Si ves errores relacionados con timezone al conectar:
|
||||
```
|
||||
could not find timezone "Atlantic/Canary"
|
||||
```
|
||||
|
||||
Solución:
|
||||
```bash
|
||||
# Entrar al contenedor de PostgreSQL
|
||||
docker-compose exec postgres sh
|
||||
|
||||
# Instalar datos de zona horaria (si no están instalados)
|
||||
apk add --no-cache tzdata
|
||||
|
||||
# Salir y reiniciar
|
||||
exit
|
||||
docker-compose restart postgres
|
||||
```
|
||||
|
||||
### Las fechas en el frontend no coinciden
|
||||
|
||||
El frontend usa la zona horaria del navegador del usuario. Si el usuario está en una zona diferente a Canarias, verá las fechas en su hora local. Para forzar visualización en hora de Canarias en el frontend, se pueden usar bibliotecas como `date-fns-tz` o `luxon`.
|
||||
|
||||
## Archivos Modificados
|
||||
|
||||
- ✅ `docker-compose.yml` - Variables TZ para postgres y backend
|
||||
- ✅ `docker-compose.prod.yml` - Variables TZ para postgres y backend
|
||||
- ✅ `docker-stack.yml` - Variables TZ para db y backend
|
||||
- ✅ `backend/app/core/database.py` - Configuración de conexión con timezone
|
||||
- ✅ `backend/app/main.py` - Configuración de TZ de Python
|
||||
- ✅ `migrations/set_timezone_canary.sql` - Script de migración
|
||||
- ✅ `frontend/src/App.jsx` - Uso correcto de fechas locales
|
||||
|
||||
## Notas Importantes
|
||||
|
||||
⚠️ **Después de aplicar estos cambios en producción**:
|
||||
- Hacer backup de la base de datos antes de aplicar cambios
|
||||
- Aplicar en horario de bajo tráfico
|
||||
- Verificar que todas las funcionalidades de fecha/hora funcionan correctamente
|
||||
- Informar a los usuarios si hay cambios visibles en las fechas mostradas
|
||||
@@ -1,4 +1,4 @@
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy import create_engine, event
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from app.core.config import settings
|
||||
@@ -6,9 +6,17 @@ from app.core.config import settings
|
||||
engine = create_engine(
|
||||
settings.DATABASE_URL,
|
||||
pool_pre_ping=True,
|
||||
echo=settings.ENVIRONMENT == "development"
|
||||
echo=settings.ENVIRONMENT == "development",
|
||||
connect_args={"options": "-c timezone=Atlantic/Canary"}
|
||||
)
|
||||
|
||||
# Configurar zona horaria al conectar
|
||||
@event.listens_for(engine, "connect")
|
||||
def set_timezone(dbapi_conn, connection_record):
|
||||
cursor = dbapi_conn.cursor()
|
||||
cursor.execute("SET TIME ZONE 'Atlantic/Canary';")
|
||||
cursor.close()
|
||||
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
|
||||
# ============= CONFIGURACIÓN DE ZONA HORARIA =============
|
||||
import os
|
||||
os.environ['TZ'] = 'Atlantic/Canary'
|
||||
import time
|
||||
time.tzset()
|
||||
|
||||
# ============= LOGO CONFIGURABLE =============
|
||||
|
||||
from fastapi import FastAPI, File, UploadFile, Form, Depends, HTTPException, status
|
||||
|
||||
@@ -6,6 +6,8 @@ services:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-syntria_db}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-syntria_user}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
TZ: Atlantic/Canary
|
||||
PGTZ: Atlantic/Canary
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
@@ -29,6 +31,7 @@ services:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
ENVIRONMENT: production
|
||||
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-http://localhost,http://localhost:5173}
|
||||
TZ: Atlantic/Canary
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
|
||||
@@ -6,6 +6,8 @@ services:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-checklist_db}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-checklist_user}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-checklist_pass_2024}
|
||||
TZ: Atlantic/Canary
|
||||
PGTZ: Atlantic/Canary
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
@@ -25,6 +27,7 @@ services:
|
||||
SECRET_KEY: ${SECRET_KEY:-your-secret-key-change-in-production-min-32-chars}
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
ENVIRONMENT: ${ENVIRONMENT:-development}
|
||||
TZ: Atlantic/Canary
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
|
||||
@@ -7,6 +7,8 @@ services:
|
||||
POSTGRES_DB: syntria_db
|
||||
POSTGRES_USER: syntria_user
|
||||
POSTGRES_PASSWORD: syntria_secure_2024
|
||||
TZ: Atlantic/Canary
|
||||
PGTZ: Atlantic/Canary
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
@@ -35,6 +37,7 @@ services:
|
||||
GEMINI_API_KEY: tu_api_key_de_gemini
|
||||
ENVIRONMENT: production
|
||||
ALLOWED_ORIGINS: http://localhost,https://syntria.tudominio.com
|
||||
TZ: Atlantic/Canary
|
||||
networks:
|
||||
- syntria_network
|
||||
- network_public
|
||||
|
||||
@@ -4181,13 +4181,15 @@ function InspectionsTab({ inspections, user, onUpdate, onContinue }) {
|
||||
if (dateFrom || dateTo) {
|
||||
const inspectionDate = new Date(inspection.started_at)
|
||||
if (dateFrom) {
|
||||
const fromDate = new Date(dateFrom)
|
||||
fromDate.setHours(0, 0, 0, 0)
|
||||
// Crear fecha en hora local del usuario
|
||||
const [year, month, day] = dateFrom.split('-')
|
||||
const fromDate = new Date(year, month - 1, day, 0, 0, 0, 0)
|
||||
matchesDate = matchesDate && inspectionDate >= fromDate
|
||||
}
|
||||
if (dateTo) {
|
||||
const toDate = new Date(dateTo)
|
||||
toDate.setHours(23, 59, 59, 999)
|
||||
// Crear fecha en hora local del usuario
|
||||
const [year, month, day] = dateTo.split('-')
|
||||
const toDate = new Date(year, month - 1, day, 23, 59, 59, 999)
|
||||
matchesDate = matchesDate && inspectionDate <= toDate
|
||||
}
|
||||
}
|
||||
|
||||
16
migrations/set_timezone_canary.sql
Normal file
16
migrations/set_timezone_canary.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
-- Migración: Configurar zona horaria de Canarias en la base de datos
|
||||
-- Fecha: 2024-12-08
|
||||
-- Descripción: Establece Atlantic/Canary como zona horaria por defecto
|
||||
|
||||
-- Establecer zona horaria para la sesión actual
|
||||
SET TIME ZONE 'Atlantic/Canary';
|
||||
|
||||
-- Configurar zona horaria por defecto para la base de datos
|
||||
ALTER DATABASE checklist_db SET timezone TO 'Atlantic/Canary';
|
||||
|
||||
-- Nota: Las fechas existentes en la base de datos se mantendrán tal cual están almacenadas
|
||||
-- PostgreSQL almacena las fechas con timezone en UTC internamente y las convierte según la zona horaria configurada
|
||||
-- Si necesitas convertir fechas existentes, ejecuta manualmente según sea necesario
|
||||
|
||||
-- Para verificar la configuración:
|
||||
SHOW timezone;
|
||||
Reference in New Issue
Block a user