Repository: jama5262/jiffy

Issue:
Support durations
**Is your feature request related to a problem? Please describe.**
Jiffy.from is awesome because it shows human readable relative dates. I'd like to use the same feature for Durations, without the prefix or suffix (no "in ..." or "... ago").

**Describe the solution you'd like**
So, I'd like something like `Jiffy(Duration(days: 366)).someNewMethod` to return something like "a year".

**Describe alternatives you've considered**
I tried to implement my own locale to remove the prefix and suffix, but it doesn't seem like I can do this easily.

**Additional context**
Add any other context or screenshots about the feature request here.



Discussion: Hey @atn832 , thanks for the contribution, this feature looks like it will be great to have. Maybe not necessarily have a new method but we can update the existing methods to have an optional param `withoutPrefixAndSuffix` by deafult to show the prefix and suffix of the relative time

```dart
// Update the relative time functions
String fromNow({bool withoutPrefixAndSuffix = false}) { // add the new param `withoutPrefixAndSuffix`
   ...
}

String from(var input, {bool withoutPrefixAndSuffix = false}) { // add the new param `withoutPrefixAndSuffix`
   ...
}

// and you can use it like so

Jiffy().fromNow() // a year ago
Jiffy().fromNow() // 20 mins ago
Jiffy().fromNow(withoutPrefixAndSuffix: true) // a year
Jiffy().fromNow(withoutPrefixAndSuffix: true) // 20 mins

// or assume in the case of future time

Jiffy().fromNow() // in a year
Jiffy().fromNow(withoutPrefixAndSuffix: true) // a year
```

What do you think?
If that is much less work for you, it's a good first step.

So if you implement it your way, if someone has a Duration they want to print out, they'd have to call something like:
```dart
Jiffy(DateTime.now().add(theDuration)).fromNow(withoutPrefixAndSuffix: true)
```
Is that right?

Then we could consider adding a utility function to make it easier to use:
```dart
Jiffy.printDuration(Duration d) {
  Jiffy(DateTime.now().add(d)).fromNow(withoutPrefixAndSuffix: true);
}
```

Fix patch:
diff --git a/doc/README.md b/doc/README.md
index 1316404d..ddf52dcc 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -396,6 +396,12 @@ Jiffy.parseFromDateTime(DateTime(2050, 10, 29)).fromNow(); // in 30 years
 Jiffy.now().startOf(Unit.hour).fromNow(); // 9 minutes ago
 ```
 
+You can also omit returning the prefix and suffix like `in` and `ago`.
+
+```dart
+Jiffy.parse('2007-01-29').fromNow(withPrefixAndSuffix: false); // 14 years
+```
+
 ### Time from X
 This method is used to get the relative time from a specific date time.
 ```dart
@@ -405,6 +411,15 @@ var jiffy2 = Jiffy.parse('2017-01-29');
 jiffy1.from(jiffy2); // a day ago
 ```
 
+You can also omit returning the prefix and suffix like `in` and `ago`.
+
+```dart
+var jiffy1 = Jiffy.parse('2007-01-28');
+var jiffy2 = Jiffy.parse('2017-01-29');
+
+jiffy1.from(jiffy2, withPrefixAndSuffix: false); // a day
+```
+
 ### Time to Now
 This works opposite to the `fromNow()` method. 
 This method is used to get the relative time to now.
@@ -416,6 +431,12 @@ Jiffy.parseFromDateTime(DateTime(2050, 10, 29)).toNow(); // 30 years ago
 Jiffy.now().startOf(Unit.hour).toNow(); // in 9 minutes
 ```
 
+You can also omit returning the prefix and suffix like `in` and `ago`.
+
+```dart
+Jiffy.parse('2007-01-29').toNow(withPrefixAndSuffix: false); // 14 years
+```
+
 ### Time to X
 This works opposite to the `from()` method. 
 This method is used to get the relative time to a specific date time.
@@ -426,6 +447,14 @@ var jiffy2 = Jiffy.parse('2017-01-29');
 jiffy1.to(jiffy2); // in a day
 ```
 
+You can also omit returning the prefix and suffix like `in` and `ago`.
+
+```dart
+var jiffy1 = Jiffy.parse('2007-01-28');
+var jiffy2 = Jiffy.parse('2017-01-29');
+
+jiffy1.to(jiffy2, withPrefixAndSuffix: false); // a day
+```
 ### Difference
 Used to get the difference between two Jiffy date times.
 ```dart
diff --git a/lib/src/display.dart b/lib/src/display.dart
index 55fc26d5..1fe40a78 100644
--- a/lib/src/display.dart
+++ b/lib/src/display.dart
@@ -34,8 +34,8 @@ class Display {
     }
   }
 
-  String fromAsRelativeDateTime(
-      DateTime firstDateTime, DateTime secondDateTime, Locale locale) {
+  String fromAsRelativeDateTime(DateTime firstDateTime, DateTime secondDateTime,
+      Locale locale, bool withPrefixAndSuffix) {
     final isFirstDateTimeSameOrAfterSecondDateTime = _query.isSameOrAfter(
         firstDateTime, secondDateTime, Unit.microsecond, locale.startOfWeek());
 
@@ -85,14 +85,19 @@ class Display {
       result = relativeDateTime.years(years.round());
     }
 
-    return [prefix, result, suffix]
-        .where((str) => str.isNotEmpty)
-        .join(relativeDateTime.wordSeparator());
+    if (withPrefixAndSuffix) {
+      return [prefix, result, suffix]
+          .where((str) => str.isNotEmpty)
+          .join(relativeDateTime.wordSeparator());
+    }
+
+    return result;
   }
 
-  String toAsRelativeDateTime(
-      DateTime firstDateTime, DateTime secondDateTime, Locale locale) {
-    return fromAsRelativeDateTime(secondDateTime, firstDateTime, locale);
+  String toAsRelativeDateTime(DateTime firstDateTime, DateTime secondDateTime,
+      Locale locale, bool withPrefixAndSuffix) {
+    return fromAsRelativeDateTime(
+        secondDateTime, firstDateTime, locale, withPrefixAndSuffix);
   }
 
   num diff(DateTime firstDateTime, DateTime secondDateTime, Unit unit,
diff --git a/lib/src/jiffy.dart b/lib/src/jiffy.dart
index 64fba49b..0aca7873 100644
--- a/lib/src/jiffy.dart
+++ b/lib/src/jiffy.dart
@@ -671,7 +671,8 @@ class Jiffy {
   String get jms => _defaultDisplay.jms(dateTime);
 
   /// Returns a string representation of current [Jiffy]'s instance relative
-  /// from [jiffy]'s date and time.
+  /// from [jiffy]'s date and time, with optional [withPrefixAndSuffix] flag
+  /// to include prefix and suffix like "in" or "ago".
   ///
   /// Example:
   ///
@@ -681,12 +682,27 @@ class Jiffy {
   /// print(jiffy1.from(jiffy2));
   /// // output: a month ago
   /// ```
-  String from(Jiffy jiffy) {
-    return _display.fromAsRelativeDateTime(dateTime, jiffy.dateTime, _locale);
+  ///
+  /// Example without returning prefix and suffix:
+  ///
+  /// ```dart
+  /// final jiffy1 = Jiffy.parseFromDateTime(DateTime(2023, 1, 1));
+  /// final jiffy2 = Jiffy.parseFromDateTime(DateTime(2023, 2, 1));
+  /// print(jiffy1.from(jiffy2, withPrefixAndSuffix: false));
+  /// // output: a month
+  /// ```
+  ///
+  /// If [withPrefixAndSuffix] is `true` (default), the output string will
+  /// include prefix and suffix words like "in" or "ago". Otherwise, only
+  /// the relative time difference string will be returned.
+  String from(Jiffy jiffy, {bool withPrefixAndSuffix = true}) {
+    return _display.fromAsRelativeDateTime(
+        dateTime, jiffy.dateTime, _locale, withPrefixAndSuffix);
   }
 
   /// Returns a string representation of current [Jiffy]'s instance relative
-  /// from current date and time.
+  /// from current date and time, with optional [withPrefixAndSuffix] flag
+  /// to include prefix and suffix like "in" or "ago".
   ///
   /// Example:
   ///
@@ -695,10 +711,24 @@ class Jiffy {
   /// print(jiffy.fromNow());
   /// // output: a month ago
   /// ```
-  String fromNow() => from(Jiffy.now());
+  ///
+  /// Example without returning prefix and suffix:
+  ///
+  /// ```dart
+  /// final jiffy = Jiffy.parseFromDateTime(DateTime(2023, 1, 1));
+  /// print(jiffy.fromNow(withPrefixAndSuffix: false));
+  /// // output: a month
+  /// ```
+  ///
+  /// If [withPrefixAndSuffix] is `true` (default), the output string will
+  /// include prefix and suffix words like "in" or "ago". Otherwise, only
+  /// the relative time difference string will be returned.
+  String fromNow({bool withPrefixAndSuffix = true}) =>
+      from(Jiffy.now(), withPrefixAndSuffix: withPrefixAndSuffix);
 
   /// Returns a string representation of current [Jiffy]'s instance relative
-  /// to [jiffy]'s date and time.
+  /// to [jiffy]'s date and time, with optional [withPrefixAndSuffix] flag
+  /// to include prefix and suffix like "in" or "ago".
   ///
   /// Example:
   ///
@@ -708,12 +738,27 @@ class Jiffy {
   /// print(jiffy1.to(jiffy2));
   /// // output: in a month
   /// ```
-  String to(Jiffy jiffy) {
-    return _display.toAsRelativeDateTime(dateTime, jiffy.dateTime, _locale);
+  ///
+  /// Example without returning prefix and suffix:
+  ///
+  /// ```dart
+  /// final jiffy1 = Jiffy.parseFromDateTime(DateTime(2023, 1, 1));
+  /// final jiffy2 = Jiffy.parseFromDateTime(DateTime(2023, 2, 1));
+  /// print(jiffy1.to(jiffy2, withPrefixAndSuffix: false));
+  /// // output: a month
+  /// ```
+  ///
+  /// If [withPrefixAndSuffix] is `true` (default), the output string will
+  /// include prefix and suffix words like "in" or "ago". Otherwise, only
+  /// the relative time difference string will be returned.
+  String to(Jiffy jiffy, {bool withPrefixAndSuffix = true}) {
+    return _display.toAsRelativeDateTime(
+        dateTime, jiffy.dateTime, _locale, withPrefixAndSuffix);
   }
 
   /// Returns a string representation of current [Jiffy]'s instance relative
-  /// to current date and time.
+  /// to current date and time, with optional [withPrefixAndSuffix] flag
+  /// to include prefix and suffix like "in" or "ago".
   ///
   /// Example:
   ///
@@ -722,7 +767,20 @@ class Jiffy {
   /// print(jiffy.toNow());
   /// // output: in a month
   /// ```
-  String toNow() => to(Jiffy.now());
+  ///
+  /// Example without returning prefix and suffix:
+  ///
+  /// ```dart
+  /// final jiffy = Jiffy.parseFromDateTime(DateTime(2023, 1, 1));
+  /// print(jiffy.toNow(withPrefixAndSuffix: false));
+  /// // output: a month
+  /// ```
+  ///
+  /// If [withPrefixAndSuffix] is `true` (default), the output string will
+  /// include prefix and suffix words like "in" or "ago". Otherwise, only
+  /// the relative time difference string will be returned.
+  String toNow({bool withPrefixAndSuffix = true}) =>
+      to(Jiffy.now(), withPrefixAndSuffix: withPrefixAndSuffix);
 
   /// Returns the difference between this [Jiffy] instance and the given
   /// [jiffy] instance as a numeric value.


Test patch:
diff --git a/test/src/display_test.dart b/test/src/display_test.dart
index 1a053d43..65f38767 100644
--- a/test/src/display_test.dart
+++ b/test/src/display_test.dart
@@ -110,24 +110,62 @@ void main() {
         final locale = EnLocale();
 
         final actualFromAsRelativeDateTime = underTest.fromAsRelativeDateTime(
-            testData['firstDateTime'], testData['secondDateTime'], locale);
+            testData['firstDateTime'],
+            testData['secondDateTime'],
+            locale,
+            true);
 
         expect(actualFromAsRelativeDateTime,
             testData['expectedFromAsRelativeDateTime']);
       });
     }
 
+    test(
+        'Should successfully get from as relative datetime without prefix and suffix',
+        () {
+      final locale = EnLocale();
+      final firstDateTime = DateTime(1997, 10, 23, 12, 11, 22, 123, 456);
+      final secondDateTime = DateTime(1998, 10, 23, 12, 11, 22, 123, 457);
+      final withPrefixAndSuffix = false;
+
+      final expectedFromAsRelativeDateTime = 'a year';
+
+      final actualFromAsRelativeDateTime = underTest.fromAsRelativeDateTime(
+          firstDateTime, secondDateTime, locale, withPrefixAndSuffix);
+
+      expect(actualFromAsRelativeDateTime, expectedFromAsRelativeDateTime);
+    });
+
     for (var testData in toAsRelativeDateTimeTestData()) {
       test('Should successfully get to as relative datetime', () {
         final locale = EnLocale();
 
         final actualToAsRelativeDateTime = underTest.toAsRelativeDateTime(
-            testData['firstDateTime'], testData['secondDateTime'], locale);
+            testData['firstDateTime'],
+            testData['secondDateTime'],
+            locale,
+            true);
 
         expect(actualToAsRelativeDateTime,
             testData['expectedToAsRelativeDateTime']);
       });
     }
+
+    test(
+        'Should successfully get to as relative datetime without prefix and suffix',
+        () {
+      final locale = EnLocale();
+      final firstDateTime = DateTime(1997, 10, 23, 12, 11, 22, 123, 456);
+      final secondDateTime = DateTime(1998, 10, 23, 12, 11, 22, 123, 457);
+      final withPrefixAndSuffix = false;
+
+      final expectedFromAsRelativeDateTime = 'a year';
+
+      final actualFromAsRelativeDateTime = underTest.toAsRelativeDateTime(
+          firstDateTime, secondDateTime, locale, withPrefixAndSuffix);
+
+      expect(actualFromAsRelativeDateTime, expectedFromAsRelativeDateTime);
+    });
   });
 
   group('Test diff between two datetime', () {
diff --git a/test/src/jiffy_test.dart b/test/src/jiffy_test.dart
index e82c7ad1..223008bc 100644
--- a/test/src/jiffy_test.dart
+++ b/test/src/jiffy_test.dart
@@ -763,6 +763,23 @@ void main() {
         expect(actualRelativeDateTime, expectedRelativeDateTime);
       });
 
+      test(
+          'Should successfully get relative date time from without prefix and suffix',
+          () {
+        // Setup
+        final underTest = Jiffy.parseFromList([1997]);
+        final jiffyFrom = Jiffy.parseFromList([2022]);
+
+        final expectedRelativeDateTime = '25 years';
+
+        // Execute
+        final actualRelativeDateTime =
+            underTest.from(jiffyFrom, withPrefixAndSuffix: false);
+
+        // Verify
+        expect(actualRelativeDateTime, expectedRelativeDateTime);
+      });
+
       test('Should successfully get relative date time fromNow', () {
         // Setup
         final underTest = Jiffy.now().subtract(years: 25);
@@ -776,6 +793,22 @@ void main() {
         expect(actualRelativeDateTime, expectedRelativeDateTime);
       });
 
+      test(
+          'Should successfully get relative date time fromNow without prefix and suffix',
+          () {
+        // Setup
+        final underTest = Jiffy.now().subtract(years: 25);
+
+        final expectedRelativeDateTime = '25 years';
+
+        // Execute
+        final actualRelativeDateTime =
+            underTest.fromNow(withPrefixAndSuffix: false);
+
+        // Verify
+        expect(actualRelativeDateTime, expectedRelativeDateTime);
+      });
+
       test('Should successfully get relative date time to', () {
         // Setup
         final underTest = Jiffy.parseFromList([1997]);
@@ -790,6 +823,23 @@ void main() {
         expect(actualRelativeDateTime, expectedRelativeDateTime);
       });
 
+      test(
+          'Should successfully get relative date time to without prefix and suffix',
+          () {
+        // Setup
+        final underTest = Jiffy.parseFromList([1997]);
+        final jiffyTo = Jiffy.parseFromList([2022]);
+
+        final expectedRelativeDateTime = '25 years';
+
+        // Execute
+        final actualRelativeDateTime =
+            underTest.to(jiffyTo, withPrefixAndSuffix: false);
+
+        // Verify
+        expect(actualRelativeDateTime, expectedRelativeDateTime);
+      });
+
       test('Should successfully get relative date time toNow', () {
         // Setup
         final underTest = Jiffy.now().subtract(years: 25);
@@ -802,6 +852,22 @@ void main() {
         // Verify
         expect(actualRelativeDateTime, expectedRelativeDateTime);
       });
+
+      test(
+          'Should successfully get relative date time toNow without prefix and suffix',
+          () {
+        // Setup
+        final underTest = Jiffy.now().subtract(years: 25);
+
+        final expectedRelativeDateTime = '25 years';
+
+        // Execute
+        final actualRelativeDateTime =
+            underTest.toNow(withPrefixAndSuffix: false);
+
+        // Verify
+        expect(actualRelativeDateTime, expectedRelativeDateTime);
+      });
     });
 
     group('Test displaying diff', () {
diff --git a/test/src/locale/locales/locales_test.dart b/test/src/locale/locales/locales_test.dart
index e97ffbe2..439d2661 100644
--- a/test/src/locale/locales/locales_test.dart
+++ b/test/src/locale/locales/locales_test.dart
@@ -61,7 +61,8 @@ void main() {
         final actualRelativeDateTime = display.toAsRelativeDateTime(
             testData['firstDateTime'],
             testData['secondDateTime'],
-            testData['locale']);
+            testData['locale'],
+            true);
 
         // Verify
         expect(actualRelativeDateTime, testData['expectedRelativeDateTime']);