0

我目前有这个代码:

public static String getTimeAgo(OffsetDateTime dateArg) {
    Instant instantNow = Instant.now();
    Instant instantThen = dateArg.toInstant();
    Duration comparedDuration = Duration.between(instantThen, instantNow);

    LocalDate localDate = dateArg.toLocalDate();
    LocalDate localDateToday = LocalDate.now(ZoneId.systemDefault());
    Period comparedPeriod = Period.between(localDate, localDateToday);

    ZonedDateTime zdt1 = ZonedDateTime.ofInstant(instantThen, ZoneId.systemDefault());
    ZonedDateTime zdt2 = ZonedDateTime.ofInstant(instantNow, ZoneId.systemDefault());
    Calendar calendarFetched = GregorianCalendar.from(zdt1);
    Calendar calendarNow = GregorianCalendar.from(zdt2);

    Instant d1i = Instant.ofEpochMilli(calendarFetched.getTimeInMillis());
    Instant d2i = Instant.ofEpochMilli(calendarNow.getTimeInMillis());

    LocalDateTime startDateWeek = LocalDateTime.ofInstant(d1i, ZoneId.systemDefault());
    LocalDateTime endDateWeek = LocalDateTime.ofInstant(d2i, ZoneId.systemDefault());

    long weeksCalc = ChronoUnit.WEEKS.between(startDateWeek, endDateWeek);


    String s = "";
    if(comparedPeriod.getYears() > 0) {
        s += comparedPeriod.getYears() + " year" + ((comparedPeriod.getYears() == 1) ? " " : "s ");
    }

    if(weeksCalc > 4){
        s += comparedPeriod.getMonths() + " month" + ((comparedPeriod.getMonths() == 1) ? " " : "s ");

    }
    else{
        s += weeksCalc + " weeks ";

    }

    if (comparedPeriod.getDays() > 0){
        s += comparedPeriod.getDays() + " day" + ((comparedPeriod.getDays() == 1) ? " " : "s ");
    }

    if (comparedDuration.toHoursPart() > 0) {
        s += comparedDuration.toHoursPart() + " hour" + ((comparedDuration.toHoursPart() == 1) ? " " : "s ");
    }
    else{
        if(comparedDuration.toMinutesPart() > 0){
            s += comparedDuration.toMinutesPart() + " minute" + ((comparedDuration.toMinutesPart() == 1) ? " " : "s ");
        }

        else s += comparedDuration.toSecondsPart() + " seconds "; // lol lets just end it here...
    }

    return s + "ago";
}

目标是根据给定的OffsetDateTime参数显示“时间前”。这是为了显示年、月、周、日、小时、分钟,一直到秒,如果所述时间单位不是在0. 但是我在计算月份时遇到了麻烦,因为结果总是返回为0,同时有一个“s”表示它不是真的0

例如,运行System.out.println(Utils.getTimeAgo(OffsetDateTime.parse("2020-12-13T15:54:43.971273200-05:00")))显示1 year 0 months 1 hour ago作为它的输出......

4

1 回答 1

1

如果您仔细考虑一下,您会发现将时间跨度表示为年-月-日-小时-分钟-秒的组合很少有意义。

这就是为什么java.time将秤分成两个单独的类:

  • Period年月日
  • Duration时分秒

org.threeten.extra.PeriodDuration

如果你坚持要把这两个尺度结合起来,我建议在你的项目中加入ThreeTen-Extra库。这提供了PeriodDuration类。

OffsetDateTime odtThen = … ;
OffsetDateTime odtNow = OffsetDateTime.now( odtThen.getOffset() ) ;
PeriodDuration pd = PeriodDuration.between( odtThen, odtNow ) ;

询问以获得每个部分。一种方法是循环从返回的列表PeriodDuration#getUnits


正如评论,停止使用Calendar类。除了Date& SimpleDateFormat,这些糟糕的日期时间类完全被JSR 310 中定义的java.time类所取代。

于 2021-12-13T22:37:57.937 回答