2017-05-08 15:28:33 +02:00
|
|
|
package org.schabi.newpipe.util;
|
2015-12-29 15:35:51 +01:00
|
|
|
|
2020-01-18 10:46:53 +01:00
|
|
|
import android.annotation.SuppressLint;
|
2015-12-29 15:35:51 +01:00
|
|
|
import android.content.Context;
|
|
|
|
import android.content.SharedPreferences;
|
2020-01-04 21:38:27 +01:00
|
|
|
import android.content.res.Configuration;
|
|
|
|
import android.content.res.Resources;
|
2020-10-18 04:00:32 +02:00
|
|
|
import android.icu.text.CompactDecimalFormat;
|
|
|
|
import android.os.Build;
|
2017-10-13 05:47:12 +02:00
|
|
|
import android.text.TextUtils;
|
2020-01-04 21:38:27 +01:00
|
|
|
import android.util.DisplayMetrics;
|
2021-01-15 17:11:04 +01:00
|
|
|
|
2020-01-09 09:40:05 +01:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.PluralsRes;
|
|
|
|
import androidx.annotation.StringRes;
|
2022-07-18 05:30:11 +02:00
|
|
|
import androidx.core.math.MathUtils;
|
2020-10-18 04:00:32 +02:00
|
|
|
import androidx.preference.PreferenceManager;
|
2021-01-15 17:11:04 +01:00
|
|
|
|
|
|
|
import org.ocpsoft.prettytime.PrettyTime;
|
|
|
|
import org.ocpsoft.prettytime.units.Decade;
|
|
|
|
import org.schabi.newpipe.R;
|
|
|
|
import org.schabi.newpipe.extractor.ListExtractor;
|
|
|
|
import org.schabi.newpipe.extractor.localization.ContentCountry;
|
|
|
|
|
2020-02-28 16:59:52 +01:00
|
|
|
import java.math.BigDecimal;
|
|
|
|
import java.math.RoundingMode;
|
2015-12-29 15:35:51 +01:00
|
|
|
import java.text.NumberFormat;
|
2020-10-18 08:16:55 +02:00
|
|
|
import java.time.OffsetDateTime;
|
|
|
|
import java.time.ZoneId;
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
import java.time.format.FormatStyle;
|
2018-01-28 07:14:38 +01:00
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.List;
|
2015-12-29 15:35:51 +01:00
|
|
|
import java.util.Locale;
|
2022-07-29 05:35:50 +02:00
|
|
|
import java.util.stream.Collectors;
|
2015-12-29 15:35:51 +01:00
|
|
|
|
2020-02-27 23:10:07 +01:00
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
/*
|
2015-12-29 15:35:51 +01:00
|
|
|
* Created by chschtsch on 12/29/15.
|
2016-01-05 21:41:55 +01:00
|
|
|
*
|
|
|
|
* Copyright (C) Gregory Arkhipov 2015
|
|
|
|
* Localization.java is part of NewPipe.
|
|
|
|
*
|
|
|
|
* NewPipe is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* NewPipe is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
2015-12-29 15:35:51 +01:00
|
|
|
*/
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public final class Localization {
|
2015-12-29 15:35:51 +01:00
|
|
|
|
2020-12-20 15:05:37 +01:00
|
|
|
public static final String DOT_SEPARATOR = " • ";
|
Multiple localization fixes
With the extractor PR, fixes title & description shown in the wrong language.
Fixed views / spectators counts possibly in the wrong language
Fixed live spectators not showing full count on detail page
Fixed LIVE shown on players, it shows translated instead
Fixed Videos string in search / three dots not available in Weblate
(because it was videos, but there already was a plural string named videos, in Weblate)
Subscriber count is always giving the short count.
We can't get exact number since this YouTube update: https://support.google.com/youtube/thread/6543166
But only short count (B, M, k), so showing full number, eg for 1.9M: 1,900,000, is wrong because the number could be 1,923,490 or 1,897,789…
Added a « sytem default » option to content language and country language selector.
It's the one selected by default (not en-GB anymore then), and correspond to the
language of the system / country of the system
By system I mean phone, tablet, TV…
Fixed russian showing - before time ago (eg 19hrs ago)
This is a workaround fix, I opened an issue on prettytime library repo.
Fixed russian plurals:
other was used instead of many for videos and subscribers
Fixed seek_duration english only
2020-02-14 18:19:35 +01:00
|
|
|
private static PrettyTime prettyTime;
|
2018-01-28 07:14:38 +01:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private Localization() { }
|
2016-03-10 10:50:42 +01:00
|
|
|
|
2018-01-28 07:14:38 +01:00
|
|
|
@NonNull
|
|
|
|
public static String concatenateStrings(final String... strings) {
|
2022-07-29 05:35:50 +02:00
|
|
|
return concatenateStrings(DOT_SEPARATOR, Arrays.asList(strings));
|
2018-01-28 07:14:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
2022-07-29 05:35:50 +02:00
|
|
|
public static String concatenateStrings(final String delimiter, final List<String> strings) {
|
|
|
|
return strings.stream()
|
|
|
|
.filter(string -> !TextUtils.isEmpty(string))
|
|
|
|
.collect(Collectors.joining(delimiter));
|
2018-01-28 07:14:38 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static org.schabi.newpipe.extractor.localization.Localization getPreferredLocalization(
|
|
|
|
final Context context) {
|
|
|
|
return org.schabi.newpipe.extractor.localization.Localization
|
2022-08-22 04:50:16 +02:00
|
|
|
.fromLocale(getPreferredLocale(context));
|
2019-10-28 03:35:51 +01:00
|
|
|
}
|
2018-10-05 16:19:21 +02:00
|
|
|
|
2019-10-28 03:35:51 +01:00
|
|
|
public static ContentCountry getPreferredContentCountry(final Context context) {
|
2020-03-31 19:20:15 +02:00
|
|
|
final String contentCountry = PreferenceManager.getDefaultSharedPreferences(context)
|
|
|
|
.getString(context.getString(R.string.content_country_key),
|
|
|
|
context.getString(R.string.default_localization_key));
|
2020-02-15 16:29:46 +01:00
|
|
|
if (contentCountry.equals(context.getString(R.string.default_localization_key))) {
|
Multiple localization fixes
With the extractor PR, fixes title & description shown in the wrong language.
Fixed views / spectators counts possibly in the wrong language
Fixed live spectators not showing full count on detail page
Fixed LIVE shown on players, it shows translated instead
Fixed Videos string in search / three dots not available in Weblate
(because it was videos, but there already was a plural string named videos, in Weblate)
Subscriber count is always giving the short count.
We can't get exact number since this YouTube update: https://support.google.com/youtube/thread/6543166
But only short count (B, M, k), so showing full number, eg for 1.9M: 1,900,000, is wrong because the number could be 1,923,490 or 1,897,789…
Added a « sytem default » option to content language and country language selector.
It's the one selected by default (not en-GB anymore then), and correspond to the
language of the system / country of the system
By system I mean phone, tablet, TV…
Fixed russian showing - before time ago (eg 19hrs ago)
This is a workaround fix, I opened an issue on prettytime library repo.
Fixed russian plurals:
other was used instead of many for videos and subscribers
Fixed seek_duration english only
2020-02-14 18:19:35 +01:00
|
|
|
return new ContentCountry(Locale.getDefault().getCountry());
|
|
|
|
}
|
2019-10-28 03:35:51 +01:00
|
|
|
return new ContentCountry(contentCountry);
|
2018-10-05 16:19:21 +02:00
|
|
|
}
|
|
|
|
|
2022-08-22 04:50:16 +02:00
|
|
|
private static Locale getLocaleFromPrefs(final Context context, @StringRes final int prefKey) {
|
2020-08-16 10:24:58 +02:00
|
|
|
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
2022-08-22 04:50:16 +02:00
|
|
|
final String defaultKey = context.getString(R.string.default_localization_key);
|
|
|
|
final String languageCode = sp.getString(context.getString(prefKey), defaultKey);
|
2015-12-29 15:35:51 +01:00
|
|
|
|
2022-08-22 04:50:16 +02:00
|
|
|
if (languageCode.equals(defaultKey)) {
|
|
|
|
return Locale.getDefault();
|
|
|
|
} else {
|
|
|
|
return Locale.forLanguageTag(languageCode);
|
2015-12-29 15:35:51 +01:00
|
|
|
}
|
2022-08-22 04:50:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static Locale getPreferredLocale(final Context context) {
|
|
|
|
return getLocaleFromPrefs(context, R.string.content_language_key);
|
|
|
|
}
|
2015-12-29 15:35:51 +01:00
|
|
|
|
2022-08-22 04:50:16 +02:00
|
|
|
public static Locale getAppLocale(final Context context) {
|
|
|
|
return getLocaleFromPrefs(context, R.string.app_language_key);
|
2015-12-29 15:35:51 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String localizeNumber(final Context context, final long number) {
|
2020-02-27 23:10:07 +01:00
|
|
|
return localizeNumber(context, (double) number);
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String localizeNumber(final Context context, final double number) {
|
2020-08-16 10:24:58 +02:00
|
|
|
final NumberFormat nf = NumberFormat.getInstance(getAppLocale(context));
|
2015-12-29 15:35:51 +01:00
|
|
|
return nf.format(number);
|
|
|
|
}
|
|
|
|
|
2020-10-18 08:16:55 +02:00
|
|
|
public static String formatDate(final OffsetDateTime offsetDateTime, final Context context) {
|
|
|
|
return DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
|
|
|
|
.withLocale(getAppLocale(context)).format(offsetDateTime
|
|
|
|
.atZoneSameInstant(ZoneId.systemDefault()));
|
2015-12-29 15:35:51 +01:00
|
|
|
}
|
|
|
|
|
2020-01-18 10:46:53 +01:00
|
|
|
@SuppressLint("StringFormatInvalid")
|
2020-10-18 08:16:55 +02:00
|
|
|
public static String localizeUploadDate(final Context context,
|
|
|
|
final OffsetDateTime offsetDateTime) {
|
|
|
|
return context.getString(R.string.upload_date_text, formatDate(offsetDateTime, context));
|
2015-12-29 15:35:51 +01:00
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String localizeViewCount(final Context context, final long viewCount) {
|
|
|
|
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
|
|
|
|
localizeNumber(context, viewCount));
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String localizeStreamCount(final Context context, final long streamCount) {
|
2020-03-20 20:57:56 +01:00
|
|
|
switch ((int) streamCount) {
|
2020-03-20 22:01:56 +01:00
|
|
|
case (int) ListExtractor.ITEM_COUNT_UNKNOWN:
|
|
|
|
return "";
|
2020-03-20 20:57:56 +01:00
|
|
|
case (int) ListExtractor.ITEM_COUNT_INFINITE:
|
2020-03-20 21:43:17 +01:00
|
|
|
return context.getResources().getString(R.string.infinite_videos);
|
2020-03-20 22:01:56 +01:00
|
|
|
case (int) ListExtractor.ITEM_COUNT_MORE_THAN_100:
|
|
|
|
return context.getResources().getString(R.string.more_than_100_videos);
|
2020-03-20 20:57:56 +01:00
|
|
|
default:
|
|
|
|
return getQuantity(context, R.plurals.videos, R.string.no_videos, streamCount,
|
|
|
|
localizeNumber(context, streamCount));
|
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2020-03-20 21:43:17 +01:00
|
|
|
public static String localizeStreamCountMini(final Context context, final long streamCount) {
|
|
|
|
switch ((int) streamCount) {
|
2020-03-20 22:01:56 +01:00
|
|
|
case (int) ListExtractor.ITEM_COUNT_UNKNOWN:
|
|
|
|
return "";
|
2020-03-20 21:43:17 +01:00
|
|
|
case (int) ListExtractor.ITEM_COUNT_INFINITE:
|
|
|
|
return context.getResources().getString(R.string.infinite_videos_mini);
|
2020-03-20 22:01:56 +01:00
|
|
|
case (int) ListExtractor.ITEM_COUNT_MORE_THAN_100:
|
|
|
|
return context.getResources().getString(R.string.more_than_100_videos_mini);
|
2020-03-20 21:43:17 +01:00
|
|
|
default:
|
|
|
|
return String.valueOf(streamCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String localizeWatchingCount(final Context context, final long watchingCount) {
|
|
|
|
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
|
|
|
|
localizeNumber(context, watchingCount));
|
Multiple localization fixes
With the extractor PR, fixes title & description shown in the wrong language.
Fixed views / spectators counts possibly in the wrong language
Fixed live spectators not showing full count on detail page
Fixed LIVE shown on players, it shows translated instead
Fixed Videos string in search / three dots not available in Weblate
(because it was videos, but there already was a plural string named videos, in Weblate)
Subscriber count is always giving the short count.
We can't get exact number since this YouTube update: https://support.google.com/youtube/thread/6543166
But only short count (B, M, k), so showing full number, eg for 1.9M: 1,900,000, is wrong because the number could be 1,923,490 or 1,897,789…
Added a « sytem default » option to content language and country language selector.
It's the one selected by default (not en-GB anymore then), and correspond to the
language of the system / country of the system
By system I mean phone, tablet, TV…
Fixed russian showing - before time ago (eg 19hrs ago)
This is a workaround fix, I opened an issue on prettytime library repo.
Fixed russian plurals:
other was used instead of many for videos and subscribers
Fixed seek_duration english only
2020-02-14 18:19:35 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String shortCount(final Context context, final long count) {
|
2020-10-31 20:54:02 +01:00
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
2020-10-18 04:00:32 +02:00
|
|
|
return CompactDecimalFormat.getInstance(getAppLocale(context),
|
|
|
|
CompactDecimalFormat.CompactStyle.SHORT).format(count);
|
|
|
|
}
|
|
|
|
|
2020-08-16 10:24:58 +02:00
|
|
|
final double value = (double) count;
|
2017-09-03 08:04:18 +02:00
|
|
|
if (count >= 1000000000) {
|
2020-03-31 19:20:15 +02:00
|
|
|
return localizeNumber(context, round(value / 1000000000, 1))
|
|
|
|
+ context.getString(R.string.short_billion);
|
2017-09-03 08:04:18 +02:00
|
|
|
} else if (count >= 1000000) {
|
2020-03-31 19:20:15 +02:00
|
|
|
return localizeNumber(context, round(value / 1000000, 1))
|
|
|
|
+ context.getString(R.string.short_million);
|
2017-09-03 08:04:18 +02:00
|
|
|
} else if (count >= 1000) {
|
2020-03-31 19:20:15 +02:00
|
|
|
return localizeNumber(context, round(value / 1000, 1))
|
|
|
|
+ context.getString(R.string.short_thousand);
|
2017-09-03 08:04:18 +02:00
|
|
|
} else {
|
2020-02-27 23:10:07 +01:00
|
|
|
return localizeNumber(context, value);
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String listeningCount(final Context context, final long listeningCount) {
|
|
|
|
return getQuantity(context, R.plurals.listening, R.string.no_one_listening, listeningCount,
|
|
|
|
shortCount(context, listeningCount));
|
2019-10-28 03:37:36 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String shortWatchingCount(final Context context, final long watchingCount) {
|
|
|
|
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
|
|
|
|
shortCount(context, watchingCount));
|
2019-10-28 03:37:36 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String shortViewCount(final Context context, final long viewCount) {
|
|
|
|
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
|
|
|
|
shortCount(context, viewCount));
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String shortSubscriberCount(final Context context, final long subscriberCount) {
|
|
|
|
return getQuantity(context, R.plurals.subscribers, R.string.no_subscribers, subscriberCount,
|
|
|
|
shortCount(context, subscriberCount));
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2021-08-29 13:28:01 +02:00
|
|
|
public static String downloadCount(final Context context, final int downloadCount) {
|
|
|
|
return getQuantity(context, R.plurals.download_finished_notification, 0,
|
|
|
|
downloadCount, shortCount(context, downloadCount));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String deletedDownloadCount(final Context context, final int deletedCount) {
|
|
|
|
return getQuantity(context, R.plurals.deleted_downloads_toast, 0,
|
|
|
|
deletedCount, shortCount(context, deletedCount));
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private static String getQuantity(final Context context, @PluralsRes final int pluralId,
|
|
|
|
@StringRes final int zeroCaseStringId, final long count,
|
|
|
|
final String formattedCount) {
|
|
|
|
if (count == 0) {
|
|
|
|
return context.getString(zeroCaseStringId);
|
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
// As we use the already formatted count
|
|
|
|
// is not the responsibility of this method handle long numbers
|
|
|
|
// (it probably will fall in the "other" category,
|
|
|
|
// or some language have some specific rule... then we have to change it)
|
2022-07-18 05:30:11 +02:00
|
|
|
final int safeCount = (int) MathUtils.clamp(count, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
2017-09-03 08:04:18 +02:00
|
|
|
return context.getResources().getQuantityString(pluralId, safeCount, formattedCount);
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String getDurationString(final long duration) {
|
|
|
|
final String output;
|
|
|
|
|
|
|
|
final long days = duration / (24 * 60 * 60L); /* greater than a day */
|
|
|
|
final long hours = duration % (24 * 60 * 60L) / (60 * 60L); /* greater than an hour */
|
|
|
|
final long minutes = duration % (24 * 60 * 60L) % (60 * 60L) / 60L;
|
|
|
|
final long seconds = duration % 60L;
|
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
if (duration < 0) {
|
2020-03-31 19:20:15 +02:00
|
|
|
output = "0:00";
|
|
|
|
} else if (days > 0) {
|
|
|
|
//handle days
|
2017-09-03 08:04:18 +02:00
|
|
|
output = String.format(Locale.US, "%d:%02d:%02d:%02d", days, hours, minutes, seconds);
|
|
|
|
} else if (hours > 0) {
|
|
|
|
output = String.format(Locale.US, "%d:%02d:%02d", hours, minutes, seconds);
|
|
|
|
} else {
|
|
|
|
output = String.format(Locale.US, "%d:%02d", minutes, seconds);
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
2019-10-28 05:20:06 +01:00
|
|
|
|
2020-03-06 03:20:55 +01:00
|
|
|
/**
|
|
|
|
* Localize an amount of seconds into a human readable string.
|
|
|
|
*
|
|
|
|
* <p>The seconds will be converted to the closest whole time unit.
|
|
|
|
* <p>For example, 60 seconds would give "1 minute", 119 would also give "1 minute".
|
|
|
|
*
|
2020-03-31 19:20:15 +02:00
|
|
|
* @param context used to get plurals resources.
|
2020-03-06 03:20:55 +01:00
|
|
|
* @param durationInSecs an amount of seconds.
|
|
|
|
* @return duration in a human readable string.
|
|
|
|
*/
|
|
|
|
@NonNull
|
2020-03-31 19:20:15 +02:00
|
|
|
public static String localizeDuration(final Context context, final int durationInSecs) {
|
2020-03-06 03:20:55 +01:00
|
|
|
if (durationInSecs < 0) {
|
|
|
|
throw new IllegalArgumentException("duration can not be negative");
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
final int days = (int) (durationInSecs / (24 * 60 * 60L));
|
|
|
|
final int hours = (int) (durationInSecs % (24 * 60 * 60L) / (60 * 60L));
|
|
|
|
final int minutes = (int) (durationInSecs % (24 * 60 * 60L) % (60 * 60L) / 60L);
|
|
|
|
final int seconds = (int) (durationInSecs % (24 * 60 * 60L) % (60 * 60L) % 60L);
|
2020-03-06 03:20:55 +01:00
|
|
|
|
|
|
|
final Resources resources = context.getResources();
|
|
|
|
|
|
|
|
if (days > 0) {
|
|
|
|
return resources.getQuantityString(R.plurals.days, days, days);
|
|
|
|
} else if (hours > 0) {
|
|
|
|
return resources.getQuantityString(R.plurals.hours, hours, hours);
|
|
|
|
} else if (minutes > 0) {
|
|
|
|
return resources.getQuantityString(R.plurals.minutes, minutes, minutes);
|
|
|
|
} else {
|
|
|
|
return resources.getQuantityString(R.plurals.seconds, seconds, seconds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-28 05:20:06 +01:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Pretty Time
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2021-01-06 14:48:34 +01:00
|
|
|
public static void initPrettyTime(final PrettyTime time) {
|
|
|
|
prettyTime = time;
|
2019-10-28 05:20:06 +01:00
|
|
|
// Do not use decades as YouTube doesn't either.
|
|
|
|
prettyTime.removeUnit(Decade.class);
|
|
|
|
}
|
|
|
|
|
2021-01-06 14:48:34 +01:00
|
|
|
public static PrettyTime resolvePrettyTime(final Context context) {
|
|
|
|
return new PrettyTime(getAppLocale(context));
|
|
|
|
}
|
|
|
|
|
2020-11-19 14:05:17 +01:00
|
|
|
public static String relativeTime(final OffsetDateTime offsetDateTime) {
|
2020-12-20 05:23:05 +01:00
|
|
|
return prettyTime.formatUnrounded(offsetDateTime);
|
2019-10-28 05:20:06 +01:00
|
|
|
}
|
2020-01-04 21:38:27 +01:00
|
|
|
|
2022-08-22 04:50:16 +02:00
|
|
|
private static void changeAppLanguage(final Resources res, final Locale loc) {
|
2020-08-16 10:24:58 +02:00
|
|
|
final DisplayMetrics dm = res.getDisplayMetrics();
|
|
|
|
final Configuration conf = res.getConfiguration();
|
2020-01-04 21:38:27 +01:00
|
|
|
conf.setLocale(loc);
|
|
|
|
res.updateConfiguration(conf, dm);
|
|
|
|
}
|
2020-01-09 09:40:05 +01:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
public static void assureCorrectAppLanguage(final Context c) {
|
2022-08-22 04:50:16 +02:00
|
|
|
changeAppLanguage(c.getResources(), getAppLocale(c));
|
2020-01-28 20:48:42 +01:00
|
|
|
}
|
2020-02-28 16:59:52 +01:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private static double round(final double value, final int places) {
|
2020-02-28 16:59:52 +01:00
|
|
|
return new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue();
|
|
|
|
}
|
2015-12-29 15:35:51 +01:00
|
|
|
}
|