How to set mtime value

Sep 8, 2009 at 7:52 PM

Hello,

When adding ZipEntry objects, I need to set the mtime value. This is a readonly property, and it seems the only way I could set it is by using SetNtfsTimes(). Can someone please confirm that this is indeed the only way to set this property.

Thanks,

Norton.

Coordinator
Sep 8, 2009 at 8:13 PM

That is correct.

Rather than providing three separate setters and getters for the modified, created, and accessed time, I converged them into a single method.

 

Sep 8, 2009 at 8:28 PM

Doesn't this method make an assumption that the DateTime passed in is a local time and it sets the mtime to the UTC? If someone uses the zip file as a container to save and read data, it makes it a bit inconvinient to reconstruct the container with the same data that has the same timestamps. This is because they would need to persist the files within the zip file with local time stamp in order to restore it back to the correct mtime. Otherwise, it will keep shifting time. This is not a big deal really, but it would have been more convenient to be able to just set the value with the exact utc timestamp.

Thanks again,

Norton.

Coordinator
Sep 8, 2009 at 8:30 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Sep 8, 2009 at 9:19 PM

Hey Norton, No.  I don't understand the issue you're raising.  The documentation for SetEntryTimes says:

When adding an entry from a file or directory, the Creation, Access, and Modified times for the given entry are automatically set from the filesystem values. When adding an entry from a stream or string, the values are implicitly set to DateTime.Now. The application may wish to set these values to some arbitrary value, before saving the archive. If you set the times using this method, the LastModified property also gets set, to the same value provided for mtime.

The values you set here will be retrievable with the ModifiedTime, CreationTime and AccessedTime read-only properties.

When this method is called, the EmitTimesInWindowsFormatWhenSaving flag is automatically set.

DateTime values provided here without a DateTimeKind are assumed to be Local Time.

The DateTime you pass in can be of any kind.  If it is DateTimeKind.Unspecified, then it is assumed to be DateTimeKind.Local.   In any case when saving the zip file, the times are formatted in UTC.  This is an implementation detail and you shouldn't care about it.  When the files are extracted, the times are set on the file as UTC.  Depending on the way you look at the file (Windows Explorer, some other tool) it may be displayed in Local time or in UTC.  The timestamp on the extracted file will be the same as the timestamp on the file that was put into the zip file, regardless of what DateTimeKind was used  in any call to SetEntryTimes(). 

Also, as the doc states, you don't have to set the creation, accessed, or modified times on a zip entry when adding a file to a zipfile.  It's done automatically.  You need the SetEntryTimes method only when you want to override the times on the entry, as, for example, when you want all files in a zip to have the same time. or, when adding entries from a stream or from a string (via AddEntry()). 

If you are experiencing an unexpected shift in entry times, comparing the times on the files added, versus the times on the files later extracted, that's a bug.   You'll have to describe how you get this behavior.

The workitem I opened and already closed is to make the CreationTime, AccessedTime and ModifiedTime properties read/write.  (These havve been renamed in v1.9 from Ctime, Atime, and Mtime for clarity).  So with the next interim binary build you will be able to individually override the file entry times.  Of course you will still be able to use SetEntryTimes(). 

 

Sep 8, 2009 at 10:12 PM

I am creating entries from the stream. Do you know how to modify the Kind property of a DateTime object? I cannot even create a new DateTime object from an existing one by passing DateTimeKind.Utc. For example, when I do something like this: DateTime someDateTime = new DateTime(zipEntry.Mtime.Ticks, zipEntry.Mtime.Kind); - the someDateTime object will still have the Kind property set to DateTimeKind.Unspecified, even though the zipEntry.Mtime.Kind is Utc.

Coordinator
Sep 9, 2009 at 12:55 AM

My code doesn't agree with what you are reporting.

I just tried

        System.DateTime now2 = System.DateTime.UtcNow;
        System.Console.WriteLine("now2 DateTime: {0} ({1})", now2.ToString("G"), now2.Kind);

        DateTime fromTicks = new DateTime(now2.Ticks, now2.Kind);
        System.Console.WriteLine("fromTicks DateTime: {0} ({1})", fromTicks.ToString("G"), fromTicks.Kind);
       

And I get the expected results.  In both cases the Kind is Utc.