private DateTime GetDateTime(ZipExtraData extraData)
{
// Check for NT timestamp
// NOTE: Disable by default to match behavior of InfoZIP
#if RESPECT_NT_TIMESTAMP
NTTaggedData ntData = extraData.GetData<NTTaggedData>();
if (ntData != null)
return ntData.LastModificationTime;
#endif
// Check for Unix timestamp
ExtendedUnixData unixData = extraData.GetData<ExtendedUnixData>();
if (unixData != null &&
// Only apply modification time, but require all other values to be present
// This is done to match InfoZIP's behaviour
((unixData.Include & ExtendedUnixData.Flags.ModificationTime) != 0) &&
((unixData.Include & ExtendedUnixData.Flags.AccessTime) != 0) &&
((unixData.Include & ExtendedUnixData.Flags.CreateTime) != 0))
return unixData.ModificationTime;
// Fall back to DOS time
uint sec = Math.Min(59, 2 * (dosTime & 0x1f));
uint min = Math.Min(59, (dosTime >> 5) & 0x3f);
uint hrs = Math.Min(23, (dosTime >> 11) & 0x1f);
uint mon = Math.Max(1, Math.Min(12, ((dosTime >> 21) & 0xf)));
uint year = ((dosTime >> 25) & 0x7f) + 1980;
int day = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)mon), (int)((dosTime >> 16) & 0x1f)));
return new DateTime((int)year, (int)mon, day, (int)hrs, (int)min, (int)sec, DateTimeKind.Utc);
}