Menu
Coddy logo textTech

Parsing de cadenas de tiempo

Parte de la sección Lógica y Flujo del Journey de GO de Coddy — lección 61 de 68.

A veces recibirás información de fecha y hora como cadenas que necesitan ser convertidas en objetos time.Time para su procesamiento. Go proporciona la función time.Parse para manejar esta conversión.

La función time.Parse funciona como lo inverso al formateo: toma una cadena de diseño y una cadena de tiempo, y luego devuelve un objeto time.Time:

dateString := "2023-10-26"
parsedTime, err := time.Parse("2006-01-02", dateString)
if err != nil {
    fmt.Println("Error parsing time:", err)
} else {
    fmt.Println(parsedTime)
}

Al igual que con el formato, utilizas los mismos componentes de la fecha de referencia en tu cadena de diseño (layout). El diseño "2006-01-02" le indica a Go que espere la cadena de entrada en el formato YYYY-MM-DD. El diseño debe coincidir exactamente con el formato de tu cadena de entrada.

Recuerda que time.Parse devuelve dos valores: el objeto time.Time analizado y un error. Comprueba siempre el error para asegurarte de que el análisis fue exitoso, ya que las cadenas de fecha no válidas o los formatos (layouts) que no coinciden harán que el análisis falle.

quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

challenge icon

Desafío

Fácil

Crea un analizador de archivos de registro que convierta cadenas de marcas de tiempo de varios formatos en objetos time.Time para su análisis. Este desafío pondrá a prueba tu capacidad para usar time.Parse con diferentes patrones de diseño (layouts) para manejar múltiples formatos de fecha y hora que se encuentran comúnmente en los registros del sistema.

Nota importante: Dado que los mensajes de registro y los patrones de diseño pueden contener espacios, deberás usar bufio.Scanner para leer líneas completas de entrada. La función fmt.Scanln deja de leer en el primer espacio, lo que rompería las entradas de registro y los diseños con espacios. Usa bufio.NewScanner(os.Stdin) y llama a scanner.Scan() seguido de scanner.Text() para leer líneas completas.

Recibirás dos entradas:

  • Una cadena que contiene entradas de registro en el formato "timestamp1:message1,timestamp2:message2,timestamp3:message3" (por ejemplo, "2023-10-26:System startup,2023/12/25:Holiday shutdown,Jan 15 2024:Maintenance window")
  • Una cadena que contiene patrones de diseño separados por comas en el formato "layout1,layout2,layout3" (por ejemplo, "2006-01-02,2006/01/02,Jan 2 2006")

Tu tarea es:

  1. Usar bufio.Scanner para leer las líneas de entrada correctamente para manejar espacios en los mensajes de registro y patrones de diseño
  2. Analizar la primera entrada dividiéndola por comas para obtener entradas de registro individuales
  3. Para cada entrada de registro, dividir por dos puntos para extraer la cadena de marca de tiempo y el mensaje
  4. Analizar la segunda entrada dividiéndola por comas para obtener los patrones de diseño
  5. Mostrar el encabezado de la aplicación: "=== LOG TIMESTAMP PARSER ==="
  6. Mostrar el estado del procesamiento: "Processing log entries with multiple timestamp formats..."
  7. Para cada entrada de registro, intentar analizar la marca de tiempo utilizando cada patrón de diseño hasta que uno tenga éxito:
    • Prueba cada patrón de diseño con time.Parse hasta que el análisis tenga éxito (sin error)
    • Cuando tenga éxito, muestra: "Parsed: [timestamp_string] -> [parsed_time_object] (using layout: [successful_layout])"
    • También muestra: " Message: [log_message]"
    • Si ningún diseño funciona para una marca de tiempo, muestra: "Failed to parse: [timestamp_string] - no matching layout found"
  8. Después de procesar todas las entradas, muestra las estadísticas de análisis:
    • "=== PARSING RESULTS ==="
    • "Total log entries processed: [number_of_entries]"
    • "Successfully parsed timestamps: [number_of_successful_parses]"
    • "Failed parsing attempts: [number_of_failed_parses]"
  9. Mostrar estadísticas de uso de diseños:
    • "Layout pattern usage:"
    • Para cada patrón de diseño: " [layout_pattern]: [number_of_times_used] times"
  10. Si alguna marca de tiempo se analizó correctamente, muestra el análisis cronológico:
    • "=== CHRONOLOGICAL ANALYSIS ==="
    • "Earliest timestamp: [earliest_parsed_time]"
    • "Latest timestamp: [latest_parsed_time]"
    • "Time span covered: [time_difference_description]"
  11. Mostrar el mensaje de finalización: "Log parsing completed - timestamps converted to time objects"

Usa el paquete time para las operaciones de análisis, el paquete strings para dividir las cadenas de entrada, los paquetes bufio y os para el manejo adecuado de la entrada, y el paquete fmt para la salida formateada. Recuerda que time.Parse devuelve tanto un objeto time.Time como un error; debes verificar el error para determinar si el análisis fue exitoso. Cuando el análisis falle con un diseño, prueba el siguiente patrón de diseño hasta que encuentres uno que funcione o agotes todas las opciones. Este desafío demuestra cómo manejar múltiples formatos de marca de tiempo en escenarios de procesamiento de registros del mundo real.

Hoja de referencia

Usa time.Parse para convertir cadenas de fecha/hora en objetos time.Time:

dateString := "2023-10-26"
parsedTime, err := time.Parse("2006-01-02", dateString)
if err != nil {
    fmt.Println("Error parsing time:", err)
} else {
    fmt.Println(parsedTime)
}

La cadena de diseño (layout) debe coincidir con el formato exacto de su cadena de entrada utilizando los componentes de fecha de referencia de Go. time.Parse devuelve tanto un objeto time.Time como un error; compruebe siempre el error para asegurarse de que el análisis fue exitoso.

Pruébalo tú mismo

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"time"
)

func main() {
	// Crear un escáner para leer las líneas de entrada
	scanner := bufio.NewScanner(os.Stdin)
	
	// Leer las entradas del registro (log)
	scanner.Scan()
	logEntries := scanner.Text()
	
	// Leer los patrones de diseño (layout)
	scanner.Scan()
	layoutPatterns := scanner.Text()
	
	// Analizar las entradas
	entries := strings.Split(logEntries, ",")
	layouts := strings.Split(layoutPatterns, ",")
	
	// Inicializar contadores para las estadísticas
	totalEntries := len(entries)
	successfulParses := 0
	failedParses := 0
	layoutUsage := make(map[string]int)
	var parsedTimes []time.Time
	
	// TODO: Escribe tu código a continuación
	// 1. Mostrar el encabezado de la aplicación
	// 2. Mostrar el estado del procesamiento
	// 3. Procesar cada entrada del registro:
	//    - Dividir la entrada en ":" para obtener la marca de tiempo y el mensaje
	//    - Probar cada patrón de diseño hasta que uno funcione
	//    - Mostrar los resultados del análisis
	//    - Actualizar las estadísticas
	// 4. Mostrar las estadísticas de análisis
	// 5. Mostrar las estadísticas de uso de los diseños
	// 6. Si se analizaron las marcas de tiempo, mostrar el análisis cronológico
	// 7. Mostrar el mensaje de finalización
	
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Lógica y Flujo