10

Google I / O Session 2012アプリを確認していて、このTODOに出くわしました

public static String getTimeAgo(long time, Context ctx) {
    if (time < 1000000000000L) {
        // if timestamp given in seconds, convert to millis
        time *= 1000;
    }

    long now = getCurrentTime(ctx);
    if (time > now || time <= 0) {
        return null;
    }

    // TODO: localize
    final long diff = now - time;
    if (diff < MINUTE_MILLIS) {
        return "just now";
    } else if (diff < 2 * MINUTE_MILLIS) {
        return "a minute ago";
    } else if (diff < 50 * MINUTE_MILLIS) {
        return diff / MINUTE_MILLIS + " minutes ago";
    } else if (diff < 90 * MINUTE_MILLIS) {
        return "an hour ago";
    } else if (diff < 24 * HOUR_MILLIS) {
        return diff / HOUR_MILLIS + " hours ago";
    } else if (diff < 48 * HOUR_MILLIS) {
        return "yesterday";
    } else {
        return diff / DAY_MILLIS + " days ago";
    }
}

それは私にそれをローカライズするためのステップは何であるか疑問に思いました。

4

4 に答える 4

21

カスタム文字列が必要ない場合は、次のような文字列を生成するDateUtils.getRelativeTimeSpanStringを使用することもできます。

  • 42分前
  • 10秒前
  • 1時間で

使用例:

final CharSequence relativeTimeSpan = DateUtils.getRelativeTimeSpanString(time, now, 0);
于 2012-11-02T21:53:04.073 に答える
10

イアンレイクの答えから:

final CharSequence relativeTimeSpan = DateUtils.getRelativeTimeSpanString(time, now, 0);

DateUtils.getRelativeTimeSpanStringは、次のようなものを生成します。

  • 42分前
  • 10秒前
  • 1時間で

あるいは、これにより、与えられたを使用してAndroidresフレームワークを介して翻訳を提供できるようになりContextます。これは、フレームワークの方法から得られるものと希望するメッセージングの違いがある場合に役立ちます。

public static String getTimeAgo(long time, Context context) {
    if (time < 1000000000000L)
        // if timestamp given in seconds, convert to millis
        time *= 1000;

    final long now = getCurrentTime(context);
    if (time > now || time <= 0) return "";


    final Resources res = context.getResources();
    final long time_difference = now - time;
    if (time_difference < _A_MINUTE)
        return res.getString(R.string.just_now);
    else if (time_difference < 50 * _A_MINUTE)
        return res.getString(R.string.time_ago,
                             res.getQuantityString(R.plurals.minutes, (int) time_difference / _A_MINUTE, time_difference / _A_MINUTE));
    else if (time_difference < 24 * _AN_HOUR)
        return res.getString(R.string.time_ago,
                             res.getQuantityString(R.plurals.hours, (int) time_difference / _AN_HOUR, time_difference / _AN_HOUR));
    else if (time_difference < 48 * _AN_HOUR)
        return res.getString(R.string.yesterday);
    else
        return res.getString(R.string.time_ago,
                             res.getQuantityString(R.plurals.days, (int) time_difference / _A_DAY, time_difference / _A_DAY));
}

ここで、定数を次のように定義しました。

/** One second (in milliseconds) */
private static final int _A_SECOND = 1000;
/** One minute (in milliseconds) */
private static final int _A_MINUTE = 60 * _A_SECOND;
/** One hour (in milliseconds) */
private static final int _AN_HOUR = 60 * _A_MINUTE;
/** One day (in milliseconds) */
private static final int _A_DAY = 24 * _AN_HOUR;

その後、残りの作業は複数形と文字列リソースの構造になります。

私のデフォルトのローカルはenなので、res/values/strings.xml

<!-- time ago strings -->
<string name="just_now">just now</string>
<string name="time_ago">%s ago</string>
<string name="yesterday">yesterday</string>

次にres/values/plurals.xml

<plurals name="minutes">
    <item quantity="one">a minute</item>
    <item quantity="other">%d minutes</item>
</plurals>

<plurals name="hours">
    <item quantity="one">an hour</item>
    <item quantity="other">%d hours</item>
</plurals>

<plurals name="days">
    <item quantity="one">a day</item>
    <item quantity="other">%d days</item>
</plurals>

このアプローチでは、言語の語彙と文法にローカライズできるはずです。言語が異なれば、「分」などの単語の単語が異なるだけでなく、量に基づいて単語を複数形にする方法についても異なるルールがあります。したがって、複数形のリソースは、複数形にローカライズするためのAndroidフレームワークのサポートを利用します。残っているのは翻訳を提供することだけです。

于 2012-11-02T21:04:13.597 に答える
1

この回答は、Dandre の回答と似ていますが、次の点が異なります。

  • 昨日は、秒ではなく暦時間に基づいて定義されます。
    • たとえば、次の場合です。
      • 投稿時間は2015/01/19 10:00:00 pm です
      • および現在の時刻は01:00:00 am 01/20/2015 です
    • フォーマットされた日付は次のように表示されます: 3 時間前ではなく、昨日

まず、フォーマットされた日付を返すメイン関数を書きましょう。

public String getStringFormattedDate(Context context, Date postDate){
    Calendar postCalendar = Calendar.getInstance();
    postCalendar.setTime(postDate);
    Calendar currentCalendar = Calendar.getInstance();

    long delta = Math.abs(currentCalendar.getTimeInMillis() - postCalendar .getTimeInMillis()) / 1000;

    //**yesterday**
    //This has to be checked first, otherwise, yesterday logic 
    //will be overridden by "seconds ago", "minutes ago", "hours ago"
    if(isYesterday(postCalendar , currentCalendar)){
        return context.getResources().getString(R.string.yesterday);
    }
    //seconds ago
    else if (delta < 60)
    {
        return context.getResources().getQuantityString(R.plurals.seconds, (int)delta, (int)delta);
    }
    //minutes ago
    else if (delta < 3600) // 60 * 60
    {
        delta /= 60.0; // convert seconds to minutes
        return context.getResources().getQuantityString(R.plurals.minutes, (int)delta, (int)delta);
    }
    //hours ago
    else if (delta < 86400) // 24 * 60 * 60
    {
        delta /= (60.0*60.0); // convert seconds to hours
        return context.getResources().getQuantityString(R.plurals.hours, (int)delta, (int)delta);
    }
    //older dates
    else{
       delta /= (60.0*60.0*24.0); // convert seconds to days
       return context.getResources().getString(R.string.time_ago, context.getResources().getQuantityString(R.plurals.days, (int) delta , (int) delta));
    }
}

isYesterday()postCalendar が現在のカレンダーと比較して昨日かどうかをチェックする関数:

//return true, if postCalendar is a day behind currentCalendar
private boolean isYesterday(Calendar postCalendar, Calendar currentCalendar){
    Calendar cloneCurrentCalendar = (Calendar) currentCalendar.clone();
    resetTime(cloneCurrentCalendar);

    Calendar clonePostCalendar = (Calendar) postCalendar.clone();
    resetTime(clonePostCalendar);
    clonePostCalendar.add(Calendar.DAY_OF_MONTH, 1);

    return (cloneCurrentCalendar.compareTo(clonePostCalendar) == 0);
}

resetTime()カレンダーの日付のみを比較する目的でカレンダー インスタンスをリセットする関数:

//set Time to 00:00:00
private void resetTime(Calendar calendar){
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
}
于 2015-10-22T17:41:14.673 に答える
0

回答のコードを少し編集しました。long と int の除算が原因で、「0 時間前」の文字列を取得しました。さらに、getCurrentTime()答えにメソッドが欠けていたので、 を使用しSystem.getCurrentTimeInMillis()ました。これが問題を解決する私の修正0 hour agoです。

public static String getTimeAgo(long time, Context context) {
    if (time < 1000000000000L) {
        // if timestamp given in seconds, convert to millis
        time *= 1000;
    }

    final long now = System.currentTimeMillis();
    if (time > now || time <= 0) return "";

    final Resources res = context.getResources();
    final long time_difference = now - time;

    if (time_difference < C._A_MINUTE)
        return res.getString(R.string.just_now);
    else if (time_difference < 50 * C._A_MINUTE)
        return res.getString(R.string.time_ago,
            res.getQuantityString(R.plurals.minutes, (int) time_difference / C._A_MINUTE, time_difference / C._A_MINUTE));
    else if (time_difference < 24 * C._AN_HOUR)
        return res.getString(R.string.time_ago,
            res.getQuantityString(R.plurals.hours, (int) Math.ceil((double)time_difference / C._AN_HOUR), time_difference / C._AN_HOUR));
    else if (time_difference < 48 * C._AN_HOUR)
        return res.getString(R.string.yesterday);
    else
        return res.getString(R.string.time_ago,
            res.getQuantityString(R.plurals.days, (int) Math.ceil((double)time_difference / C._A_DAY), time_difference / C._A_DAY));
}

C.java定数を保持する場所です。ここにあります:

public class C {
    /** One second (in milliseconds) */
    public static final int _A_SECOND = 1000;
    /** One minute (in milliseconds) */
    public static final int _A_MINUTE = 60 * _A_SECOND;
    /** One hour (in milliseconds) */
    public static final int _AN_HOUR = 60 * _A_MINUTE;
    /** One day (in milliseconds) */
    public static final int _A_DAY = 24 * _AN_HOUR;

他のファイル (plurals.xmlstrings.xml) は同じです。上記の回答をご覧ください。

于 2015-06-14T16:26:29.647 に答える