Skip to content

Commit f2755e8

Browse files
feat: conditional, relative/absolute date/time formatter
Signed-off-by: Andy Scherzinger <[email protected]>
1 parent 652e447 commit f2755e8

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Nextcloud Android Common Library
3+
*
4+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: MIT
6+
*/
7+
package com.nextcloud.android.common.core.utils
8+
9+
import android.content.Context
10+
import android.text.format.DateFormat
11+
import com.nextcloud.android.common.core.R
12+
import java.text.SimpleDateFormat
13+
import java.util.Calendar
14+
15+
/**
16+
* Helper implementation for date formatting.
17+
*/
18+
class DateFormatter(
19+
private val context: Context
20+
) {
21+
private val sdfDays: SimpleDateFormat
22+
private val sdfMonths: SimpleDateFormat
23+
private val sdfYears: SimpleDateFormat
24+
25+
/**
26+
* constructor.
27+
*
28+
* @param context Context needed to load locale-specific date/time-patterns and translation strings.
29+
*/
30+
init {
31+
val locale = this.context.resources.configuration.locale
32+
this.sdfDays = SimpleDateFormat(DateFormat.getBestDateTimePattern(locale, "EEE"), locale)
33+
this.sdfMonths =
34+
SimpleDateFormat(DateFormat.getBestDateTimePattern(locale, "MMM d"), locale)
35+
this.sdfYears =
36+
SimpleDateFormat(DateFormat.getBestDateTimePattern(locale, "MMM d, yyyy"), locale)
37+
}
38+
39+
/**
40+
* Returns a conditionally relative date formated string.
41+
* For anything less than 1h hours a relative time in minutes will be returned,
42+
* for anything less than 24h hours a relative time in hours will be returned,
43+
* for anything less than 6 days the day of the week in short form,
44+
* for anything up to 364 days a day and moth string will be returned,
45+
* for anything more than 364 days from now a complete date will be returned.
46+
*
47+
* @param calendar to be formatted calendar
48+
* @return formatted date strings
49+
*/
50+
fun getConditionallyRelativeFormattedTimeSpan(calendar: Calendar): String {
51+
var timeSpan = ""
52+
val span = System.currentTimeMillis() - calendar.getTimeInMillis()
53+
if (span < ONE_MINUTE_IN_MILLIS) {
54+
// less than 1m
55+
timeSpan = context.getString(R.string.date_formatting_now)
56+
} else if (span < ONE_HOUR_IN_MILLIS) {
57+
// less than 1h
58+
timeSpan =
59+
context.getString(
60+
R.string.date_formatting_relative_minutes,
61+
span / ONE_MINUTE_IN_MILLIS
62+
)
63+
} else if (span < ONE_DAY_IN_MILLIS) {
64+
// less than 24h
65+
val hours: Int = span.toInt() / ONE_HOUR_IN_MILLIS
66+
timeSpan =
67+
context
68+
.resources
69+
.getQuantityString(R.plurals.date_formatting_relative_hours, hours, hours)
70+
} else if (span <= SIX_DAYS_IN_MILLIS) {
71+
// less than 6 days
72+
timeSpan = sdfDays.format(calendar.getTime())
73+
} else if (span <= YEAR_IN_MILLIS) {
74+
// up to 364 days
75+
timeSpan = sdfMonths.format(calendar.getTime())
76+
} else {
77+
// more than 364 days
78+
timeSpan = sdfYears.format(calendar.getTime())
79+
}
80+
return timeSpan
81+
}
82+
83+
companion object {
84+
private const val ONE_MINUTE_IN_MILLIS = 60000
85+
private const val ONE_HOUR_IN_MILLIS: Int = ONE_MINUTE_IN_MILLIS * 60
86+
private const val ONE_DAY_IN_MILLIS: Int = ONE_HOUR_IN_MILLIS * 24
87+
private const val SIX_DAYS_IN_MILLIS: Int = ONE_DAY_IN_MILLIS * 6
88+
private const val YEAR_IN_MILLIS: Long = ONE_DAY_IN_MILLIS * 364L
89+
}
90+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
~ Nextcloud Android Common Library
4+
~
5+
~ SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
6+
~ SPDX-License-Identifier: MIT
7+
-->
8+
<resources>
9+
<!-- relative time less than 1 minute using the term: Now -->
10+
<string name="date_formatting_now">Now</string>
11+
<!-- relative time in minutes, less than 1 hour, i.e. 1m, 5m, 59m -->
12+
<string name="date_formatting_relative_minutes">%dm</string>
13+
<!-- relative time in hours, less than 1 day, i.e. 1h, 5h, 23h -->
14+
<plurals name="date_formatting_relative_hours">
15+
<item quantity="one">%dh</item>
16+
<item quantity="other">%dh</item>
17+
</plurals>
18+
</resources>

0 commit comments

Comments
 (0)