56

それ以降の時間を表示するための Android/Java 用の優れたライブラリの提案はありますか?

(例: 10 分前、5 日前)

4

10 に答える 10

102

Google I/O 2012 アプリから:

/*
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

private static final int SECOND_MILLIS = 1000;
private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
private static final int DAY_MILLIS = 24 * HOUR_MILLIS;


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";
    }
}
于 2012-10-22T19:45:33.353 に答える
49

DateUtils.getRelativeTimeSpanString()を確認してください。これは API レベル 3 から存在しています。

于 2012-10-22T19:43:17.050 に答える
24

jquery timeago プラグインから

これにより、上記の回答よりも多くのオプションと形式が提供されます。

public static Date currentDate() {
    Calendar calendar = Calendar.getInstance();
    return calendar.getTime();
}

public static String getTimeAgo(Date date, Context ctx) {

    if(date == null) {
        return null;
    }

    long time = date.getTime();

    Date curDate = currentDate();
    long now = curDate.getTime();
    if (time > now || time <= 0) {
        return null;
    }

    int dim = getTimeDistanceInMinutes(time);

    String timeAgo = null;

    if (dim == 0) {
        timeAgo = ctx.getResources().getString(R.string.date_util_term_less) + " " +  ctx.getResources().getString(R.string.date_util_term_a) + " " + ctx.getResources().getString(R.string.date_util_unit_minute);
    } else if (dim == 1) {
        return "1 " + ctx.getResources().getString(R.string.date_util_unit_minute);
    } else if (dim >= 2 && dim <= 44) {
        timeAgo = dim + " " + ctx.getResources().getString(R.string.date_util_unit_minutes);
    } else if (dim >= 45 && dim <= 89) {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_about) + " "+ctx.getResources().getString(R.string.date_util_term_an)+ " " + ctx.getResources().getString(R.string.date_util_unit_hour);
    } else if (dim >= 90 && dim <= 1439) {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_about) + " " + (Math.round(dim / 60)) + " " + ctx.getResources().getString(R.string.date_util_unit_hours);
    } else if (dim >= 1440 && dim <= 2519) {
        timeAgo = "1 " + ctx.getResources().getString(R.string.date_util_unit_day);
    } else if (dim >= 2520 && dim <= 43199) {
        timeAgo = (Math.round(dim / 1440)) + " " + ctx.getResources().getString(R.string.date_util_unit_days);
    } else if (dim >= 43200 && dim <= 86399) {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_about) + " "+ctx.getResources().getString(R.string.date_util_term_a)+ " " + ctx.getResources().getString(R.string.date_util_unit_month);
    } else if (dim >= 86400 && dim <= 525599) {
        timeAgo = (Math.round(dim / 43200)) + " " + ctx.getResources().getString(R.string.date_util_unit_months);
    } else if (dim >= 525600 && dim <= 655199) {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_about) + " "+ctx.getResources().getString(R.string.date_util_term_a)+ " " + ctx.getResources().getString(R.string.date_util_unit_year);
    } else if (dim >= 655200 && dim <= 914399) {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_over) + " "+ctx.getResources().getString(R.string.date_util_term_a)+ " " + ctx.getResources().getString(R.string.date_util_unit_year);
    } else if (dim >= 914400 && dim <= 1051199) {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_almost) + " 2 " + ctx.getResources().getString(R.string.date_util_unit_years);
    } else {
        timeAgo = ctx.getResources().getString(R.string.date_util_prefix_about) + " " + (Math.round(dim / 525600)) + " " + ctx.getResources().getString(R.string.date_util_unit_years);
    }

    return timeAgo + " " + ctx.getResources().getString(R.string.date_util_suffix);
}

private static int getTimeDistanceInMinutes(long time) {
      long timeDistance = currentDate().getTime() - time;
      return Math.round((Math.abs(timeDistance) / 1000) / 60);
}

string.xml ファイルに次の文字列を追加します

<!-- Date Util -->
<string name="date_util_term_less">less than</string>
<string name="date_util_term_a">a</string>
<string name="date_util_term_an">an</string>

<string name="date_util_unit_second">second</string>
<string name="date_util_unit_seconds">seconds</string>
<string name="date_util_unit_minute">minute</string>
<string name="date_util_unit_minutes">minutes</string>
<string name="date_util_unit_hour">hour</string>
<string name="date_util_unit_hours">hours</string>
<string name="date_util_unit_day">day</string>
<string name="date_util_unit_days">days</string>
<string name="date_util_unit_month">month</string>
<string name="date_util_unit_months">months</string>
<string name="date_util_unit_year">year</string>
<string name="date_util_unit_years">years</string>

<string name="date_util_prefix_lt">less than a</string>
<string name="date_util_prefix_about">about</string>
<string name="date_util_prefix_over">over</string>
<string name="date_util_prefix_almost">almost</string>

<string name="date_util_suffix">ago</string>
于 2014-02-11T08:15:29.687 に答える
7

メソッドで組み込みのDateUtilsクラスを使用できますgetRelative...()

于 2012-10-22T19:43:02.063 に答える
4

libray PrettyTime のような moment.js を使用することもできます。これにより、さらに翻訳されたコンテンツが得られます。http://www.ocpsoft.org/prettytime/

簡単な例:

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
//prints: “moments from now”

System.out.println(p.format(new Date(System.currentTimeMillis() + 1000*60*10)));
//prints: “10 minutes from now”
于 2015-10-16T17:24:33.883 に答える
4

@kaderudの回答で「n週間前」が必要な場合は、これを試してください。

/*
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

private static final int SECOND_MILLIS = 1000;
private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
private static final int DAY_MILLIS = 24 * HOUR_MILLIS;
private static final int WEEK_MILLIS = 7 * DAY_MILLIS;

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

    long now = System.currentTimeMillis();
    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 if (diff < 7 * DAY_MILLIS) {
        return diff / DAY_MILLIS + " days ago";
    } else if (diff < 2 * WEEK_MILLIS) {
        return "a week ago";
    } else {
        return diff / WEEK_MILLIS + " weeks ago";
    }
}
于 2017-05-03T11:07:25.597 に答える
3

Time4Jの Android バージョンである私のライブラリTime4Aを試すことができます。デモ:

Locale uk = Locale.UK;
TZID paris = EUROPE.PARIS; 
ChronoFormatter<Moment> f = 
    ChronoFormatter.ofMomentPattern("d. MMMM uuuu h:mm B", PatternType.CLDR, uk, paris);
PrettyTime pt = PrettyTime.of(uk);

// => examples for relative formats
Moment moment = f.parse("4. January 2016 5:45 in the afternoon");
System.out.println(pt.printRelative(moment, paris)); 
// output: 1 week ago

Moment now = SystemClock.currentMoment();
System.out.println(pt.printRelative(now, paris)); 
// output: now

Moment shortTimeAgo = now.minus(15, SI.SECONDS);
System.out.println(pt.printRelative(shortTimeAgo, paris)); 
// output: 15 seconds ago

TimeUnit precision = TimeUnit.DAYS;
System.out.println(pt.printRelative(shortTimeAgo, Timezone.of(paris), precision)); 
// output: today

// => examples for list formats     
Duration<?> duration = // this way for getting duration requires extra range-module
    MomentInterval.between(moment, now).getNominalDuration(
      Timezone.of(paris), 
      DAYS, HOURS, MINUTES);

System.out.println(pt.print(duration)); 
// output: 11 days, 1 hour and 26 minutes

System.out.println(pt.print(duration, TextWidth.ABBREVIATED)); 
// output: 11 days, 1 hr, 26 min

実際には、72 の言語(v3.18-2016c) がサポートされており、ローカライズされた複数形の規則(スラブ語またはアラビア語で重要) と3 つの異なるテキスト幅が含まれています。

af am ar az be bg bn bs ca cs da de el en es et fa fi

fil fr ga gu he hi hr hu hy id is it ja ka kk km kn ko

ky lo lt lv mk mn mr ms my nb ne nl nn pa pl pt ro ru

si sk sl sq sr sv sw ta te th tk tr uk ur uz vi zh zu

年から秒までのすべての単位(またはリスト形式のミリ、マイクロ、ナノ) がサポートされています。

java.util.Dateタイムスタンプ (Unix エポック以降のミリ秒を表す) を time4j 型との間で変換または変換するには、次を使用できます。

java.util.Date d = TemporalType.JAVA_UTIL_DATE.from(moment);
long epochMillis = TemporalType.MILLIS_SINCE_UNIX.from(moment);
Moment m1 = TemporalType.JAVA_UTIL_DATE.translate(d);
Moment m2 = TemporalType.MILLIS_SINCE_UNIX.translate(epochMillis);

2019-06-06 からの更新:

gradle-dependency を使用した新しいバージョンの Time4A-4.4-2019a

dependencies {
    implementation group: 'net.time4j', name: 'time4j-android', version: '4.4-2019a'
}

94 の言語をサポートし、「次の日曜日」などの相対パターンも含まれるようになりました。

于 2016-01-15T18:41:46.557 に答える
2

android-ago モジュールを使用できますhttps://github.com/curioustechizen/android-ago

XML にコンポーネントを追加する

<com.github.curioustechizen.ago.RelativeTimeTextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:relative_time_prefix="Completed "
android:layout_marginTop="@dimen/margin_primary" />

時間参照ビュー コードを設定する

RelativeTimeTextView v = (RelativeTimeTextView)findViewById(R.id.timestamp); //Or just use Butterknife!

v.setReferenceTime(new Date().getTime());

于 2016-08-05T08:17:59.483 に答える
1

タイムスタンプ番号を入力するだけで、質問の回答が得られます。出力はあなたの場所に従って来ます。

public static String getTimeAgo(long timestamp) {

    Calendar cal = Calendar.getInstance();
    TimeZone tz = cal.getTimeZone();//get your local time zone.
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
    sdf.setTimeZone(tz);//set time zone.
    String localTime = sdf.format(new Date(timestamp * 1000));
    Date date = new Date();
    try {
        date = sdf.parse(localTime);//get local date
    } catch (ParseException e) {
        e.printStackTrace();
    }

    if(date == null) {
        return null;
    }

    long time = date.getTime();

    Date curDate = currentDate();
    long now = curDate.getTime();
    if (time > now || time <= 0) {
        return null;
    }

    int timeDIM = getTimeDistanceInMinutes(time);

    String timeAgo = null;

    if (timeDIM == 0) {
        timeAgo = "less than a minute";
    } else if (timeDIM == 1) {
        return "1 minute";
    } else if (timeDIM >= 2 && timeDIM <= 44) {
        timeAgo = timeDIM + " minutes";
    } else if (timeDIM >= 45 && timeDIM <= 89) {
        timeAgo = "about an hour";
    } else if (timeDIM >= 90 && timeDIM <= 1439) {
        timeAgo = "about " + (Math.round(timeDIM / 60)) + " hours";
    } else if (timeDIM >= 1440 && timeDIM <= 2519) {
        timeAgo = "1 day";
    } else if (timeDIM >= 2520 && timeDIM <= 43199) {
        timeAgo = (Math.round(timeDIM / 1440)) + " days";
    } else if (timeDIM >= 43200 && timeDIM <= 86399) {
        timeAgo = "about a month";
    } else if (timeDIM >= 86400 && timeDIM <= 525599) {
        timeAgo = (Math.round(timeDIM / 43200)) + " months";
    } else if (timeDIM >= 525600 && timeDIM <= 655199) {
        timeAgo = "about a year";
    } else if (timeDIM >= 655200 && timeDIM <= 914399) {
        timeAgo = "over a year";
    } else if (timeDIM >= 914400 && timeDIM <= 1051199) {
        timeAgo = "almost 2 years";
    } else {
        timeAgo = "about " + (Math.round(timeDIM / 525600)) + " years";
    }

    return timeAgo + " ago";
}

public static Date currentDate() {
    Calendar calendar = Calendar.getInstance();
    return calendar.getTime();
}

private static int getTimeDistanceInMinutes(long time) {
    long timeDistance = currentDate().getTime() - time;
    return Math.round((Math.abs(timeDistance) / 1000) / 60);
}
于 2016-03-24T18:30:05.757 に答える