我使用以下方式覆盖我的应用的区域设置:
Locale locale = new Locale("ca");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
但似乎getRelativeTimeSpanString
不适用于应用程序上下文,而是使用系统区域设置。
答案 0 :(得分:12)
你的解决方案几乎是正确的。
但是,由于字符串是从系统资源加载的,因此必须更新系统资源的配置。以下是我的所作所为:
Configuration configuration = new Configuration(Resources.getSystem().getConfiguration());
configuration.locale = Locale.GERMANY; // or whichever locale you desire
Resources.getSystem().updateConfiguration(configuration, null);
(注意:从Jelly Bean MR1开始,建议使用
configuration.setLocale(Locale.GERMANY);
更改区域设置,而不是直接设置成员。)
答案 1 :(得分:5)
我今天遇到了这个问题,花了几个小时才解决了#34;。
我建议你,如果你可以使用getRelativeTimeSpanString(context,long,boolean)来代替。这不是我的情况,因为结果字符串与getRelativeTimeSpanString(long)不同。
我的解决方法需要将一些字符串的一些android内部资源复制到您的代码中,因此如果您需要支持很多语言,那将非常烦人。
我跟踪了Android(4.4 r1)的当前源代码并提取了DateUtils并进行了更改,以便您可以像这样使用它:
CharSequence desiredString = MyDateUtils.getRelativeTimeSpanString(time,
System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR, activity);
这将给你与getRelativeTimeSpanString(long)相同的结果。
只保留MyDateUtils:
public static CharSequence getRelativeTimeSpanString(long time,long now,long minResolution,int flags,Context c)
我在方法中添加了上下文,然后更改了上下文资源的系统资源以及我自己的字符串的所有内部android字符串(与android' s相同,但无法找到使用它们的方法,因为它们是internal)。
private static final String getRelativeDayString(Resources r,long day,long today)
也保持此方法为先前使用的方法。在这里我也改变了字符串。
这是我对MyDateUtils的实现:
import java.util.Locale;
import android.content.Context;
import android.content.res.Resources;
import android.text.format.DateUtils;
import android.text.format.Time;
import com.YOURPACKAGE.R;
/**
* This class contains various date-related utilities for creating text for things like
* elapsed time and date ranges, strings for days of the week and months, and AM/PM text etc.
*/
public class MyDateUtils
{
/**
* Returns a string describing 'time' as a time relative to 'now'.
* <p>
* Time spans in the past are formatted like "42 minutes ago". Time spans in
* the future are formatted like "in 42 minutes".
* <p>
* Can use {@link #FORMAT_ABBREV_RELATIVE} flag to use abbreviated relative
* times, like "42 mins ago".
*
* @param time the time to describe, in milliseconds
* @param now the current time in milliseconds
* @param minResolution the minimum timespan to report. For example, a time
* 3 seconds in the past will be reported as "0 minutes ago" if
* this is set to MINUTE_IN_MILLIS. Pass one of 0,
* MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS,
* WEEK_IN_MILLIS
* @param flags a bit mask of formatting options, such as
* {@link #FORMAT_NUMERIC_DATE} or
* {@link #FORMAT_ABBREV_RELATIVE}
*/
public static CharSequence getRelativeTimeSpanString(long time, long now, long minResolution,
int flags, Context c) {
Resources r = c.getResources();
//boolean abbrevRelative = (flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0;
boolean past = (now >= time);
long duration = Math.abs(now - time);
int resId;
long count;
if (duration < DateUtils.MINUTE_IN_MILLIS && minResolution < DateUtils.MINUTE_IN_MILLIS) {
count = duration / DateUtils.SECOND_IN_MILLIS;
if (past) {
resId = R.plurals.num_seconds_ago;
} else {
resId = R.plurals.in_num_seconds;
}
} else if (duration < DateUtils.HOUR_IN_MILLIS && minResolution < DateUtils.HOUR_IN_MILLIS) {
count = duration / DateUtils.MINUTE_IN_MILLIS;
if (past) {
resId = R.plurals.num_minutes_ago;
} else {
resId = R.plurals.in_num_minutes;
}
} else if (duration < DateUtils.DAY_IN_MILLIS && minResolution < DateUtils.DAY_IN_MILLIS) {
count = duration / DateUtils.HOUR_IN_MILLIS;
if (past) {
resId = R.plurals.num_hours_ago;
} else {
resId = R.plurals.in_num_hours;
}
} else if (duration < DateUtils.WEEK_IN_MILLIS && minResolution < DateUtils.WEEK_IN_MILLIS) {
return getRelativeDayString(r, time, now);
} else {
// We know that we won't be showing the time, so it is safe to pass
// in a null context.
return DateUtils.formatDateRange(null, time, time, flags);
}
String format = r.getQuantityString(resId, (int) count);
return String.format(format, count);
}
/**
* Returns a string describing a day relative to the current day. For example if the day is
* today this function returns "Today", if the day was a week ago it returns "7 days ago", and
* if the day is in 2 weeks it returns "in 14 days".
*
* @param r the resources
* @param day the relative day to describe in UTC milliseconds
* @param today the current time in UTC milliseconds
*/
private static final String getRelativeDayString(Resources r, long day, long today) {
Locale locale = r.getConfiguration().locale;
if (locale == null) {
locale = Locale.getDefault();
}
// TODO: use TimeZone.getOffset instead.
Time startTime = new Time();
startTime.set(day);
int startDay = Time.getJulianDay(day, startTime.gmtoff);
Time currentTime = new Time();
currentTime.set(today);
int currentDay = Time.getJulianDay(today, currentTime.gmtoff);
int days = Math.abs(currentDay - startDay);
boolean past = (today > day);
// TODO: some locales name other days too, such as de_DE's "Vorgestern" (today - 2).
if (days == 1) {
if (past) {
return r.getString(R.string.yesterday);
} else {
return r.getString(R.string.tomorrow);
}
} else if (days == 0) {
return r.getString(R.string.today);
}
int resId;
if (past) {
resId = R.plurals.num_days_ago;
} else {
resId = R.plurals.in_num_days;
}
String format = r.getQuantityString(resId, days);
return String.format(format, days);
}
}
在值文件夹string.xml上添加:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="yesterday">yesterday</string>
<string name="tomorrow">tomorrow</string>
<string name="today">today</string>
<plurals name="num_seconds_ago">
<item quantity="one">1 second ago</item>
<item quantity="other"><xliff:g id="count">%d</xliff:g> seconds ago</item>
</plurals>
<plurals name="num_minutes_ago">
<item quantity="one">1 minute ago</item>
<item quantity="other"><xliff:g id="count">%d</xliff:g> minutes ago</item>
</plurals>
<plurals name="num_hours_ago">
<item quantity="one">1 hour ago</item>
<item quantity="other"><xliff:g id="count">%d</xliff:g> hours ago</item>
</plurals>
<plurals name="num_days_ago">
<item quantity="one">yesterday</item>
<item quantity="other"><xliff:g id="count">%d</xliff:g> days ago</item>
</plurals>
<plurals name="in_num_seconds">
<item quantity="one">in 1 second</item>
<item quantity="other">in <xliff:g id="count">%d</xliff:g> seconds</item>
</plurals>
<plurals name="in_num_minutes">
<item quantity="one">in 1 minute</item>
<item quantity="other">in <xliff:g id="count">%d</xliff:g> minutes</item>
</plurals>
<plurals name="in_num_hours">
<item quantity="one">in 1 hour</item>
<item quantity="other">in <xliff:g id="count">%d</xliff:g> hours</item>
</plurals>
<plurals name="in_num_days">
<item quantity="one">tomorrow</item>
<item quantity="other">in <xliff:g id="count">%d</xliff:g> days</item>
</plurals>
</resources>
例如,对于其他语言,例如Portuguese,在values-pt文件夹string.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="yesterday">ontem</string>
<string name="tomorrow">manhã</string>
<string name="today">hoje</string>
<plurals name="num_seconds_ago">
<item msgid="4869870056547896011" quantity="one">"1 segundo atrás"</item>
<item msgid="3903706804349556379" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> segundos atrás"</item>
</plurals>
<plurals name="num_minutes_ago">
<item msgid="3306787433088810191" quantity="one">"1 minuto atrás"</item>
<item msgid="2176942008915455116" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutos atrás"</item>
</plurals>
<plurals name="num_hours_ago">
<item msgid="9150797944610821849" quantity="one">"1 hora atrás"</item>
<item msgid="2467273239587587569" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> horas atrás"</item>
</plurals>
<plurals name="num_days_ago">
<item msgid="861358534398115820" quantity="one">"ontem"</item>
<item msgid="2479586466153314633" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dias atrás"</item>
</plurals>
<plurals name="in_num_seconds">
<item msgid="2729745560954905102" quantity="one">"em 1 segundo"</item>
<item msgid="1241926116443974687" quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
</plurals>
<plurals name="in_num_minutes">
<item msgid="8793095251325200395" quantity="one">"em 1 minuto"</item>
<item msgid="3330713936399448749" quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> minutos"</item>
</plurals>
<plurals name="in_num_hours">
<item msgid="7164353342477769999" quantity="one">"em 1 hora"</item>
<item msgid="547290677353727389" quantity="other">"Em <xliff:g id="COUNT">%d</xliff:g> horas"</item>
</plurals>
<plurals name="in_num_days">
<item msgid="5413088743009839518" quantity="one">"amanhã"</item>
<item msgid="5109449375100953247" quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> dias"</item>
</plurals>
</resources>
答案 2 :(得分:1)
我使用Custom方法来处理这个问题:
public static String getRelativeTimeSpanString(Context context, Date fromdate) {
long then;
then = fromdate.getTime();
Date date = new Date(then);
StringBuffer dateStr = new StringBuffer();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
Calendar now = Calendar.getInstance();
int days = daysBetween(calendar.getTime(), now.getTime());
int weeks= days/7;
int minutes = hoursBetween(calendar.getTime(), now.getTime());
int hours = minutes / 60;
if (days == 0) {
int second = minuteBetween(calendar.getTime(), now.getTime());
if (minutes > 60) {
if (hours >= 1 && hours <= 24) {
dateStr.append(String.format("%s %s %s",
hours,
context.getString(R.string.hour)
,context.getString(R.string.ago)));
}
}else {
if (second <= 10) {
dateStr.append(context.getString(R.string.now));
} else if (second > 10 && second <= 30) {
dateStr.append(context.getString(R.string.few_seconds_ago));
} else if (second > 30 && second <= 60) {
dateStr.append(String.format("%s %s %s",
second,
context.getString(R.string.seconds)
,context.getString(R.string.ago)));
} else if (second >= 60 && minutes <= 60) {
dateStr.append(String.format("%s %s %s",
minutes,
context.getString(R.string.minutes)
,context.getString(R.string.ago)));
}
}
} else
if (hours > 24 && days < 7) {
dateStr.append(String.format("%s %s %s",
days,
context.getString(R.string.days)
,context.getString(R.string.ago)));
}else if(weeks == 1){
dateStr.append(String.format("%s %s %s",
weeks,
context.getString(R.string.weeks)
,context.getString(R.string.ago)));
}
else {
/**
* make formatted createTime by languageTag("fa")
*
* @return
*/
return SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,new Locale("fra"))
.format(date).toUpperCase();
}
return dateStr.toString();
}
public static int minuteBetween(Date d1, Date d2) {
return (int) ((d2.getTime() - d1.getTime()) / android.text.format.DateUtils.SECOND_IN_MILLIS);
}
public static int hoursBetween(Date d1, Date d2) {
return (int) ((d2.getTime() - d1.getTime()) / android.text.format.DateUtils.MINUTE_IN_MILLIS);
}
public static int daysBetween(Date d1, Date d2) {
return (int) ((d2.getTime() - d1.getTime()) / android.text.format.DateUtils.DAY_IN_MILLIS);
}
我将date设置为此方法的参数:
return getRelativeTimeSpanString(context,this.createdTime);
这个按照我想要的位置返回字符串!希望能帮到你。