bpo-34097: Add support for zipping files older than 1980-01-01 (GH-8270)

ZipFile can zip files older than 1980-01-01 and newer than 2107-12-31 using
a new strict_timestamps parameter at the cost of setting the timestamp
to the limit.
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 2757ce9..6da1778 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -469,7 +469,7 @@
             extra = extra[ln+4:]
 
     @classmethod
-    def from_file(cls, filename, arcname=None):
+    def from_file(cls, filename, arcname=None, *, strict_timestamps=True):
         """Construct an appropriate ZipInfo for a file on the filesystem.
 
         filename should be the path to a file or directory on the filesystem.
@@ -484,6 +484,10 @@
         isdir = stat.S_ISDIR(st.st_mode)
         mtime = time.localtime(st.st_mtime)
         date_time = mtime[0:6]
+        if not strict_timestamps and date_time[0] < 1980:
+            date_time = (1980, 1, 1, 0, 0, 0)
+        elif not strict_timestamps and date_time[0] > 2107:
+            date_time = (2107, 12, 31, 23, 59, 59)
         # Create ZipInfo instance to store file information
         if arcname is None:
             arcname = filename
@@ -1673,7 +1677,8 @@
                                    " would require ZIP64 extensions")
 
     def write(self, filename, arcname=None,
-              compress_type=None, compresslevel=None):
+              compress_type=None, compresslevel=None, *,
+              strict_timestamps=True):
         """Put the bytes from filename into the archive under the name
         arcname."""
         if not self.fp:
@@ -1684,7 +1689,8 @@
                 "Can't write to ZIP archive while an open writing handle exists"
             )
 
-        zinfo = ZipInfo.from_file(filename, arcname)
+        zinfo = ZipInfo.from_file(filename, arcname,
+                                  strict_timestamps=strict_timestamps)
 
         if zinfo.is_dir():
             zinfo.compress_size = 0