これまでの Go の archive/zip には問題があり、zip ファイルに格納されるファイルのタイムゾーンが UTC になっていた為、日本であれば9時間ずれてしまうという問題があった。
これは zip の NTFS/UNIX/ExtendedTS extra fields を扱っていなかったのが問題。以前一度僕のパッチがマージされたが問題がありリバートされてしまっていた。
archive/zip: add FileHeader.Modified field - golang/go@6e8894d - GitHub
The ModifiedTime and ModifiedDate fields are not expressive enough for many of the time extensions t...
https://github.com/golang/go/commit/6e8894d5ffca9acc635e0d7298167122ed52ce55
この修正により、Reader は NTFS/UNIX/ExtendedTS extra fields を見る様になったので、圧縮した際のファイルのタイムスタンプが正しく扱えるようになった。Modified という属性が FileHeader に追加された。Reader は時刻拡張がある場合には ModTime と Modified が同じ物になる。Writer については Modified に自分のタイムゾーンの時刻を設定する必要がある。
header.Modified = header.Modified.In(time.Local)
もう1点、archive/zip には日本語のファイル名が正しく扱えないという問題があった。
archive/zip: add FileHeader.NonUTF8 field - golang/go@4fcc835 - GitHub
The NonUTF8 field provides users with a way to explictly tell the ZIP writer to avoid setting the UT...
https://github.com/golang/go/commit/4fcc835971ad63cf913ebe074ef6191e35a44ab9
以前僕が Golang の文字列は UTF-8 である事から archive/zip のヘッダに UTF-8 ビット(11)を立てる修正を入れたけど、このビットを立てるかどうかを決定できる NonUTF8 というフラグが追加された。この修正により、Reader は FileHeader の NonUTF8 フラグを参照し、ファイル名が UTF-8 かそうでないかを判断できる。zip のフォーマットにはファイル名が何で書かれているかは書かれていないので、そこはさすがに解凍する方が Shift_JIS 等に変換する必要がある。また Writer もこのフラグを立て、ファイル名を Shift_JIS に変換して書く事で Shift_JIS しか対応していない zip アーカイバでも読む事の出来る zip ファイルを作れる様になった。これでずいぶん長いあいだ解決してこなかった Go の archive/zip の問題は一通り修正された事になる。めでたい。