【问题标题】:Displaying time ago like Twitter像 Twitter 一样显示时间前
【发布时间】:2017-01-06 11:06:49
【问题描述】:

我使用DateUtils.getRelativeTimeSpanString() 来显示发布帖子的时间。

它返回的字符串是这样的:1 分钟前,但我希望是 1 m1 h 等等on (缩短且无前)。

我可以将“小时”替换为“h”或“分钟”替换为“m”,但如果语言与英语不同,它将无法正常工作。这就是Twitter 现在正在使用的东西。 英文/西里尔文通过 Twitter 显示的方式。

更新:我会接受@Bradley Wilson 的回答,尽管我会在这里添加更清洁的解决方案(再次使用 JodaTime 包)。此外,其余答案也可以针对相同的结果进行修改,因此它们值得投票。谢谢大家:

    DateTime postMaded = new DateTime(your previous date);
    DateTime nowUpdate = new DateTime();

    Period period = new Period(postMaded, nowUpdate);

    PeriodFormatter formatter;

    Locale current = ConverterMethods.getCurrentLocale();

    if (current.getLanguage().contentEquals(any Cyrillic language )) {

        if (period.getYears() != 0) {
            formatter = new PeriodFormatterBuilder().appendYears().appendSuffix(" г.").printZeroNever().toFormatter();
        } else if (period.getMonths() != 0) {
            formatter = new PeriodFormatterBuilder().appendMonths().appendSuffix(" м").printZeroNever().toFormatter();
        } else if (period.getWeeks() != 0) {
            formatter = new PeriodFormatterBuilder().appendWeeks().appendSuffix(" седм.").printZeroNever().toFormatter();
        } else if (period.getDays() != 0) {
            formatter = new PeriodFormatterBuilder().appendDays().appendSuffix(" д").printZeroNever().toFormatter();
        } else if (period.getHours() != 0) {
            formatter = new PeriodFormatterBuilder().appendHours().appendSuffix(" ч").printZeroNever().toFormatter();
        } else if (period.getMinutes() != 0) {
            formatter = new PeriodFormatterBuilder().appendMinutes().appendSuffix(" мин").printZeroNever().toFormatter();
        } else {
            formatter = new PeriodFormatterBuilder().appendSeconds().appendSuffix(" с").printZeroNever().toFormatter();
        }

    } else {

        if (period.getYears() != 0) {
            formatter = new PeriodFormatterBuilder().appendYears().appendSuffix(" y").printZeroNever().toFormatter();
        } else if (period.getMonths() != 0) {
            formatter = new PeriodFormatterBuilder().appendMonths().appendSuffix(" mon").printZeroNever().toFormatter();
        } else if (period.getWeeks() != 0) {
            formatter = new PeriodFormatterBuilder().appendWeeks().appendSuffix(" w").printZeroNever().toFormatter();
        } else if (period.getDays() != 0) {
            formatter = new PeriodFormatterBuilder().appendDays().appendSuffix(" d").printZeroNever().toFormatter();
        } else if (period.getHours() != 0) {
            formatter = new PeriodFormatterBuilder().appendHours().appendSuffix(" h").printZeroNever().toFormatter();
        } else if (period.getMinutes() != 0) {
            formatter = new PeriodFormatterBuilder().appendMinutes().appendSuffix(" m").printZeroNever().toFormatter();
        } else {
            formatter = new PeriodFormatterBuilder().appendSeconds().appendSuffix(" s").printZeroNever().toFormatter();
        }
    }

【问题讨论】:

  • Joda-Time (github.com/dlew/joda-time-android) 有一些不错的选择来做这样的事情。
  • 如果您指定包含PeriodPeriodFormatterPeriodFormatterBuilder 类的包会很有帮助
  • 我添加了它。感谢您指出。

标签: java android time java-time


【解决方案1】:

看看PrettyTime 库。

使用起来非常简单:

import org.ocpsoft.prettytime.PrettyTime

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
// prints "moments ago"

你也可以为国际化消息传递一个语言环境:

PrettyTime p = new PrettyTime(new Locale("fr"));
System.out.println(p.format(new Date()));
// prints "à l'instant"

如 cmets 中所述,Android 将此功能内置于 android.text.format.DateUtils 类中。

【讨论】:

  • 正如我所说我正在使用 DateUtils.getRelativeTimeSpanString() 它工作正常。但我想自定义每种语言的输出。查看图片
  • 第二个选项首先你试试这个库PrettyTime
  • 一个问题:我没有看到任何实现缩写样式的方法,请参见resource 的示例。 OP 似乎强烈希望可配置文本宽度,另见我的回答。
  • @ionicorn 对您有帮助吗?
【解决方案2】:

你可以使用这个功能来做到这一点

  public static String getTimeAgo(long time) {
     if (time < 1000000000000L) {
     // if timestamp given in seconds, convert to millis
     time *= 1000;
  }

  long now = System.currentTimeMillis();
  if (time > now || time <= 0) {
     return null;
  }

  // TODO: localize
  final long diff = now - time;
  if (diff < MINUTE_MILLIS) {
     return "just now";
  } else if (diff < 2 * MINUTE_MILLIS) {
     return "a minute ago";
  } else if (diff < 50 * MINUTE_MILLIS) {
     return diff / MINUTE_MILLIS + " min ago";
  } else if (diff < 90 * MINUTE_MILLIS) {
     return "an hour ago";
  } else if (diff < 24 * HOUR_MILLIS) {
     return diff / HOUR_MILLIS + " hours ago";
  } else if (diff < 48 * HOUR_MILLIS) {
     return "yesterday";
  } else {
     return diff / DAY_MILLIS + " days ago";
  }
 }

【讨论】:

  • 不,我不能,因为如果语言不是英语,它不会在您的任何情况下输入。例如,在西里尔文中,分钟/分钟是“минута/мин”
  • 您可以使用字符串资源进行本地化@ionicorn
【解决方案3】:

您可以使用JodaTime 来实现:

将依赖项添加到您的应用级别 Build.Gradle 文件中,如下所示:

compile 'net.danlew:android.joda:2.9.4.1'

然后你就可以简单地实现这个功能了。

private String time = "Just Now";

private String how_long_ago(String created_at) {
        DateTime sinceGraduation = new DateTime(created_at, GregorianChronology.getInstance());
        DateTime currentDate = new DateTime(); //current date

        Months diffInMonths = Months.monthsBetween(sinceGraduation, currentDate);
        Days diffInDays = Days.daysBetween(sinceGraduation, currentDate);
        Hours diffInHours = Hours.hoursBetween(sinceGraduation, currentDate);
        Minutes diffInMinutes = Minutes.minutesBetween(sinceGraduation, currentDate);
        Seconds seconds = Seconds.secondsBetween(sinceGraduation, currentDate);

        Log.d("since grad", "before if " + sinceGraduation);
        if (diffInDays.isGreaterThan(Days.days(31))) {
            time = diffInMonths.getMonths() + " months ago";
            if (diffInMonths.getMonths() == 1) {
                time = diffInMonths.getMonths() + " month ago";
            } else {
                time = diffInMonths.getMonths() + " months ago";
            }
            return time;
        } else if (diffInHours.isGreaterThan(Hours.hours(24))) {
            if (diffInDays.getDays() == 1) {
                time = diffInDays.getDays() + " day ago";
            } else {
                time = diffInDays.getDays() + " days ago";
            }
            return time;
        } else if (diffInMinutes.isGreaterThan(Minutes.minutes(60))) {
            if (diffInHours.getHours() == 1) {
                time = diffInHours.getHours() + " hour ago";
            } else {
                time = diffInHours.getHours() + " hours ago";
            }
            return time;
        } else if (seconds.isGreaterThan(Seconds.seconds(60))) {
            if (diffInMinutes.getMinutes() == 1) {
                time = diffInMinutes.getMinutes() + " minute ago";
            } else {
                time = diffInMinutes.getMinutes() + " minutes ago";
            }
            return time;
        } else if (seconds.isLessThan(Seconds.seconds(60))) {
            return time;
        }
        Log.d("since grad", "" + sinceGraduation);
        return time;
    }

只需将String 的输出更改为time 即可达到所需的“1m”

注意:您可以使用本地化来更改您的资源中的字符串。

查看Android Localization Tutorial了解更多详情。

【讨论】:

    【解决方案4】:

    使用我的库 Time4A 会像您在问题中指定的那样工作:

    打印相对时间(使用 ago-word)

        PlainTimestamp now = PlainTimestamp.nowInSystemTime();
        PlainTimestamp earlier = now.minus(1, ClockUnit.MINUTES);
        Moment past = earlier.inStdTimezone();
        Locale russian = new Locale("ru");
    
        PrettyTime.of(Locale.ENGLISH).printRelativeInStdTimezone(past);
        // output: 1 minute ago
    
        PrettyTime.of(Locale.ENGLISH)
           .withShortStyle().printRelativeInStdTimezone(past);
        // output: 1 min. ago
    
        PrettyTime.of(russian).printRelativeInStdTimezone(past);
        // output: 1 минуту назад
    
        PrettyTime.of(russian).withShortStyle().printRelativeInStdTimezone(past);
        // output: 1 мин. назад
    

    打印没有前字的平坦时间

        IsoUnit days = CalendarUnit.DAYS;
        IsoUnit hours = ClockUnit.HOURS;
        IsoUnit minutes = ClockUnit.MINUTES;
        net.time4j.Duration<IsoUnit> d =
            Duration.in(Timezone.ofSystem(), days, hours, minutes)
                .between(earlier, now);
    
        PrettyTime.of(Locale.ENGLISH).print(d, TextWidth.WIDE);
        // output: 1 minute
    
        PrettyTime.of(Locale.ENGLISH).print(d, TextWidth.ABBREVIATED);
        // output: 1 min
    
        PrettyTime.of(Locale.ENGLISH).print(d, TextWidth.NARROW);
        // output: 1m
    
        PrettyTime.of(russian).print(d, TextWidth.WIDE);
        // output: 1 минута
    
        PrettyTime.of(russian).print(d, TextWidth.ABBREVIATED);
        // output: 1 мин
    
        PrettyTime.of(russian).print(d, TextWidth.NARROW);
        // output: 1 мин
    

    最新的库版本使用 CLDR-repository v30.0.2 的数据(来自 Unicode-consortium,实际上有 80 种语言)。如有必要,您可能希望通过定义自己的资产与 Time4A 一起分发来更改文本资源(然后覆盖默认资产)。

    【讨论】:

      猜你喜欢
      • 2012-06-16
      • 1970-01-01
      • 2020-05-15
      • 2012-08-18
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 2015-03-03
      • 1970-01-01
      相关资源
      最近更新 更多