diff --git a/jython-java8compat.patch b/jython-java8compat.patch
new file mode 100644
index 0000000..f6585c1
--- /dev/null
+++ b/jython-java8compat.patch
@@ -0,0 +1,55 @@
+diff --git a/build.xml b/build.xml
+index 52dfe71..43d7649 100644
+--- a/build.xml
++++ b/build.xml
+@@ -91,8 +91,8 @@ informix.jar = ../support/jdbc-4.10.12.jar
+
+
+
+-
+-
++
++
+
+
++
++
+
+
+
+@@ -1151,7 +1155,10 @@ The text for an official release would continue like ...
+
+
+
+-
++
++
+
+
+
+@@ -1175,7 +1182,10 @@ The text for an official release would continue like ...
+
+-
++
++
+
+
+
diff --git a/jython-reproducible-now.patch b/jython-reproducible-now.patch
new file mode 100644
index 0000000..d785277
--- /dev/null
+++ b/jython-reproducible-now.patch
@@ -0,0 +1,40 @@
+diff --git a/src/org/python/modules/posix/PosixModule.java b/src/org/python/modules/posix/PosixModule.java
+index e3a8dd9..07d4b43 100644
+--- a/src/org/python/modules/posix/PosixModule.java
++++ b/src/org/python/modules/posix/PosixModule.java
+@@ -1144,7 +1144,7 @@ public class PosixModule implements ClassDictInit {
+ if (times == Py.None) {
+ // FIXME dynamically bind to java.time.Instant, available in Java 8,
+ // to potentially get higher resolution (nanosecond) time
+- atime = mtime = FileTime.from(
++ atime = mtime = FileTime.from(System.getenv("SOURCE_DATE_EPOCH") != null ? 1000 * Long.parseLong(System.getenv("SOURCE_DATE_EPOCH")) :
+ System.currentTimeMillis(), TimeUnit.MILLISECONDS);
+ } else if (times instanceof PyTuple && times.__len__() == 2) {
+ atime = getFileTime(times.__getitem__(0));
+diff --git a/src/org/python/modules/random/PyRandom.java b/src/org/python/modules/random/PyRandom.java
+index f5ea8d9..0dc4881 100644
+--- a/src/org/python/modules/random/PyRandom.java
++++ b/src/org/python/modules/random/PyRandom.java
+@@ -45,7 +45,7 @@ public class PyRandom extends PyObject {
+ final void Random_seed(PyObject seed) {
+ long n;
+ if (seed == null) {
+- seed = new PyLong(System.currentTimeMillis());
++ seed = new PyLong(System.getenv("SOURCE_DATE_EPOCH") != null ? 1000 * Long.parseLong(System.getenv("SOURCE_DATE_EPOCH")) : System.currentTimeMillis());
+ }
+ if (seed instanceof PyLong) {
+ PyLong max = new PyLong(Long.MAX_VALUE);
+diff --git a/src/org/python/modules/time/Time.java b/src/org/python/modules/time/Time.java
+index ebd9871..cf2218d 100644
+--- a/src/org/python/modules/time/Time.java
++++ b/src/org/python/modules/time/Time.java
+@@ -131,6 +131,9 @@ public class Time implements ClassDictInit
+ }
+
+ public static double time() {
++ if (System.getenv("SOURCE_DATE_EPOCH") != null) {
++ return Long.parseLong(System.getenv("SOURCE_DATE_EPOCH"));
++ }
+ return System.currentTimeMillis()/1000.0;
+ }
+
diff --git a/jython.changes b/jython.changes
index 184d55f..975a745 100644
--- a/jython.changes
+++ b/jython.changes
@@ -1,3 +1,17 @@
+-------------------------------------------------------------------
+Mon Sep 25 16:49:29 UTC 2023 - Fridrich Strba
+
+- Added patches:
+ * jython-java8compat.patch
+ + use release=8 on compilers that support it
+ * jython-reproducible-builds.patch
+ + preserve mtimes of files since they get embedded in the
+ resultiong class files
+ + use relative paths of files that get included in antlr
+ getGrammar* methods
+ * jython-reproducible-now.patch
+ + use SOURCE_DATE_EPOCH for "now" if the variable is set
+
-------------------------------------------------------------------
Wed Jun 28 10:40:43 UTC 2023 - Pedro Monreal
diff --git a/jython.spec b/jython.spec
index b2edb85..1247cae 100644
--- a/jython.spec
+++ b/jython.spec
@@ -32,6 +32,9 @@ Patch0: %{name}-build.patch
Patch1: %{name}-dont-validate-pom.patch
Patch2: %{name}-cachedir.patch
Patch3: %{name}-fix-tty-detection.patch
+Patch4: %{name}-reproducible-now.patch
+Patch5: %{name}-reproducible-builds.patch
+Patch6: %{name}-java8compat.patch
BuildRequires: ant
BuildRequires: ant-junit
BuildRequires: antlr3-java