Ответ
Основным типом для работы со временем в Go является time.Time
из стандартной библиотеки. Выбор формата для хранения или передачи зависит от конкретной задачи.
1. В коде (в памяти)
Всегда используйте time.Time
. Это не просто число или строка, а полноценная структура, которая хранит время с наносекундной точностью и информацию о временной зоне (location). Это позволяет избежать ошибок при арифметических операциях и сравнениях.
2. В базах данных
- Предпочтительный способ: Использовать нативные типы данных БД, такие как
TIMESTAMP WITH TIME ZONE
(PostgreSQL) илиDATETIME
(MySQL). Большинство драйверов баз данных (database/sql
) умеют автоматически конвертироватьtime.Time
в нужный формат и обратно. - Альтернатива: Хранить время как
BIGINT
, используя Unix Timestamp (количество секунд или миллисекунд с 1 января 1970 года). Недостаток: теряется информация о временной зоне.
3. При передаче по сети (JSON/API)
- Стандарт: Строка в формате
RFC3339
/ISO 8601
. Это общепринятый стандарт, который однозначен, читаем человеком и включает информацию о смещении временной зоны. В Go для этого есть константаtime.RFC3339
.- Пример:
"2023-10-27T10:00:00Z"
(Z означает UTC).
- Пример:
- Альтернатива: Число (JSON Number), представляющее Unix Timestamp.
Пример работы с форматами:
import (
"fmt"
"time"
)
func main() {
// Рекомендуется работать с временем в UTC, чтобы избежать путаницы
now := time.Now().UTC()
// 1. Форматирование в строку для API (RFC3339)
rfcString := now.Format(time.RFC3339)
fmt.Println("Для API (RFC3339):", rfcString)
// 2. Получение Unix timestamp для хранения в виде числа
unixTimestamp := now.Unix()
fmt.Println("Unix Timestamp (секунды):", unixTimestamp)
// 3. Парсинг времени из строки
parsedTime, err := time.Parse(time.RFC3339, rfcString)
if err != nil {
panic(err)
}
fmt.Println("Время совпадает после парсинга:", now.Equal(parsedTime))
}