From 837a264e81d0f39805b514a9a0ddb051fb368a7d Mon Sep 17 00:00:00 2001 From: Ricardo Gonzalez Date: Thu, 28 May 2026 13:51:16 -0500 Subject: [PATCH] timezone: parseo UTC Teams + conversion Colombia + doc RUMBO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - services/timezone.ts: parseTeamsUTC(), toColombiaTime(), isTeamsFile() - TranscriptionsView: fecha prioriza UTC del filename sobre AI/hoy - TranscriptionsView: muestra conversion UTC → Colombia en resultados - rumbo/timezone.md: documentacion arquitectura horaria para RUMBO --- src/services/timezone.ts | 53 ++++++++++++++++++++++++++++++++ src/views/TranscriptionsView.vue | 17 ++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/services/timezone.ts diff --git a/src/services/timezone.ts b/src/services/timezone.ts new file mode 100644 index 0000000..2de6626 --- /dev/null +++ b/src/services/timezone.ts @@ -0,0 +1,53 @@ +/** + * Utilidades de huso horario para Alpha. + * + * Colombia: UTC-5 (sin horario de verano). + * Microsoft Teams transcripts incluyen UTC en el filename. + */ + +const COLOMBIA_OFFSET = -5 // UTC-5 + +/** + * Parsea timestamp UTC desde filename de Microsoft Teams. + * Formato: "305 Equilibrium Logicas Dashboard Informes-20260525_185916UTC-Meeting Recording" + * ^^^^^^^^^^^^^^^^^^^^ + * Devuelve: { dateStr: "2026-05-25", timeStr: "13:59", utc: "18:59" } + */ +export function parseTeamsUTC(filename: string): { dateStr: string; timeStr: string; utc: string } | null { + // Busca patrón YYYYMMDD_HHMMSSUTC + const match = filename.match(/(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})UTC/) + if (!match) return null + + const [, y, m, d, hh, mm] = match + + // Crear fecha UTC + const utcDate = new Date(Date.UTC(Number(y), Number(m) - 1, Number(d), Number(hh), Number(mm))) + + // Convertir a Colombia (UTC-5) + const colombia = new Date(utcDate.getTime() + COLOMBIA_OFFSET * 3600000) + + const pad2 = (n: number) => String(n).padStart(2, '0') + + const dateStr = `${colombia.getFullYear()}-${pad2(colombia.getMonth() + 1)}-${pad2(colombia.getDate())}` + const timeStr = `${pad2(colombia.getHours())}:${pad2(colombia.getMinutes())}` + const utcStr = `${hh}:${mm}` + + return { dateStr, timeStr, utc: utcStr } +} + +/** + * Detecta si el filename es de Microsoft Teams. + */ +export function isTeamsFile(filename: string): boolean { + return /Meetings?\s*(Recording|Transcript)/i.test(filename) || /^\d{8}_\d{6}UTC/.test(filename) +} + +/** + * Convierte una fecha UTC a string en hora Colombia. + */ +export function toColombiaTime(isoString: string): string { + const d = new Date(isoString) + const col = new Date(d.getTime() + COLOMBIA_OFFSET * 3600000) + const pad2 = (n: number) => String(n).padStart(2, '0') + return `${col.getFullYear()}-${pad2(col.getMonth() + 1)}-${pad2(col.getDate())} ${pad2(col.getHours())}:${pad2(col.getMinutes())}` +} diff --git a/src/views/TranscriptionsView.vue b/src/views/TranscriptionsView.vue index aa1fe09..d54bc66 100644 --- a/src/views/TranscriptionsView.vue +++ b/src/views/TranscriptionsView.vue @@ -15,6 +15,7 @@ import { analyzeSession, type SessionExtraction } from '@/services/session-analy import { generateMasterDoc } from '@/services/project-doc' import { parseFile } from '@/services/parse-transcription' import { saveSession, saveSessionSummary, saveProjectState, getSessionCount } from '@/services/transcriptions-db' +import { parseTeamsUTC, toColombiaTime } from '@/services/timezone' import { Card, CardContent, @@ -68,6 +69,7 @@ const uploadError = ref(null) const sessionLoading = ref(false) const sessionResult = ref(null) const sessionError = ref(null) +const sessionTeamsInfo = ref<{ utc: string; timeStr: string } | null>(null) const docGenerating = ref(false) const docGenerated = ref(false) @@ -275,11 +277,16 @@ async function analyzeAsSession() { selectedProject.value?.name || '', ) - // 1. Guardar transcripción en BD + // 1. Determinar fecha (prioridad: UTC del filename → AI → hoy) const now = new Date().toISOString() + const teamsDate = parseTeamsUTC(parsedFileName.value) + sessionTeamsInfo.value = teamsDate ? { utc: teamsDate.utc, timeStr: teamsDate.timeStr } : null + const sessionDate = teamsDate?.dateStr || result.sessionDate || now.slice(0, 10) + + // 1b. Guardar transcripción en BD const sessionId = await saveSession({ projectId: selectedProjectId.value, - date: result.sessionDate || now.slice(0, 10), + date: sessionDate, title: result.sessionTitle, fileName: parsedFileName.value, fileType: parsedFileName.value.split('.').pop() || 'txt', @@ -706,6 +713,12 @@ function clearAll() { {{ sessionResult.sessionTitle }} +
+ {{ sessionResult.sessionDate || '' }} + + · UTC {{ sessionTeamsInfo.utc }} → Colombia {{ sessionTeamsInfo.timeStr }} + +