#go #alpine #tzdata
#Вперед #alpine-linux #tzdata
Вопрос:
Я только что наткнулся на ошибку с пакетом tzdata2020c для alpine. Он не вычисляет правильное время для Европы / Берлина после запланированного перехода на летнее время в следующее воскресенье 25 октября 2020 года. Версия tzdata2020c использует CEST, например, для 31 октября 2020 года и часового пояса Европа / Берлин, тогда как CET будет правильным.
Кто-нибудь знает, как вручную добавить новую версию базы данных tzdata2020d, доступную здесь .
Мое приложение, написанное на Go, неправильно использует CEST для Европы / Берлина 31 октября 2020 года с использованием tzdata2020c:
То же приложение корректно использует CET для Европы / Берлина 31 октября 2020 года с использованием tzdata2020a:
Комментарии:
1. Я повторил эту проблему; игровая площадка работает так, как ожидалось, как и изображения docker
golang:latest
иgolang:alpine
. Однако, если я установлю данные часового пояса в alpine image (apk add tzdata
), результаты будут неверными (все времяCEST
). Запускexport ZONEINFO=/usr/local/go/lib/time/zoneinfo.zip
исправляет это (поэтому быстрым решением было бы использовать этот подход).
Ответ №1:
Ручная установка tzdata2020d
файлов сама по себе не исправит это. Однако следующее должно (успешно протестировано с golang:alpine
помощью образа docker):
mkdir tz
cd tz
wget https://www.iana.org/time-zones/repository/releases/tzdata2020d.tar.gz
tar -xvf tzdata2020d.tar.gz
zic -b fat -d zoneinfo/ europe
cp zoneinfo/Europe/Berlin /usr/share/zoneinfo/Europe/Berlin
Другие обходные пути включают:
- Обновитесь до Go 1.15.4 или 1.14.11.
- Используйте
ZONEINFO
переменную среды, чтобы выбрать другой файл зоны (напримерexport ZONEINFO=/usr/local/go/lib/time/zoneinfo.zip
;zoneinfo.zip
находится в установке go). - Включите пакет tzdata в свое приложение (и не устанавливайте tzdata в контейнер — пакет используется только в том случае, если пакет time не может найти файлы tzdata в системе).
- Используйте контейнер, созданный с нуля (в сочетании с одним из вышеуказанных вариантов)
- Закрепите более раннюю версию alpine (например, alpine: 3.8), которая использует 2020a или более раннюю (обратите внимание, что версия 3.8 истекла с датой окончания поддержки).
Причина
Эта проблема была вызвана изменением в zic
приложении; до версии, включенной в выпуск 2020b, по умолчанию fat
использовался режим, в котором приложения go обрабатывались правильно. По умолчанию используется now thin
, и go не поддерживает этот формат (без этого исправления). К сожалению LoadLocation
, функция автоматически завершается сбоем (возвращает неверную информацию о зоне).
Проблема, вероятно, возникнет везде, где используются файлы часовых поясов 2020b или более поздних версий (если только сопровождающий пакета не переопределяет значения по умолчанию при запуске zic
).
zic
Подробные сведения
iana распространяет информацию о часовых поясах в виде серии текстовых файлов вместе с рядом приложений. Одно из таких приложений zic
обрабатывает текстовые файлы в двоичные файлы (RFC 8536), в которые они развернуты /usr/share/zoneinfo
.
Этот коммит изменил формат вывода по умолчанию с fat
на slim
. Результатом этого является то, что файлы часовых поясов, созданные с использованием 2020b или более поздних версий, не будут правильно считываться Go (если они не созданы с использованием -b fat
аргумента).
Исправьте
Это исправлено в Go 1.15.4 и 1.14.11.
Возникла проблема, и проблема частично устранена недавним коммитом (основной целью этого коммита было уменьшить размер time/tzdata
пакета, но это также должно быть исправлено). Смотрите Эту проблему в другой части исправления.
Тестирование
Следующее приложение демонстрирует проблему:
package main
import (
"fmt"
"time"
)
func main() {
b, err := time.LoadLocation("Europe/Berlin")
if err != nil {
panic(err)
}
t := time.Date(2020, 10, 23, 11, 00, 00, 00, time.UTC)
fmt.Printf("1: %s %sn", t, t.In(b))
t = time.Date(2020, 10, 31, 11, 00, 00, 00, time.UTC)
fmt.Printf("2: %s %sn", t, t.In(b))
}
Выходные данные (Alpine 3.12 в Docker) по состоянию на 19 октября:
1: 2020-10-23 11:00:00 0000 UTC 2020-10-23 13:00:00 0200 CEST
2: 2020-10-31 11:00:00 0000 UTC 2020-10-31 13:00:00 0200 CEST
Это неверно, потому что должно быть 31 CET
-е число (Alpine 3.8 генерирует правильный результат).
Комментарии:
1. Исправлено с Go 1.15.4: проблема # 42138 находится на этапе 1.15.4 или см. Примечания к выпуску .
Ответ №2:
Возникла та же проблема с изображением alpine: 3.9, и ее удалось исправить на основе ответа Brit. Спасибо.