Android 格式化截止日期的剩余时间

Android 格式化截止日期的剩余时间,android,date-format,Android,Date Format,我有一个未来的日期,必须格式化剩余的时间,直到今天这样 4天 1个月4天 1年1个月 我看过DateUtils文档,但没有看到这种确切的格式 我也可以使用像threetenabp这样的外部库 是否有一个可以同时处理时间计算和字符串本地化的库?使用threeten的LocalDate您可以获得从一个日期到另一个日期的剩余年、月和日。有了这些值,您可以对其进行0检查,并仅显示大于0的值。 简单的例子: val futureDate = LocalDate.of(2020,2,20)

我有一个未来的日期,必须格式化剩余的时间,直到今天这样

4天

1个月4天

1年1个月

我看过DateUtils文档,但没有看到这种确切的格式

我也可以使用像threetenabp这样的外部库


是否有一个可以同时处理时间计算和字符串本地化的库?

使用threeten的LocalDate您可以获得从一个日期到另一个日期的剩余年、月和日。有了这些值,您可以对其进行0检查,并仅显示大于0的值。 简单的例子:

    val futureDate = LocalDate.of(2020,2,20)
    val todayDate = LocalDate.now()
    val remainingYears = futureDate.year - todayDate.year //output 0
    val remainingMonth = futureDate.monthValue - todayDate.monthValue //output 0
    val remainingDays = futureDate.dayOfMonth - todayDate.dayOfMonth // output 16

我希望这就是你想要的,干杯

我不久前写了这个博客,它展示了如何做与你要求的相反的事情:-)也就是说,给定一个时间,说那是多久以前的事了。 Android在过去也多次提供此解决方案:。 所以你需要这些的反面

倒过来应该不难。而不是利用现在的时间,否定过去的时间差异。现在使用时间,将来添加时间

与之相反的是:

主要区别在于你希望现在和将来的日期有所不同,比如:

private fun getMillisFromNow(futureTime: Date): Long {
    val futureTimeMillis = futureTime.time
    val nowMillis = System.currentTimeMillis()
    return futureTimeMillis - nowMillis
}
然后格式化它。大概是这样的:

 fun format(timestamp: Date): String {
    val millisFromNow = getMillisFromNow(timestamp)

    val minutesFromNow = TimeUnit.MILLISECONDS.toMinutes(millisFromNow)
    if (minutesFromNow < 1) {
        return "about now"
    }
    val hoursFromNow = TimeUnit.MILLISECONDS.toHours(millisFromNow)
    if (hoursFromNow < 1) {
        return formatMinutes(minutesFromNow)
    }
    val daysFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow)
    if (daysFromNow < 1) {
        return formatHours(hoursFromNow)
    }
    val weeksFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow) / 7
    if (weeksFromNow < 1) {
        return formatDays(daysFromNow)
    }
    val monthsFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow) / 30
    if (monthsFromNow < 1) {
        return formatWeeks(weeksFromNow)
    }
    val yearsFromNow = TimeUnit.MILLISECONDS.toDays(millisFromNow) / 365
    return if (yearsFromNow < 1) {
        formatMonths(monthsFromNow)
    } else formatYears(yearsFromNow)
}

 private fun getMillisFromNow(futureTime: Date): Long {
    val futureTimeMillis = futureTime.time
    val nowMillis = System.currentTimeMillis()
    return futureTimeMillis - nowMillis
}

private fun formatMinutes(minutes: Long): String {
    return format(minutes, " minute to go", " minutes to go")
}

private fun formatHours(hours: Long): String {
    return format(hours, " hour to go", " hours to go")
}

private fun formatDays(days: Long): String {
    return format(days, " day to go", " days to go")
}

private fun formatWeeks(weeks: Long): String {
    return format(weeks, " week to go", " weeks to go")
}

private fun formatMonths(months: Long): String {
    return format(months, " month to go", " months to go")
}

private fun formatYears(years: Long): String {
    return format(years, " year to go", " years to go")
}

private fun format(hand: Long, singular: String, plural: String): String {
    return if (hand == 1L) {
        hand.toString() + singular
    } else {
        hand.toString() + plural
    }
}

对于本地化,您可以将其转换为使用
Strings.xml

使用
LocalDate
是一个很好的开始。你还没到那里。当我在你的代码中输入
LocalDate.of(2021,1,20)
时,我会用1年,-1个月,16天。我本来希望11个月16天,这不是我的主场,但我认为《乔达时代》可以做到这一点。JoDaTime正准备退休,所以我可能仍然会考虑一些你提到的地方。我应该把你和正确的方向联系起来——只对日期进行一些调整。我已经用了类似的方法来解决这个问题,所以我把它标记为答案。谢谢
@Test
fun test() {
    val twoDaysInMillisInstant = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(50))
    val result = format(Date.from(twoDaysInMillisInstant))

    assertEquals("2 days to go", result)
}