time.Time упрощает работу с датами и временем в Go, и даже входит в стандартную библиотеку! Однако в большинстве случаев структура time.Time{} использует более 24 байта памяти, и я сталкивался с ситуациями, когда мне нужно было хранить в памяти миллионы байтов, но все, что мне действительно было нужно, была дата UTC! Go-TinyDate решает эту проблему, используя всего 4 байта памяти.
Звезда Github! https://github.com/lane-c-wagner/go-tinydate
Как?
Давайте посмотрим на структуру time.Time:
type Time struct {
wall uint64 // 8 bytes
ext int64 // b bytes
loc *Location // 8 bytes if not nil, plus location memory
}
type Location struct {
name string // unlimited
zone []zone // unlimited
tx []zoneTrans // unlimited
cacheStart int64 // 8 bytes
cacheEnd int64 // 8 bytes
cacheZone *zone // 8 bytes if not nil, plus zone
}
type zone struct {
name string // unlimited
offset int // 4-8 bytes depending on OS
isDST bool // 1 bit
}
type zoneTrans struct {
when int64 // 8 bytes
index uint8 // 1 byte
isstd, isutc bool // 1 bit
}
Как видите, в зависимости от того, как установлен TimeZone, может быть достаточно много памяти, выделенной только для хранения time.Time. Даже если местоположение не задано, нижняя граница по-прежнему составляет 16 байт.
В отличие от tinydate.TinyDate{}:
type TinyDate struct {
year uint16 // 2 byte
month uint8 // 1 byte
day uint8 // 1 byte
}
Всего 4 байта! Мы отказываемся от возможности отслеживать что-то более конкретное, чем дата, но часто это все, что нам нужно.
Быстрый старт
Создайте дату и добавьте к ней:
package main
import (
tinydate "github.com/lane-c-wagner/go-tinydate"
)
func main(){
td, err := tinydate.New(2020, 04, 3)
if err != nil {
fmt.Println(err.Error())
}
td = td.Add(time.Hour * 48)
fmt.Println(td)
// prints 2020-04-05
}
Или переведите время на крошечную дату и обратно:
newTinydate, err := FromTime(time.Now())
if err != nil{
fmt.Println(err.Error())
}
convertedTime := newTinydate.ToTime()
Когда я должен использовать это?
Как говорится в Readme TinyDate, если вы не ограничены в ресурсах, лучше придерживаться стандартного time.Time. Но следующие ситуации могут быть вескими причинами для перехода на TinyDate:
- Вы работаете во встроенных системах, и каждый байт имеет значение
- Вы работаете с системой, в которой хранятся тысячи дат, и сокращение затрат памяти на ›75 % имеет большое значение.
- Вы уверены, что вам никогда не понадобится больше, чем точность даты
Почему нет часовых поясов?
Главная причина? Часовые пояса занимают больше всего памяти в структуре time.Time, однако рекомендуется обычно хранить даты и время только в формате UTC. TinyDate остается крошечным, всегда сохраняя даты в формате UTC, но по-прежнему дает возможность вычислять даты в других часовых поясах с помощью таких методов, как ParseInLocation, FromTime и ToTime.
API
API tinydate.Tinydate во многом повторяет интерфейс time.Time. Отсутствуют только те методы, которые не имеют смысла без часового пояса или внутридневной поддержки. Проверьте годок для справки: https://godoc.org/github.com/lane-c-wagner/go-tinydate
Спасибо за чтение
Напишите мне в твиттере @wagslane, если у вас есть какие-либо вопросы или комментарии.
Переулок на Dev.to: wagslane
Если вам понравился пакет, поставьте ему звезду на Github
Пост Я написал Go-TinyDate, The Missing Golang Date Package впервые появился на Qvault.