DateTimeConverter.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. namespace PhpZip\Util;
  3. use PhpZip\Exception\ZipException;
  4. /**
  5. * Convert unix timestamp values to DOS date/time values and vice versa.
  6. *
  7. * @author Ne-Lexa alexey@nelexa.ru
  8. * @license MIT
  9. */
  10. class DateTimeConverter
  11. {
  12. /**
  13. * Smallest supported DOS date/time value in a ZIP file,
  14. * which is January 1st, 1980 AD 00:00:00 local time.
  15. */
  16. const MIN_DOS_TIME = 0x210000; // (1 << 21) | (1 << 16)
  17. /**
  18. * Largest supported DOS date/time value in a ZIP file,
  19. * which is December 31st, 2107 AD 23:59:58 local time.
  20. */
  21. const MAX_DOS_TIME = 0xff9fbf7d; // ((2107 - 1980) << 25) | (12 << 21) | (31 << 16) | (23 << 11) | (59 << 5) | (58 >> 1);
  22. /**
  23. * Convert a 32 bit integer DOS date/time value to a UNIX timestamp value.
  24. *
  25. * @param int $dosTime Dos date/time
  26. * @return int Unix timestamp
  27. */
  28. public static function toUnixTimestamp($dosTime)
  29. {
  30. if (self::MIN_DOS_TIME > $dosTime) {
  31. $dosTime = self::MIN_DOS_TIME;
  32. } elseif (self::MAX_DOS_TIME < $dosTime) {
  33. $dosTime = self::MAX_DOS_TIME;
  34. }
  35. return mktime(
  36. ($dosTime >> 11) & 0x1f, // hour
  37. ($dosTime >> 5) & 0x3f, // minute
  38. 2 * ($dosTime & 0x1f), // second
  39. ($dosTime >> 21) & 0x0f, // month
  40. ($dosTime >> 16) & 0x1f, // day
  41. 1980 + (($dosTime >> 25) & 0x7f) // year
  42. );
  43. }
  44. /**
  45. * Converts a UNIX timestamp value to a DOS date/time value.
  46. *
  47. * @param int $unixTimestamp The number of seconds since midnight, January 1st,
  48. * 1970 AD UTC.
  49. * @return int A DOS date/time value reflecting the local time zone and
  50. * rounded down to even seconds
  51. * and is in between DateTimeConverter::MIN_DOS_TIME and DateTimeConverter::MAX_DOS_TIME.
  52. * @throws ZipException If unix timestamp is negative.
  53. */
  54. public static function toDosTime($unixTimestamp)
  55. {
  56. if (0 > $unixTimestamp) {
  57. throw new ZipException("Negative unix timestamp: " . $unixTimestamp);
  58. }
  59. $date = getdate($unixTimestamp);
  60. if ($date['year'] < 1980) {
  61. return self::MIN_DOS_TIME;
  62. }
  63. $date['year'] -= 1980;
  64. return ($date['year'] << 25 | $date['mon'] << 21 |
  65. $date['mday'] << 16 | $date['hours'] << 11 |
  66. $date['minutes'] << 5 | $date['seconds'] >> 1);
  67. }
  68. }