Retore Local Time on File Stamps across Time Zones

Nov 24, 2010 at 6:46 PM

When I create and unzip a zip file with DotNetZip, the time is off by the difference between time zones I created it in and the one I extract it in.  For instance, let's say I zip up the file "AnExample.XLS" at 5am on the Pacific Coast (PST), then copy the zip file to a machine on the East Coast and unzip it with DotNetZip using the code below.  The "file modified" timestamp in the resulting unzipped file shows 8am.

I need the timestamps on the zipped files (for reasons of my own) to be the extracted to the same times as they were in their own time zone. The aforementioned "AnExample.XLS" file would need a 5am timestamp in any timezone where I extract it.  When I unzip it with (for instance) WinRAR, it works out fine; but I'd much rather be using DotNetZip.

It seems like the extraction pulls the UTC values in "ZipEntry.ModifiedTime" and the system applies the UTC Offset of the local time.  If I query the contents of the zip file with DotNetZip, I get the correct local times from ZipEntry.LastModified. I was planning to load the values and filenames into a dictionary and rewrite the timestamps on each after extraction. There shouldn't be any duplicate filenames, so it would work, but is there a more elegant solution?

    Using zip As ZipFile = ZipFile.Read(strZipToOpen)
          If strPassword <> "" Then zip.Password = strPassword
          If Not zip.Comment Is Nothing Then strComment = zip.Comment
          totalEntriesToProcess = zip.Entries.Count
          SetProgressBarMax(zip.Entries.Count)
          AddHandler zip.ExtractProgress, New EventHandler(Of ExtractProgressEventArgs)(AddressOf zip_ExtractProgress)
          zip.ExtractAll(strExtractDir, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently)
    End Using

Coordinator
Nov 24, 2010 at 8:11 PM
ChrisFontenot13 wrote:

When I create and unzip a zip file with DotNetZip, the time is off by the difference between time zones I created it in and the one I extract it in.  For instance, let's say I zip up the file "AnExample.XLS" at 5am on the Pacific Coast (PST), then copy the zip file to a machine on the East Coast and unzip it with DotNetZip using the code below.  The "file modified" timestamp in the resulting unzipped file shows 8am.

I need the timestamps on the zipped files (for reasons of my own) to be the extracted to the same times as they were in their own time zone. The aforementioned "AnExample.XLS" file would need a 5am timestamp in any timezone where I extract it.  When I unzip it with (for instance) WinRAR, it works out fine; but I'd much rather be using DotNetZip.

It seems like the extraction pulls the UTC values in "ZipEntry.ModifiedTime" and the system applies the UTC Offset of the local time.  If I query the contents of the zip file with DotNetZip, I get the correct local times from ZipEntry.LastModified. I was planning to load the values and filenames into a dictionary and rewrite the timestamps on each after extraction. There shouldn't be any duplicate filenames, so it would work, but is there a more elegant solution? 

Yes, by default DotNetZip uses UTC timestamps for entries you add to ZipFiles. When you extract a zipfile using DotNetZip, and the zipfile was created with DotNetZip, then upon extraction the extracted files will get the UTC time (8am in NYC is the same as 5am in Los Angeles).  When you display the timestamp for the file in Windows Explorer or some other tool, it will typically apply the UTC offset and display the local time.   If for some reason you don't want the actual UTC time to be applied to entries in a zip file, you can do one of these things:

  1. you can modify the ModifiedTime property on each entry, using an offset for each timezone.   This would require you to know the zipping timezone, the unzipping timezone, and be able to calculate the offset between the two.  There are two options here:
    1. you apply the delta at the time of creation of the zip.  In this case, there is no one-size fits all solution.  If some of your zips need to be unzipped in London, and some in New York, and then you'd have to apply a different delta, depending on the eventual unzip location.  In other words, you'd need to produce one zipfile for eventual unzip in NY, and a second one for eventual unzip in London. 
    2. Apply the delta at the time of unzip.  In this case you'd assume the zip creation location is fixed.   Your approach of iterating through the entries and adjusting the time would work.  A better idea might be to modify the ModifiedTime of each ZipEntry before extraction.  One tweak to your approach is to use a self-extracting zip for extraction, and upon extraction automatically run a program (that's a feature of the SFX) that intelligently calculates the offset according to its current timezone, and resets the time of the already-unzipped files in the filesystem. 
  2. You can NOT store the times as UTC when you create the zip. The succintly named ZipFile.EmitTimesInWindowsFormatWhenSaving property, when set to false, tells DotNetZip to NOT use UTC times.  DotNetZip WILL store the DOS  time for each entry, which will not include any timezone information. Set this property before adding any entries into the ZipFile.  Therefore if your file has a 5am (localtime) timestamp when you zip in California, it will have a 5am (localtime) timestamp when you unzip in New York.  If you do this, you will get a lower precision time (accurate to 2 seconds) in addition to losing the timezone information.