Подтвердить что ты не робот

"Время с/Аго" для Android/Java

Любые предложения по хорошей библиотеке для Android/Java для отображения времени с?

(например, 10 минут назад, 5 дней назад)

4b9b3361

Ответ 1

В приложении 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";
    }
}

Ответ 3

Из плагина 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>

Ответ 4

Вы можете использовать встроенный DateUtils класс с помощью методов getRelative...().

Ответ 5

Вы также можете использовать moment.js, например libray PrettyTime, что дополнительно дает вам переведенный контент. 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"

Ответ 6

Вы можете попробовать мою библиотеку Time4A, которая является версией Android для Time4J. Демо-версия:

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), включая локализованные правила множественного числа (важно для рабских языков или арабского) и три разных ширины текста:

На самом деле, я думаю, что это все, что мне нужно.

фил ф га га он хи хр хы хи ид это джа ка кк км кн ко

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

си скл кв ср ср св т е т ч т к у к у р у уз ви ж цу

Поддерживаются все единицы измерения от года до секунды (или даже миллис, микро, нанос для списочных форматов).

Чтобы преобразовать 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:

Более новая версия Time4A-4.4-2019a с зависимостью gradle

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

поддерживает 94 языка и теперь также включает относительные шаблоны, такие как "следующее воскресенье".

Ответ 7

Я проверил все ответы в этом сообщении, не смог получить правильный и отформатированный вывод из любого. наконец, нашел ответ, который ищет в этом сообщении, http://memorynotfound.com/calculate-relative-time-time-ago-java/

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class TimeAgo {

    public static final Map<String, Long> times = new LinkedHashMap<>();

    static {
        times.put("year", TimeUnit.DAYS.toMillis(365));
        times.put("month", TimeUnit.DAYS.toMillis(30));
        times.put("week", TimeUnit.DAYS.toMillis(7));
        times.put("day", TimeUnit.DAYS.toMillis(1));
        times.put("hour", TimeUnit.HOURS.toMillis(1));
        times.put("minute", TimeUnit.MINUTES.toMillis(1));
        times.put("second", TimeUnit.SECONDS.toMillis(1));
    }

    public static String toRelative(long duration, int maxLevel) {
        StringBuilder res = new StringBuilder();
        int level = 0;
        for (Map.Entry<String, Long> time : times.entrySet()){
            long timeDelta = duration / time.getValue();
            if (timeDelta > 0){
                res.append(timeDelta)
                        .append(" ")
                        .append(time.getKey())
                        .append(timeDelta > 1 ? "s" : "")
                        .append(", ");
                duration -= time.getValue() * timeDelta;
                level++;
            }
            if (level == maxLevel){
                break;
            }
        }
        if ("".equals(res.toString())) {
            return "0 seconds ago";
        } else {
            res.setLength(res.length() - 2);
            res.append(" ago");
            return res.toString();
        }
    }

    public static String toRelative(long duration) {
        return toRelative(duration, times.size());
    }

    public static String toRelative(Date start, Date end){
        assert start.after(end);
        return toRelative(end.getTime() - start.getTime());
    }

    public static String toRelative(Date start, Date end, int level){
        assert start.after(end);
        return toRelative(end.getTime() - start.getTime(), level);
    }
}

Ответ 8

Вы можете использовать модуль 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(новая дата(). getTime());

Ответ 9

Если вам нужно "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";
    }
}

Ответ 10

Введите только номер метки времени и ответьте на свой вопрос. вывод поступает согласно вашему местоположению.

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);
}