Menu
Coddy logo textTech

Парсинг строк времени

Часть раздела Логика и управление потоком путешествия по GO на Coddy — урок 61 из 68.

Иногда вы будете получать информацию о дате и времени в виде строк, которые необходимо преобразовать в объекты time.Time для обработки. Go предоставляет функцию time.Parse для выполнения этого преобразования.

Функция time.Parse работает в обратном порядке по сравнению с форматированием — она принимает строку макета и строку времени, а затем возвращает объект 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)
}

Так же, как и при форматировании, вы используете те же компоненты эталонной даты в строке макета. Макет "2006-01-02" указывает Go ожидать входную строку в формате YYYY-MM-DD. Макет должен точно соответствовать формату вашей входной строки.

Помните, что time.Parse возвращает два значения: разобранный объект time.Time и ошибку. Всегда проверяйте ошибку, чтобы убедиться, что разбор прошел успешно, так как неверные строки даты или несовпадающие макеты приведут к ошибке разбора.

quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

challenge icon

Задание

Легко

Создайте парсер лог-файлов, который преобразует строки меток времени из различных форматов в объекты time.Time для анализа. Эта задача проверит ваше умение использовать time.Parse с различными шаблонами макетов (layout patterns) для обработки нескольких форматов даты и времени, часто встречающихся в системных логах.

Важное примечание: Поскольку сообщения логов и шаблоны макетов могут содержать пробелы, вам потребуется использовать bufio.Scanner для чтения полных строк ввода. Функция fmt.Scanln прекращает чтение на первом пробеле, что нарушит обработку записей лога и макетов с пробелами. Используйте bufio.NewScanner(os.Stdin) и вызывайте scanner.Scan(), а затем scanner.Text() для чтения полных строк.

Вы получите два входных значения:

  • Строка, содержащая записи лога в формате "timestamp1:message1,timestamp2:message2,timestamp3:message3" (например, "2023-10-26:System startup,2023/12/25:Holiday shutdown,Jan 15 2024:Maintenance window")
  • Строка, содержащая шаблоны макетов, разделенные запятыми, в формате "layout1,layout2,layout3" (например, "2006-01-02,2006/01/02,Jan 2 2006")

Ваша задача:

  1. Использовать bufio.Scanner для правильного чтения строк ввода, чтобы корректно обрабатывать пробелы в сообщениях логов и шаблонах макетов
  2. Разобрать первую строку ввода, разделив ее по запятым, чтобы получить отдельные записи лога
  3. Для каждой записи лога разделить ее по двоеточию, чтобы извлечь строку метки времени и сообщение
  4. Разобрать вторую строку ввода, разделив ее по запятым, чтобы получить шаблоны макетов
  5. Вывести заголовок приложения: "=== LOG TIMESTAMP PARSER ==="
  6. Вывести статус обработки: "Processing log entries with multiple timestamp formats..."
  7. Для каждой записи лога попытаться разобрать метку времени, используя каждый шаблон макета, пока один из них не сработает:
    • Пробовать каждый шаблон макета с помощью time.Parse, пока парсинг не пройдет успешно (без ошибки)
    • При успехе вывести: "Parsed: [timestamp_string] -> [parsed_time_object] (using layout: [successful_layout])"
    • Также вывести: " Message: [log_message]"
    • Если ни один макет не подошел для метки времени, вывести: "Failed to parse: [timestamp_string] - no matching layout found"
  8. После обработки всех записей вывести статистику парсинга:
    • "=== PARSING RESULTS ==="
    • "Total log entries processed: [number_of_entries]"
    • "Successfully parsed timestamps: [number_of_successful_parses]"
    • "Failed parsing attempts: [number_of_failed_parses]"
  9. Вывести статистику использования макетов:
    • "Layout pattern usage:"
    • Для каждого шаблона макета: " [layout_pattern]: [number_of_times_used] times"
  10. Если какие-либо метки времени были успешно разобраны, вывести хронологический анализ:
    • "=== CHRONOLOGICAL ANALYSIS ==="
    • "Earliest timestamp: [earliest_parsed_time]"
    • "Latest timestamp: [latest_parsed_time]"
    • "Time span covered: [time_difference_description]"
  11. Вывести сообщение о завершении: "Log parsing completed - timestamps converted to time objects"

Используйте пакет time для операций парсинга, пакет strings для разделения входных строк, пакеты bufio и os для правильной обработки ввода и пакет fmt для форматированного вывода. Помните, что time.Parse возвращает как объект time.Time, так и ошибку — вы должны проверять ошибку, чтобы определить, был ли парсинг успешным. Если парсинг не удался с одним макетом, пробуйте следующий шаблон, пока не найдете подходящий или не исчерпаете все варианты. Эта задача демонстрирует, как обрабатывать несколько форматов меток времени в реальных сценариях обработки логов.

Шпаргалка

Используйте time.Parse для преобразования строк даты/времени в объекты 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)
}

Строка макета должна точно соответствовать формату вашей входной строки с использованием эталонных компонентов даты Go. time.Parse возвращает как объект time.Time, так и ошибку — всегда проверяйте ошибку, чтобы убедиться, что парсинг прошел успешно.

Попробуйте сами

package main

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

func main() {
	// Создать сканер для чтения строк ввода
	scanner := bufio.NewScanner(os.Stdin)
	
	// Прочитать записи лога
	scanner.Scan()
	logEntries := scanner.Text()
	
	// Прочитать шаблоны макетов
	scanner.Scan()
	layoutPatterns := scanner.Text()
	
	// Разобрать входные данные
	entries := strings.Split(logEntries, ",")
	layouts := strings.Split(layoutPatterns, ",")
	
	// Инициализировать счетчики для статистики
	totalEntries := len(entries)
	successfulParses := 0
	failedParses := 0
	layoutUsage := make(map[string]int)
	var parsedTimes []time.Time
	
	// TODO: Напишите свой код ниже
	// 1. Отобразить заголовок приложения
	// 2. Отобразить статус обработки
	// 3. Обработать каждую запись лога:
	//    - Разделить запись по символу ":" для получения метки времени и сообщения
	//    - Пробовать каждый шаблон макета, пока один из них не сработает
	//    - Отобразить результаты парсинга
	//    - Обновить статистику
	// 4. Отобразить статистику парсинга
	// 5. Отобразить статистику использования макетов
	// 6. Если метки времени были разобраны, отобразить хронологический анализ
	// 7. Отобразить сообщение о завершении
	
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком