1414use OCP \Files \IRootFolder ;
1515use OCP \Files \NotFoundException ;
1616use OCP \Files \NotPermittedException ;
17+ use OCP \IDateTimeZone ;
1718use OCP \IRequest ;
1819use ownCloud \TarStreamer \TarStreamer ;
1920use Psr \Log \LoggerInterface ;
@@ -40,7 +41,12 @@ public static function isUserAgentPreferTar(IRequest $request): bool {
4041 * @param int $numberOfFiles The number of files (and directories) that will
4142 * be included in the streamed file
4243 */
43- public function __construct (IRequest |bool $ preferTar , int |float $ size , int $ numberOfFiles ) {
44+ public function __construct (
45+ IRequest |bool $ preferTar ,
46+ int |float $ size ,
47+ int $ numberOfFiles ,
48+ private IDateTimeZone $ timezoneFactory ,
49+ ) {
4450 if ($ preferTar instanceof IRequest) {
4551 $ preferTar = self ::isUserAgentPreferTar ($ preferTar );
4652 }
@@ -156,7 +162,7 @@ public function addFileFromStream($stream, string $internalName, int|float $size
156162 $ options = [];
157163 if ($ time ) {
158164 $ options = [
159- 'timestamp ' => $ time
165+ 'timestamp ' => $ this -> fixTimestamp ( $ time),
160166 ];
161167 }
162168
@@ -176,7 +182,7 @@ public function addFileFromStream($stream, string $internalName, int|float $size
176182 public function addEmptyDir (string $ dirName , int $ timestamp = 0 ): bool {
177183 $ options = null ;
178184 if ($ timestamp > 0 ) {
179- $ options = ['timestamp ' => $ timestamp ];
185+ $ options = ['timestamp ' => $ this -> fixTimestamp ( $ timestamp) ];
180186 }
181187
182188 return $ this ->streamerInstance ->addEmptyDir ($ dirName , $ options );
@@ -191,4 +197,14 @@ public function addEmptyDir(string $dirName, int $timestamp = 0): bool {
191197 public function finalize () {
192198 return $ this ->streamerInstance ->finalize ();
193199 }
200+
201+ private function fixTimestamp (int $ timestamp ): int {
202+ if ($ this ->streamerInstance instanceof ZipStreamer) {
203+ // Zip does not support any timezone information
204+ // while tar is interpreted as Unix time the Zip time is interpreted as local time of the user...
205+ $ zone = $ this ->timezoneFactory ->getTimeZone ($ timestamp );
206+ $ timestamp += $ zone ->getOffset (new \DateTimeImmutable ('@ ' . (string )$ timestamp ));
207+ }
208+ return $ timestamp ;
209+ }
194210}
0 commit comments