Как описать временные метки на основе текущей разницы во времени, например, в списке уведомлений

В моем предыдущем блоге я клонирую пользовательский интерфейс носителя уведомлений (версия для Android). В статье объяснялось, как я конвертирую снимок экрана в код Flutter.



Если вы читали статью выше, я выделил в конце шага 2 временные метки уведомлений. А теперь, это продолжение той статьи.

К концу этой статьи мы сможем описать отметку времени на основе текущей разницы во времени. Например, на обложке выше есть 2 уведомления. Первое уведомление было описано как 17 минут назад, а второе уведомление из Twitter — 29 минут назад. С помощью класса DateTime мы создадим новый метод расширения, чтобы мы могли описывать время без дополнительных пакетов.

Прежде всего, этот метод был вдохновлен примером выражения переключения на #GoogleIO2023. Для достоверности показываю скриншоты из видео.

Из примера на этом рисунке метод обрабатывает разницу во времени только для дней. Я возьму его и извлеку как метод обработчика дней.

  • Дней

если вы используете dart v3.x, вы можете использовать то же, что и в примере:

String dayHandler2(Duration diff) =>  switch(diff) {
  Duration(inDays: -1) => "Yesterday",
  Duration(inDays: 1) => "Tomorrow",
  Duration(inDays: 0) => "Today",
  Duration(inDays: int d, isNegative: true) => "${d.abs()} days ago",
  Duration(inDays: int d, isNegative: false) => "$d days from now",
};

но если вы все еще используете dart v2.x, которое является выражением переключения, еще не доступным, вы можете использовать этот оператор переключения.

String dayHandler(Duration day) {
  String result = "";
  switch (day) {
    case Duration(inDays: -1):
      result = "Yesterday";
    case Duration(inDays: 1):
      result = "Tomorrow";
    case Duration(inDays: 0):
      result = "Today";
    case Duration(inDays: int d, isNegative: true):
      result = "${d.abs()} days ago";
    case Duration(inDays: int d, isNegative: false):
      result = "$d days from now";
  }
  return result;
}
  • Часов

В этой части нам нужно обработать условие, когда разница во времени между 59 минутами и 24 часами.

Я делаю это максимально просто, передавая целочисленное значение разницы во времени. Итак, у меня есть метод, как показано ниже:

String hrsHandler(int hrs) {
  return hrs.isNegative ? "${hrs.abs()} hours ago" : "$hrs hours from now";
}

Когда целое число hrs отрицательное, это означает, что разница просрочена, мы возвращаем x hours ago. Но для положительных моментов это означает, что впереди несколько часов. Возвращаем x hours from now.

  • Минуты

В этом случае мы хотим обрабатывать, когда разница во времени составляет менее 60 минут. Метод будет таким:

String minsHandler(int min) {
  return min.isNegative ? "${min.abs()} minutes ago" : "$min minutes from now";
}

Он использует ту же логику, что и в hrsHanlder, проверяя отрицательные или положительные значения. Затем возвращает метку времени, описываемую ее значением.

Вы можете создать другой обработчик для более полного метода. Например, monthHandler или yearHandler . Но пока я расскажу только о днях, часах и минутах.

При реализации описанного выше метода окончательный результат метода расширения будет таким:

extension DescribeTimeDiff on DateTime {
  String getDifferences() {
    final now = DateTime.now();
    final diff = difference(DateTime(
        now.year, now.month, now.day, now.hour, now.minute, now.second));
    String a = diff.inHours.abs() > 23
        // ? dayHandler(diff) // if you use dart 2 
        ? dayHandler2(diff) // if you use dart 3
        : diff.inHours.abs() < 24 && diff.inMinutes.abs() > 59
            ? hrsHandler(diff.inHours)
            : minsHandler(diff.inMinutes);
    return a;
  }
}

Если вам интересно, почему я до сих пор использую if-else в этом методе, то это потому, что выражения переключения и операторы переключения требуют выражения постоянного значения. Я пробовал несколько простых способов, используя переключающие выражения. Но у меня нет идей. Не стесняйтесь оставлять комментарии, если у вас есть какие-либо идеи для этого.

Полный код вы можете увидеть здесь и попробовать самостоятельно на Dartpad:

https://dartpad.dev/?id=b213bd69e1d44e2f0263081f9954af6a

Хорошо, мы уже протестировали метод, и он работает хорошо. Теперь мы реализуем это в пользовательском интерфейсе.

вот старые данные, которые у меня есть:

List<NotifModel> notifData = [
  NotifModel(
      id: 1,
      userName: "Pmatatias",
      notifType: NotifType(id: 1, name: "responded to"),
      articleTitle:"The article title will be here",
      time: "59 minutes ago"),

и теперь мы используем форматированную строку для данных времени.

List<NotifModel> notifData = [
  NotifModel(
      id: 1,
      userName: "Pmatatias",
      notifType: NotifType(id: 1, name: "responded to"),
      articleTitle:"The article title will be here",
      time: "2023-05-30 16:23:32.000"),

как использовать?

Сначала разберите отформатированную строку даты в объект DateTime. А затем описать время методом расширения. И не забудьте указать import путь, если вы помещаете расширениеметод в отдельный файл.

import 'your path file where you put the time_difference method';

Text(DateTime.parse(data.time).getDifferences())

Теперь давайте посмотрим на окончательный результат клонирования пользовательского интерфейса среднего уведомления с описанной меткой времени.

Спасибо за конец. Это моя 6-я статья о методе расширения. Вы можете прочитать предыдущий метод расширения из предложения в конце этой статьи.

Кстати, я также собираю все методы extension в репозиторий GitHub. Вы можете получить его через репозиторий ниже. Не стесняйтесь вносить свой вклад, если у вас есть расширенный метод и вы хотите им поделиться.



Если вам понравилась эта статья, не забудьте похлопать 👏👏👏👏👏👏👏👏👏👏

И не стесняйтесь оставлять любые комментарии ниже. 😃

Приятного чтения!!!