Перенести python код в javascript

cases = (2, 0, 1, 1, 1, 2)

intervals = (
    (31536000, 'год', 'года', 'лет'),
    (2592000, 'месяц', 'месяца', 'месяцев'),
    (86400, 'день', 'дня', 'дней'),
    (3600, 'час', 'часа', 'часов'), 
    (60, 'минуту', 'минуты', 'минут'),
    (1, 'секунду', 'секунды', 'секунд'),)

def plural_form(n: int, v: (list, tuple)):
    """Функция возвращает число и просклонённое слово после него

    Аргументы:
    :param n: число
    :param v: варианты слова в формате (для 1, для 2, для 5)

    Пример:
    plural_form(difference.days, ("день", "дня", "дней"))

    :return: Число и просклонённое слово после него
    """

    return form(n) + f"  {v[2 if (4 < n % 100 < 20) else cases[min(n % 10, 5)]]}"

def form(args):
    #Функция форматирует числа в виде ("10000" > "10.000")
    return "{:,}".format(args).replace(",", ".")

def show_time(seconds, granularity=5):
    """Функция возвращает цифровое время с использованием utctimestamp"""
    result = []

    seconds = int(seconds)

    for count, *name in intervals:
        value = seconds // count
        if value:
            seconds -= value * count
            result.append(plural_form(value, name))

    return '. '.join(result[:granularity]) if result else '0 сек'

Есть такая функция show_time помогите перенести данный код в javascript моя попытка встала на этом:

var cases = [2, 0, 1, 1, 1, 2];
var intervals = [
                  [31536000, ['год', 'года', 'лет']],
                  [2592000, ['месяц', 'месяца', 'месяцев']],
                  [86400, ['день', 'дня', 'дней']],
                  [3600, ['час', 'часа', 'часов']],
                  [60, ['минуту', 'минуты', 'минут']],
                  [1, ['секунду', 'секунды', 'секунд']]
                ];

function plural_form(n, v){
  return n + ` ${v[(4 < n % 100 < 20) ? 2 : cases[Math.min(n % 10, 5)]]}`;
}

function show_time(utctime, granularity=4){

  let results = [];

  let seconds = parseInt(utctime);

  for (var i = 0; i < intervals.lenght; i++) {

    let value = Math.floor(seconds / intervals[i][0]);

    if (value){
      seconds -= value * intervals[i][0]
      results.push(plural_form(value, intervals[i][1]))
    }

  return results.slices(0, granularity).join('. ');

  }

}

console.log(show_time(1611584));

Ответы (1 шт):

Автор решения: OPTIMUS PRIME
def form(args):
    #Функция форматирует числа в виде ("10000" > "10.000")
    return "{:,}".format(args).replace(",", ".")

function format(n) {
  return Intl.NumberFormat('de-DE').format(n);
}

def plural_form(n: int, v: (list, tuple)):
    return form(n) + f" {v[2 if (4 < n % 100 < 20) else cases[min(n % 10, 5)]]}"

4 < n % 100 < 20 — В JS это всегда дает true, потому что сначала выполняется 4 < n % 100, а потом возвращенный оттуда true / false сравнивается с 20 как 0 < 20 или 1 < 20. Такое записывают через «and», 4 < n % 100 && n % 100 < 20

function plural_form(n, values) {
  let index = (4 < n % 100 && n % 100 < 20) ? 2 : cases[Math.min(n % 10, 5)];

  return format(n) + ` ${values[index]}`;
}

def show_time(seconds, granularity = 5):
    result = []

    seconds = int(seconds)

    for count, *name in intervals:
        value = seconds // count
        if value:
            seconds -= value * count
            result.append(plural_form(value, name))

    return '. '.join(result[:granularity]) if result else '0 сек'

for count, *name in intervalsДеструктурирующее присваивание в JS

Всё вместе:

let cases = [2, 0, 1, 1, 1, 2];
let intervals = [
  [31536000, 'год', 'года', 'лет'],
  [2592000, 'месяц', 'месяца', 'месяцев'],
  [86400, 'день', 'дня', 'дней'],
  [3600, 'час', 'часа', 'часов'],
  [60, 'минуту', 'минуты', 'минут'],
  [1, 'секунду', 'секунды', 'секунд'],
];

function plural_form(n, values) {
  let index = (4 < n % 100 && n % 100 < 20) ? 2 : cases[Math.min(n % 10, 5)];

  return format(n) + ` ${values[index]}`;
}

function format(n) {
  return Intl.NumberFormat('de-DE').format(n);
}

function show_time(seconds, granularity = 4) {
  let result = [];
  seconds = parseInt(seconds);

  intervals.forEach(([count, ...names]) => {
    let value = seconds / count | 0; //  |0 ← Отбрасывает дробную часть
    if (value) {
      seconds -= value * count;
      result.push(plural_form(value, names));
    }
  });

  return result.slice(0, granularity).join('. ') || '0 сек';
  // В питоне «or», в JS → ||
  // Если result пустой, первое выражение дает "", берется '0 сек';
}

console.log( show_time("123456789") );


Функция считает с точностью до секунд, но не учитывает високосный год, и что не во всех месяцах по 30 дней. Это не косяк?

→ Ссылка