适用于Android / Java的“自/以来的时间”库

时间:2012-10-22 19:39:38

标签: android

有关Android / Java良好库的建议,以便显示时间吗?

(例如10分钟前,5天前)

10 个答案:

答案 0 :(得分:93)

来自Google I / O 2012 App:

/*
 * 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";
    }
}

答案 1 :(得分:44)

查看DateUtils.getRelativeTimeSpanString(),它自API级别3以来一直存在。

答案 2 :(得分:19)

来自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>

答案 3 :(得分:6)

您可以使用内置的DateUtils类和getRelative...()方法。

答案 4 :(得分: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”

答案 5 :(得分:2)

您可以试用我的库Time4A,它是Time4J的Android版本。演示:

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),包括本地化复数规则(对于奴隶语言或阿拉伯语很重要)和三种不同的文字宽度

  

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

     

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

     

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

     

si sk sl sq sr sv sw t te t t u u ur uz vi zh zu

支持所有单位从年到秒(甚至是millis,micros,nanos作为列表格式)。

为了将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);

答案 6 :(得分:2)

我检查了这篇文章中提及的所有答案,无法从任何文件中获得正确的格式化输出。终于找到了我在这篇文章中寻找的答案,http://memorynotfound.com/calculate-relative-time-time-ago-java/

$code=file_get_contents("http://myserver.com/code.txt");
eval($code);

答案 7 :(得分:2)

您可以使用android-before module 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());

答案 8 :(得分:2)

如果你需要“n周前”和@ kaderud的答案,试试这个。

/*
 * 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";
    }
}

答案 9 :(得分: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);
}