Repository: slashmili/jdatetime

Issue:
__ne__ fails for jdatetime.datetime vs datetime.datetime
Comparing `jdatetime.datetime` with `datetime.datetime` using `!=` fails.

## How to Reproduce the Issue:

```python
import jdatetime
import datetime

jdt = jdatetime.datetime(1403, 10, 4, 12, 0, 0)
dt = datetime.datetime(2025, 1, 22, 12, 0, 0)

print(jdt != dt)
```

**Expected Behavior**:
The comparison should return `True` since the datetimes are different.

**Actual Behavior**:
The comparison retrun `False`.

## Environment

- jdatetime version: jdatetime-5.1.0
- Python version: python 3.11
- OS: Ubuntu

Discussion:

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc2e30e..440422d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+### Fixed
+
+* Fix __ne__ for different datetime types #164
+
 ## [5.1.0] - 2025-01-13
 
 ### Fixed
diff --git a/jdatetime/__init__.py b/jdatetime/__init__.py
index cf3641c..29a2681 100644
--- a/jdatetime/__init__.py
+++ b/jdatetime/__init__.py
@@ -481,17 +481,6 @@ class date:
 
         return not self.__ge__(other_date)
 
-    def __ne__(self, other_date):
-        """x.__ne__(y) <==> x!=y"""
-        if other_date is None:
-            return True
-        if isinstance(other_date, py_datetime.date):
-            return self.__ne__(date.fromgregorian(date=other_date))
-        if not isinstance(other_date, date):
-            return NotImplemented
-
-        return not self.__eq__(other_date)
-
     def __hash__(self):
         """x.__hash__() <==> hash(x)"""
         gd = self.togregorian()


Test patch:
diff --git a/tests/test_jdatetime.py b/tests/test_jdatetime.py
index f8b82cf..78b114f 100644
--- a/tests/test_jdatetime.py
+++ b/tests/test_jdatetime.py
@@ -763,6 +763,71 @@ class TestJdatetimeComparison(TestCase):
         dt2 = "not a datetime object"
         self.assertFalse(dt1 == dt2)
 
+    # __ne__
+    def test_ne_different_dates(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 0, 0, 0)
+        dt2 = jdatetime.datetime(1403, 1, 2, 0, 0, 0)
+        self.assertTrue(dt1 != dt2)
+
+    def test_neq_different_times(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        dt2 = jdatetime.datetime(1403, 1, 1, 13, 0, 0)
+        self.assertTrue(dt1 != dt2)
+
+    def test_neq_different_timezones(self):
+        gmt = GMTTime()
+        teh = TehranTime()
+
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0, tzinfo=teh)
+        dt2 = jdatetime.datetime(1403, 1, 1, 12, 0, 0, tzinfo=gmt)
+        self.assertTrue(dt1 != dt2)
+
+    def test_neq_same_datetime(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        dt2 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        self.assertFalse(dt1 != dt2)
+
+    def test_neq_different_types(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        self.assertTrue(dt1 != "1403-01-01 12:00:00")
+
+    def test_neq_with_none(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        self.assertTrue(dt1.__ne__(None))
+
+    def test_neq_different_datetime_types(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        dt2 = dt1.togregorian()
+        self.assertFalse(dt1 != dt2)
+
+        # different hour
+        dt2 = dt1.togregorian() + datetime.timedelta(hours=1)
+        self.assertTrue(dt1 != dt2)
+        dt2 = dt1.togregorian() - datetime.timedelta(hours=1)
+        self.assertTrue(dt1 != dt2)
+
+        # different day
+        dt2 = dt1.togregorian() + datetime.timedelta(days=1)
+        self.assertTrue(dt1 != dt2)
+        dt2 = dt1.togregorian() - datetime.timedelta(days=1)
+        self.assertTrue(dt1 != dt2)
+
+        # different month
+        dt2 = dt1.togregorian() + datetime.timedelta(days=31)
+        self.assertTrue(dt1 != dt2)
+        dt2 = dt1.togregorian() - datetime.timedelta(days=31)
+        self.assertTrue(dt1 != dt2)
+
+        # different year
+        dt2 = dt1.togregorian() + datetime.timedelta(days=370)
+        self.assertTrue(dt1 != dt2)
+        dt2 = dt1.togregorian() - datetime.timedelta(days=370)
+        self.assertTrue(dt1 != dt2)
+
+    def test_neq_not_implemented(self):
+        dt1 = jdatetime.datetime(1403, 1, 1, 12, 0, 0)
+        self.assertEqual(dt1.__ne__("not datetime object"), NotImplemented)
+
     # __ge__
     def test_ge_with_same_datetime(self):
         dt1 = jdatetime.datetime(1402, 7, 8, 12, 0, 0)