|
|
|
@ -28,6 +28,7 @@ import org.session.libsignal.utilities.Log;
|
|
|
|
|
|
|
|
|
|
import java.text.ParseException;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.Calendar;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.Locale;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
@ -40,8 +41,9 @@ import network.loki.messenger.R;
|
|
|
|
|
public class DateUtils extends android.text.format.DateUtils {
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
private static final String TAG = DateUtils.class.getSimpleName();
|
|
|
|
|
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
|
|
|
|
|
private static final String TAG = DateUtils.class.getSimpleName();
|
|
|
|
|
private static final SimpleDateFormat DAY_PRECISION_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
|
|
|
|
|
private static final SimpleDateFormat HOUR_PRECISION_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHH");
|
|
|
|
|
|
|
|
|
|
private static boolean isWithin(final long millis, final long span, final TimeUnit unit) {
|
|
|
|
|
return System.currentTimeMillis() - millis <= unit.toMillis(span);
|
|
|
|
@ -60,56 +62,21 @@ public class DateUtils extends android.text.format.DateUtils {
|
|
|
|
|
return new SimpleDateFormat(localizedPattern, locale).format(new Date(time));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String getBriefRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
|
|
|
|
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
|
|
|
|
return c.getString(R.string.DateUtils_just_now);
|
|
|
|
|
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
|
|
|
|
int mins = convertDelta(timestamp, TimeUnit.MINUTES);
|
|
|
|
|
return c.getResources().getString(R.string.DateUtils_minutes_ago, mins);
|
|
|
|
|
} else if (isWithin(timestamp, 1, TimeUnit.DAYS)) {
|
|
|
|
|
int hours = convertDelta(timestamp, TimeUnit.HOURS);
|
|
|
|
|
return c.getResources().getQuantityString(R.plurals.hours_ago, hours, hours);
|
|
|
|
|
} else if (isWithin(timestamp, 6, TimeUnit.DAYS)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, "EEE", locale);
|
|
|
|
|
} else if (isWithin(timestamp, 365, TimeUnit.DAYS)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, "MMM d", locale);
|
|
|
|
|
} else {
|
|
|
|
|
return getFormattedDateTime(timestamp, "MMM d, yyyy", locale);
|
|
|
|
|
}
|
|
|
|
|
public static String getHourFormat(Context c) {
|
|
|
|
|
return (DateFormat.is24HourFormat(c)) ? "HH:mm" : "hh:mm a";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String getExtendedRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
|
|
|
|
public static String getDisplayFormattedTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
|
|
|
|
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
|
|
|
|
return c.getString(R.string.DateUtils_just_now);
|
|
|
|
|
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
|
|
|
|
int mins = (int)TimeUnit.MINUTES.convert(System.currentTimeMillis() - timestamp, TimeUnit.MILLISECONDS);
|
|
|
|
|
return c.getResources().getString(R.string.DateUtils_minutes_ago, mins);
|
|
|
|
|
} else {
|
|
|
|
|
StringBuilder format = new StringBuilder();
|
|
|
|
|
if (isWithin(timestamp, 6, TimeUnit.DAYS)) format.append("EEE ");
|
|
|
|
|
else if (isWithin(timestamp, 365, TimeUnit.DAYS)) format.append("MMM d, ");
|
|
|
|
|
else format.append("MMM d, yyyy, ");
|
|
|
|
|
|
|
|
|
|
if (DateFormat.is24HourFormat(c)) format.append("HH:mm");
|
|
|
|
|
else format.append("hh:mm a");
|
|
|
|
|
|
|
|
|
|
return getFormattedDateTime(timestamp, format.toString(), locale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String getDayPrecisionTimeSpanString(Context context, Locale locale, long timestamp) {
|
|
|
|
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
|
|
|
|
|
|
|
|
|
|
if (simpleDateFormat.format(System.currentTimeMillis()).equals(simpleDateFormat.format(timestamp))) {
|
|
|
|
|
return context.getString(R.string.DeviceListItem_today);
|
|
|
|
|
} else if (isToday(timestamp)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, getHourFormat(c), locale);
|
|
|
|
|
} else if (isWithin(timestamp, 6, TimeUnit.DAYS)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, "EEE " + getHourFormat(c), locale);
|
|
|
|
|
} else if (isWithin(timestamp, 365, TimeUnit.DAYS)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, "MMM d " + getHourFormat(c), locale);
|
|
|
|
|
} else {
|
|
|
|
|
String format;
|
|
|
|
|
|
|
|
|
|
if (isWithin(timestamp, 6, TimeUnit.DAYS)) format = "EEE ";
|
|
|
|
|
else if (isWithin(timestamp, 365, TimeUnit.DAYS)) format = "MMM d";
|
|
|
|
|
else format = "MMM d, yyy";
|
|
|
|
|
|
|
|
|
|
return getFormattedDateTime(timestamp, format, locale);
|
|
|
|
|
return getFormattedDateTime(timestamp, "MMM d " + getHourFormat(c) + ", yyyy", locale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -139,11 +106,11 @@ public class DateUtils extends android.text.format.DateUtils {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean isSameDay(long t1, long t2) {
|
|
|
|
|
return DATE_FORMAT.format(new Date(t1)).equals(DATE_FORMAT.format(new Date(t2)));
|
|
|
|
|
return DAY_PRECISION_DATE_FORMAT.format(new Date(t1)).equals(DAY_PRECISION_DATE_FORMAT.format(new Date(t2)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean isSameExtendedRelativeTimestamp(@NonNull Context context, @NonNull Locale locale, long t1, long t2) {
|
|
|
|
|
return getExtendedRelativeTimeSpanString(context, locale, t1).equals(getExtendedRelativeTimeSpanString(context, locale, t2));
|
|
|
|
|
public static boolean isSameHour(long t1, long t2) {
|
|
|
|
|
return HOUR_PRECISION_DATE_FORMAT.format(new Date(t1)).equals(HOUR_PRECISION_DATE_FORMAT.format(new Date(t2)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String getLocalizedPattern(String template, Locale locale) {
|
|
|
|
@ -178,4 +145,43 @@ public class DateUtils extends android.text.format.DateUtils {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// region Deprecated
|
|
|
|
|
public static String getBriefRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
|
|
|
|
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
|
|
|
|
return c.getString(R.string.DateUtils_just_now);
|
|
|
|
|
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
|
|
|
|
int mins = convertDelta(timestamp, TimeUnit.MINUTES);
|
|
|
|
|
return c.getResources().getString(R.string.DateUtils_minutes_ago, mins);
|
|
|
|
|
} else if (isWithin(timestamp, 1, TimeUnit.DAYS)) {
|
|
|
|
|
int hours = convertDelta(timestamp, TimeUnit.HOURS);
|
|
|
|
|
return c.getResources().getQuantityString(R.plurals.hours_ago, hours, hours);
|
|
|
|
|
} else if (isWithin(timestamp, 6, TimeUnit.DAYS)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, "EEE", locale);
|
|
|
|
|
} else if (isWithin(timestamp, 365, TimeUnit.DAYS)) {
|
|
|
|
|
return getFormattedDateTime(timestamp, "MMM d", locale);
|
|
|
|
|
} else {
|
|
|
|
|
return getFormattedDateTime(timestamp, "MMM d, yyyy", locale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String getExtendedRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
|
|
|
|
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
|
|
|
|
return c.getString(R.string.DateUtils_just_now);
|
|
|
|
|
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
|
|
|
|
int mins = (int)TimeUnit.MINUTES.convert(System.currentTimeMillis() - timestamp, TimeUnit.MILLISECONDS);
|
|
|
|
|
return c.getResources().getString(R.string.DateUtils_minutes_ago, mins);
|
|
|
|
|
} else {
|
|
|
|
|
StringBuilder format = new StringBuilder();
|
|
|
|
|
if (isWithin(timestamp, 6, TimeUnit.DAYS)) format.append("EEE ");
|
|
|
|
|
else if (isWithin(timestamp, 365, TimeUnit.DAYS)) format.append("MMM d, ");
|
|
|
|
|
else format.append("MMM d, yyyy, ");
|
|
|
|
|
|
|
|
|
|
if (DateFormat.is24HourFormat(c)) format.append("HH:mm");
|
|
|
|
|
else format.append("hh:mm a");
|
|
|
|
|
|
|
|
|
|
return getFormattedDateTime(timestamp, format.toString(), locale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// endregion
|
|
|
|
|
}
|
|
|
|
|