]> git.ktnx.net Git - mobile-ledger.git/commitdiff
new: go to a date from transaction list
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Tue, 16 Jun 2020 21:02:40 +0000 (00:02 +0300)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Wed, 17 Jun 2020 18:51:45 +0000 (18:51 +0000)
15 files changed:
app/src/main/java/net/ktnx/mobileledger/async/TransactionDateFinder.java [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/async/UpdateTransactionsTask.java
app/src/main/java/net/ktnx/mobileledger/model/Data.java
app/src/main/java/net/ktnx/mobileledger/model/LedgerTransaction.java
app/src/main/java/net/ktnx/mobileledger/model/MobileLedgerProfile.java
app/src/main/java/net/ktnx/mobileledger/model/TransactionListItem.java
app/src/main/java/net/ktnx/mobileledger/ui/DatePickerFragment.java
app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListFragment.java
app/src/main/java/net/ktnx/mobileledger/utils/Globals.java
app/src/main/java/net/ktnx/mobileledger/utils/SimpleDate.java
app/src/main/res/drawable-anydpi-v21/ic_filter_list_white_24dp.xml
app/src/main/res/drawable/ic_baseline_calendar_today_24.xml [new file with mode: 0644]
app/src/main/res/layout/date_picker_view.xml
app/src/main/res/menu/transaction_list.xml
app/src/test/java/net/ktnx/mobileledger/utils/SimpleDateTest.java [new file with mode: 0644]

diff --git a/app/src/main/java/net/ktnx/mobileledger/async/TransactionDateFinder.java b/app/src/main/java/net/ktnx/mobileledger/async/TransactionDateFinder.java
new file mode 100644 (file)
index 0000000..c15e599
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.async;
+
+import android.os.AsyncTask;
+
+import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.TransactionListItem;
+import net.ktnx.mobileledger.utils.LockHolder;
+import net.ktnx.mobileledger.utils.Logger;
+import net.ktnx.mobileledger.utils.SimpleDate;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+
+public class TransactionDateFinder extends AsyncTask<SimpleDate, Void, Integer> {
+    @Override
+    protected void onPostExecute(Integer pos) {
+        Data.foundTransactionItemIndex.setValue(pos);
+    }
+    @Override
+    protected Integer doInBackground(SimpleDate... simpleDates) {
+        SimpleDate date = simpleDates[0];
+        Logger.debug("go-to-date",
+                String.format(Locale.US, "Looking for date %04d-%02d-%02d", date.year, date.month,
+                        date.day));
+        Logger.debug("go-to-date", String.format(Locale.US, "List contains %d transactions",
+                Data.transactions.size()));
+
+        try (LockHolder locker = Data.transactions.lockForWriting()) {
+            List<TransactionListItem> transactions = Data.transactions.getList();
+            TransactionListItem target = new TransactionListItem(date, true);
+            int found = Collections.binarySearch(transactions, target,
+                    new TransactionListItemComparator());
+            if (found >= 0)
+                return found;
+            else
+                return 1 - found;
+        }
+    }
+    static class TransactionListItemComparator implements Comparator<TransactionListItem> {
+        @Override
+        public int compare(TransactionListItem a, TransactionListItem b) {
+            final SimpleDate aDate = a.getDate();
+            final SimpleDate bDate = b.getDate();
+            int res = aDate.compareTo(bDate);
+            if (res != 0)
+                return -res;    // transactions are reverse sorted by date
+
+            if (a.getType() == TransactionListItem.Type.DELIMITER) {
+                if (b.getType() == TransactionListItem.Type.DELIMITER)
+                    return 0;
+                else
+                    return -1;
+            }
+            else {
+                if (b.getType() == TransactionListItem.Type.DELIMITER)
+                    return +1;
+                else
+                    return 0;
+            }
+        }
+    }
+}
index bb3d3dde82fe94fa14d632b71f2a201d262ef239..ab114531b9e78ad711fe013cc7f6fd525c7f926f 100644 (file)
@@ -63,6 +63,7 @@ public class UpdateTransactionsTask extends AsyncTask<String, Void, String> {
             }
 
             debug("UTT", sql);
+            SimpleDate latestDate = null, earliestDate = null;
             SQLiteDatabase db = App.getDatabase();
             boolean odd = true;
             SimpleDate lastDate = SimpleDate.today();
@@ -75,6 +76,10 @@ public class UpdateTransactionsTask extends AsyncTask<String, Void, String> {
                     SimpleDate date =
                             new SimpleDate(cursor.getInt(1), cursor.getInt(2), cursor.getInt(3));
 
+                    if (null == latestDate)
+                        latestDate = date;
+                    earliestDate = date;
+
                     if (!date.equals(lastDate)) {
                         boolean showMonth =
                                 (date.month != lastDate.month) || (date.year != lastDate.year);
@@ -88,6 +93,8 @@ public class UpdateTransactionsTask extends AsyncTask<String, Void, String> {
                     odd = !odd;
                 }
                 Data.transactions.setList(newList);
+                Data.latestTransactionDate.postValue(latestDate);
+                Data.earliestTransactionDate.postValue(earliestDate);
                 debug("UTT", "transaction list value updated");
             }
 
index 7c5895a104fc1a6a978acf2e3fb3b06ef932ef03..5764434f33b3dbb76f446d97cf9162986f98d1ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
  * This file is part of MoLe.
  * MoLe is free software: you can distribute it and/or modify it
  * under the term of the GNU General Public License as published by
@@ -31,6 +31,7 @@ import net.ktnx.mobileledger.utils.Locker;
 import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.MLDB;
 import net.ktnx.mobileledger.utils.ObservableList;
+import net.ktnx.mobileledger.utils.SimpleDate;
 
 import java.lang.ref.WeakReference;
 import java.text.NumberFormat;
@@ -45,8 +46,14 @@ import static net.ktnx.mobileledger.utils.Logger.debug;
 public final class Data {
     public static final ObservableList<TransactionListItem> transactions =
             new ObservableList<>(new ArrayList<>());
-    public static final ObservableList<LedgerAccount> accounts = new ObservableList<>(new ArrayList<>());
-    public static final MutableLiveData<Boolean> backgroundTasksRunning = new MutableLiveData<>(false);
+    public static final MutableLiveData<SimpleDate> earliestTransactionDate =
+            new MutableLiveData<>(null);
+    public static final MutableLiveData<SimpleDate> latestTransactionDate =
+            new MutableLiveData<>(null);
+    public static final ObservableList<LedgerAccount> accounts =
+            new ObservableList<>(new ArrayList<>());
+    public static final MutableLiveData<Boolean> backgroundTasksRunning =
+            new MutableLiveData<>(false);
     public static final MutableLiveData<Date> lastUpdateDate = new MutableLiveData<>();
     public static final MutableLiveData<MobileLedgerProfile> profile = new InertMutableLiveData<>();
     public static final MutableLiveData<ArrayList<MobileLedgerProfile>> profiles =
@@ -58,6 +65,7 @@ public final class Data {
     public static final MutableLiveData<Locale> locale = new MutableLiveData<>(Locale.getDefault());
     private static final AtomicInteger backgroundTaskCount = new AtomicInteger(0);
     private static final Locker profilesLocker = new Locker();
+    public static MutableLiveData<Integer> foundTransactionItemIndex = new MutableLiveData<>(null);
     private static RetrieveTransactionsTask retrieveTransactionsTask;
     public static final MutableLiveData<Boolean> drawerOpen = new MutableLiveData<>(false);
     public static void backgroundTaskStarted() {
index 9b73d2ce9d1c9d477c77fe70f83bcdb0ee126aeb..5bc8456bb4b81b8939e3b088ad1c9470ad8db0ca 100644 (file)
@@ -20,6 +20,9 @@ package net.ktnx.mobileledger.model;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 
+import androidx.annotation.NonNull;
+
+import net.ktnx.mobileledger.App;
 import net.ktnx.mobileledger.utils.Digest;
 import net.ktnx.mobileledger.utils.Globals;
 import net.ktnx.mobileledger.utils.SimpleDate;
@@ -98,7 +101,11 @@ public class LedgerTransaction {
         accounts.add(item);
         dataHash = null;
     }
+    @NonNull
     public SimpleDate getDate() {
+        loadData(App.getDatabase());
+        if (date == null)
+            throw new IllegalStateException("Transaction has no date");
         return date;
     }
     public void setDate(SimpleDate date) {
index 925e05eb3fd95ef3ddd64efd83c3b654ead3c0b7..2de99c8f3b30f8880a250d0b628df52985004faa 100644 (file)
@@ -29,12 +29,11 @@ import net.ktnx.mobileledger.App;
 import net.ktnx.mobileledger.R;
 import net.ktnx.mobileledger.async.DbOpQueue;
 import net.ktnx.mobileledger.async.SendTransactionTask;
-import net.ktnx.mobileledger.utils.Globals;
-import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.MLDB;
 import net.ktnx.mobileledger.utils.Misc;
 
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
@@ -60,6 +59,8 @@ public final class MobileLedgerProfile {
     // N.B. when adding new fields, update the copy-constructor below
     private FutureDates futureDates = FutureDates.None;
     private SendTransactionTask.API apiVersion = SendTransactionTask.API.auto;
+    private Calendar firstTransactionDate;
+    private Calendar lastTransactionDate;
     public MobileLedgerProfile() {
         this.uuid = String.valueOf(UUID.randomUUID());
     }
@@ -525,7 +526,7 @@ public final class MobileLedgerProfile {
             db.execSQL("delete from transactions where profile=?", pUuid);
             db.execSQL("delete from transaction_accounts where profile=?", pUuid);
             db.setTransactionSuccessful();
-            Logger.debug("wipe", String.format(Locale.ENGLISH, "Profile %s wiped out", pUuid[0]));
+            debug("wipe", String.format(Locale.ENGLISH, "Profile %s wiped out", pUuid[0]));
         }
         finally {
             db.endTransaction();
@@ -567,6 +568,12 @@ public final class MobileLedgerProfile {
             return null;
         }
     }
+    public Calendar getFirstTransactionDate() {
+        return firstTransactionDate;
+    }
+    public Calendar getLastTransactionDate() {
+        return lastTransactionDate;
+    }
     public enum FutureDates {
         None(0), OneWeek(7), TwoWeeks(14), OneMonth(30), TwoMonths(60), ThreeMonths(90),
         SixMonths(180), OneYear(365), All(-1);
index ab8bb7ac791314db553a4c47b645fb6b6f4e43eb..084eaad8e8151d00af628dffcff82234fb684a2e 100644 (file)
@@ -41,8 +41,9 @@ public class TransactionListItem {
     public Type getType() {
         return type;
     }
+    @NonNull
     public SimpleDate getDate() {
-        return date;
+        return (date != null) ? date : transaction.getDate();
     }
     public boolean isMonthShown() {
         return monthShown;
index 80c69e59bfece97bc7fd313b888f012bf4100b16..5e0fe82a1c1de9d6e6def594b49be7140eae914b 100644 (file)
@@ -121,7 +121,7 @@ public class DatePickerFragment extends AppCompatDialogFragment
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        Dialog dpd = new Dialog(Objects.requireNonNull(getActivity()));
+        Dialog dpd = new Dialog(requireActivity());
         dpd.setContentView(R.layout.date_picker_view);
         dpd.setTitle(null);
         CalendarView cv = dpd.findViewById(R.id.calendarView);
index 3625ea40a64f3412adc99b7efb6573846e8d1de9..68e243a891d4662cdfc76d4e9ef5a0e12fdb4dc3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 Damyan Ivanov.
  * This file is part of MoLe.
  * MoLe is free software: you can distribute it and/or modify it
  * under the term of the GNU General Public License as published by
@@ -19,6 +19,7 @@ package net.ktnx.mobileledger.ui.transaction_list;
 
 import android.content.Context;
 import android.database.Cursor;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -37,21 +38,28 @@ import androidx.recyclerview.widget.RecyclerView;
 import com.google.android.material.snackbar.Snackbar;
 
 import net.ktnx.mobileledger.R;
+import net.ktnx.mobileledger.async.TransactionDateFinder;
 import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.ui.DatePickerFragment;
 import net.ktnx.mobileledger.ui.MobileLedgerListFragment;
 import net.ktnx.mobileledger.ui.activity.MainActivity;
 import net.ktnx.mobileledger.utils.Colors;
 import net.ktnx.mobileledger.utils.Globals;
+import net.ktnx.mobileledger.utils.Logger;
 import net.ktnx.mobileledger.utils.MLDB;
+import net.ktnx.mobileledger.utils.SimpleDate;
 
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Locale;
+
 import static android.content.Context.INPUT_METHOD_SERVICE;
 import static net.ktnx.mobileledger.utils.Logger.debug;
 
 // TODO: support transaction-level comment
 
-public class TransactionListFragment extends MobileLedgerListFragment {
+public class TransactionListFragment extends MobileLedgerListFragment
+        implements DatePickerFragment.DatePickedListener {
     private MenuItem menuTransactionListFilter;
     private View vAccountFilter;
     private AutoCompleteTextView accNameFilter;
@@ -153,6 +161,12 @@ public class TransactionListFragment extends MobileLedgerListFragment {
                      menuTransactionListFilter.setVisible(true);
                      Globals.hideSoftKeyboard(mActivity);
                  });
+
+        Data.foundTransactionItemIndex.observe(getViewLifecycleOwner(), pos -> {
+            Logger.debug("go-to-date", String.format(Locale.US, "Found pos %d", pos));
+            if (pos != null)
+                root.scrollToPosition(pos);
+        });
     }
     private void onAccountNameFilterChanged(String accName) {
         final String fieldText = accNameFilter.getText()
@@ -200,5 +214,22 @@ public class TransactionListFragment extends MobileLedgerListFragment {
 
             return true;
         });
+
+        menu.findItem(R.id.menu_go_to_date)
+            .setOnMenuItemClickListener(item -> {
+                DatePickerFragment picker = new DatePickerFragment();
+                picker.setOnDatePickedListener(this);
+                picker.setDateRange(Data.earliestTransactionDate.getValue(),
+                        Data.latestTransactionDate.getValue());
+                picker.show(requireActivity().getSupportFragmentManager(), null);
+                return true;
+            });
+    }
+    @Override
+    public void onDatePicked(int year, int month, int day) {
+        RecyclerView list = requireActivity().findViewById(R.id.transaction_root);
+        AsyncTask<SimpleDate, Void, Integer> finder = new TransactionDateFinder();
+
+        finder.execute(new SimpleDate(year, month + 1, day));
     }
 }
index e1ce8eea5430e287e122a7aecbf2be9f02a57c98..c6cc87a36a26c72ef6d2e451ad43271927041f50 100644 (file)
@@ -47,7 +47,7 @@ public final class Globals {
     public static String[] monthNames;
     public static String developerEmail = "dam+mole-crash@ktnx.net";
     private static Pattern reLedgerDate =
-            Pattern.compile("^(?:(\\d+)/)??(?:(\\d\\d?)/)?(\\d\\d?)$");
+            Pattern.compile("^(?:(?:(\\d+)/)??(\\d\\d?)/)?(\\d\\d?)$");
     public static void hideSoftKeyboard(Activity act) {
         // hide the keyboard
         View v = act.getCurrentFocus();
index ff6c0e55982397d653e26f62493c9fef12ed46fc..28ad751d0557531b94513cbe22bfe2d186c048c7 100644 (file)
@@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
 import java.util.Calendar;
 import java.util.Date;
 
-public class SimpleDate {
+public class SimpleDate implements Comparable<SimpleDate> {
     public int year;
     public int month;
     public int day;
@@ -56,14 +56,7 @@ public class SimpleDate {
         if (date == null)
             return false;
 
-        if (year != date.year)
-            return false;
-        if (month != date.month)
-            return false;
-        if (day != date.day)
-            return false;
-
-        return true;
+        return ((year == date.year) && (month == date.month) && (day == date.day));
     }
     public boolean earlierThan(@NonNull SimpleDate date) {
         if (year < date.year)
@@ -87,4 +80,15 @@ public class SimpleDate {
             return false;
         return (day > date.day);
     }
+    public int compareTo(SimpleDate date) {
+        int res = Integer.compare(year, date.year);
+        if (res != 0)
+            return res;
+
+        res = Integer.compare(month, date.month);
+        if (res != 0)
+            return res;
+
+        return Integer.compare(day, date.day);
+    }
 }
index 336d3ccbbd9c50bd72d6114104ca36c797e5473d..b864b8a028d80501e66e9a15c3ffad890c7be514 100644 (file)
   ~ Modified/adapted by Damyan Ivanov for MoLe
   -->
 
-<vector android:height="24dp" android:tint="#EEEEEE"
-    android:viewportHeight="24.0" android:viewportWidth="24.0"
-    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
-    <path android:fillColor="#FF000000" android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
+<vector android:height="24dp"
+    android:tint="?colorOnPrimary"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:width="24dp"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    >
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"
+        />
 </vector>
diff --git a/app/src/main/res/drawable/ic_baseline_calendar_today_24.xml b/app/src/main/res/drawable/ic_baseline_calendar_today_24.xml
new file mode 100644 (file)
index 0000000..18fcdbc
--- /dev/null
@@ -0,0 +1,31 @@
+<!--
+  ~ Copyright Google Inc.
+  ~
+  ~ Licensed under the Apache License, version 2.0 ("the License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the license at:
+  ~
+  ~ https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distribution under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  ~ Modified/adapted by Damyan Ivanov for MoLe
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:autoMirrored="true"
+    android:tint="?colorOnPrimary"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    >
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M20,3h-1L19,1h-2v2L7,3L7,1L5,1v2L4,3c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,5c0,-1.1 -0.9,-2 -2,-2zM20,21L4,21L4,8h16v13z"
+        />
+</vector>
index 8c1658f6cdd271cbfc00de4864be8c9611fea620..bc5194e28675400453c51c368648677380b3f379 100644 (file)
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright © 2019 Damyan Ivanov.
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2020 Damyan Ivanov.
   ~ This file is part of MoLe.
   ~ MoLe is free software: you can distribute it and/or modify it
   ~ under the term of the GNU General Public License as published by
   ~ along with MoLe. If not, see <https://www.gnu.org/licenses/>.
   -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <CalendarView
-        android:id="@+id/calendarView"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-</LinearLayout>
\ No newline at end of file
+<CalendarView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/calendarView"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    />
\ No newline at end of file
index 063e43df7a3c9c4d2d7a4efaf6ec7e35a0588f3a..8ebea83db8463d3afa5c30b345413fff8f03d0ba 100644 (file)
     xmlns:tools="http://schemas.android.com/tools"
     >
 
+    <item
+        android:id="@+id/menu_go_to_date"
+        android:icon="@drawable/ic_baseline_calendar_today_24"
+        android:title="@string/go_to_date_menu_title"
+        app:showAsAction="ifRoom"
+        />
     <item
         android:id="@+id/menu_transaction_list_filter"
         android:icon="@drawable/ic_filter_list_white_24dp"
diff --git a/app/src/test/java/net/ktnx/mobileledger/utils/SimpleDateTest.java b/app/src/test/java/net/ktnx/mobileledger/utils/SimpleDateTest.java
new file mode 100644 (file)
index 0000000..367ee3f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.utils;
+
+import org.junit.After;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class SimpleDateTest {
+
+    @After
+    public void tearDown() throws Exception {
+    }
+    @Test
+    public void compareTo() {
+        SimpleDate d1 = new SimpleDate(2020, 6, 1);
+        SimpleDate d2 = new SimpleDate(2019, 7, 6);
+
+        assertTrue(d1.compareTo(d2) > 0);
+        assertTrue(d2.compareTo(d1) < 0);
+        assertTrue(d1.compareTo(new SimpleDate(2020, 6, 2)) < 0);
+        assertTrue(d1.compareTo(new SimpleDate(2020, 5, 2)) > 0);
+        assertTrue(d1.compareTo(new SimpleDate(2019, 5, 2)) > 0);
+    }
+}
\ No newline at end of file