Human readable time ago

<?php

echo ago(time() - 3452); // will return: 58 минут назад

function ago($timestamp) {
    $difference = time() - $timestamp;
    $periods = array(
        array('секунду', 'секурнды', 'секунд'),
        array('минуту', 'минуты', 'минут'),
        array('час', 'часа', 'часов'),
        array('день', 'дня', 'дней'),
        array('неделю', 'недели', 'недель'),
        array('месяц', 'месяца', 'месяцев'),
        array('год', 'года', 'лет'),
        array('десятилетие', 'десятилетий', 'десятилетий'),
    );

    $lengths = array('60','60','24','7','4.35','12','10');

    for($j = 0; $difference >= $lengths[$j]; $j++)
        $difference /= $lengths[$j];

    $difference = round($difference);

    $cases = array (2, 0, 1, 1, 1, 2);
    $text = $periods[$j][ ($difference%100>4 && $difference%100<20)? 2: $cases[min($difference%10, 5)] ];
    return $difference.' '.$text . ' назад';
}

Реализация на .net

public static string timeAgo(DateTime date)
{
    if (date == DateTime.Now) return "только что";

    double difference = Math.Abs( (DateTime.Now - date).TotalSeconds );

    List<string[]> periods = new List<string[]>();
    periods.Add(new string[] {"секунду", "секурнды", "секунд" });
    periods.Add(new string[] {"минуту", "минуты", "минут" });
    periods.Add(new string[] {"час", "часа", "часов" });
    periods.Add(new string[] {"день", "дня", "дней" });
    periods.Add(new string[] {"неделю", "недели", "недель" });
    periods.Add(new string[] {"месяц", "месяца", "месяцев" });
    periods.Add(new string[] {"год", "года", "лет" });
    periods.Add(new string[] { "десятилетие", "десятилетий", "десятилетий" });

    double[] lengths = new double[] { 60, 60, 24, 7, 4.35, 12, 10 };
    int[] cases = new int[] { 2, 0, 1, 1, 1, 2 };

    int j = 0;
    for (j = 0; difference >= lengths[j]; j++)
    {
        difference = difference / lengths[j];
    }

    difference = Math.Round(difference);

    string text = periods[j][ ( difference%100 > 4 && difference%100 < 20 ) ? 2 : cases[(int)Math.Min(difference%10, 5)] ];

    string prefix = date > DateTime.Now ? "через " : string.Empty;
    string suffix = date < DateTime.Now ? " назад" : string.Empty;

    return string.Format("{0}{1} {2}{3}", prefix, difference, text, suffix);
}

Реализация на javascript

function ago(date) {
  var difference = (new Date().getTime() - date.getTime()) / 1000
  var periods = [
    ['секунду', 'секурнды', 'секунд'],
    ['минуту', 'минуты', 'минут'],
    ['час', 'часа', 'часов'],
    ['день', 'дня', 'дней'],
    ['неделю', 'недели', 'недель'],
    ['месяц', 'месяца', 'месяцев'],
    ['год', 'года', 'лет'],
    ['десятилетие', 'десятилетий', 'десятилетий']
  ]

  var lengths = [60, 60, 24, 7, 4.35, 12, 10]

  for (var i = 0; difference >= lengths[i]; i++) {
    difference = difference / lengths[i]
  }

  difference = Math.round(difference)

  var cases = [2, 0, 1, 1, 1, 2]
  var text = periods[i][difference % 100 > 4 && difference % 100 < 20 ? 2 : cases[Math.min(difference % 10, 5)]]
  return difference + ' ' + text + ' назад'
}