Дата в String в формате "social"

Я пытаюсь добиться, давайте скажем "формат социальной даты. У меня уже есть решение, но похоже, что лучше быть существующим. Почему социальный и что я имею в виду:

Если мы посмотрим на метки времени в Facebook, мы можем различать следующие варианты:

  • X секунд назад
  • X минут назад
  • X часов назад
  • Вчера в 11:07
  • Пятница в 9:36 вечера
  • 5 мая в 17:00.
  • 20 ноября в 21:05, 2012

Я сделал следующий визуальный график для лучшего объяснения: enter image description here
Например:
Если текущее время: 5:33 pm, 20 секунд Среда
Социальный пост произошел между: 00:00 по вторникам и - 5:33 вечера, 20 секунд Вторник, то формат даты должен быть следующим: Вчера в 11:07.

Решение У меня:
Я проверяю каждую опцию (7 в счетчике) и возвращаю строку "social" date.

Вот как я могу проверить вариант 1:

Date postDate = getPostDate();
Date nowDate = getNowDate();

// check passed seconds
int passedSeconds = getPassedSeconds(postDate, nowDate);
if (passedSeconds < 60)
{
    return passedSeconds + " seconds ago";
} 

Вот как я могу проверить вариант 4:

// check yesterday
Date startYesterdayDate = getZeroDayBeforeDays(nowDate, 1);
int compare = compare(startYesterdayDate, postDate);

// if postDate comes after startYesterdayDate
if (compare == -1)
{
    return "Yesterday at " + getString(postDate, "HH:mma");
}

Я проверяю другие параметры таким же образом.


Некоторые методы, которые я использую в следующих операциях if:

public static String getString(Date date, String format)
{
    Format formatter = new SimpleDateFormat(format, Locale.US);
    String s = formatter.format(date);
    return s;
}

/**
 * For example: today - 1 day
 * 
 * @param date
 * @param numOfMinusDays
 * @return
 */
public static Date getDateMinusDays(Date date, int numOfMinusDays)
{
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.DAY_OF_MONTH, (0 - numOfMinusDays));
    return calendar.getTime();
}

/**
 * Get the day before today at 00:00 am.<br>
 * Means, if passed day = <b>Nov 5 13:04</b>, then returned date will be = <b>Nov 4 00:00</b> for days = 1
 * 
 * @param date
 * @param days Numner of days to reduce
 * @return
 */
public static Date getZeroDayBeforeDays(Date date, int days)
{
    Calendar yesterday = Calendar.getInstance();
    yesterday.setTime(getDateMinusDays(date, days));
    yesterday.set(Calendar.HOUR_OF_DAY, 0);
    yesterday.set(Calendar.MINUTE, 0);
    yesterday.set(Calendar.SECOND, 0);
    yesterday.set(Calendar.MILLISECOND, 1);
    return yesterday.getTime();
}


Наконец, мои вопросы:

  • Есть ли лучший способ преобразования разницы между двумя датами в "социальный" формат строки? Как я уже сказал, я чувствую, что можно использовать другой способ, например, расширение объекта DateFormat, но я не уверен.

  • Как локализовать строки, такие как "Вчера" и 'в', так что разные настройки Local изменят строки на подходящий язык?


Извините за такой длинный вопрос, но я не мог найти более короткий способ объяснить необходимость.
Благодаря

Ответ 1

Существует уже одна реализованная библиотека для этого, если вы не хотите изобретать колесо

См. PrettyTime с поддержкой локализации

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
//prints: "right now"

System.out.println(p.format(new Date(1000*60*10)));
//prints: "10 minutes from now"