миллисекунды в минуты, часы, дни, года и т.д

Есть определенная переменная, которая хранит в себе количество миллисекунд.

Есть строка, в которой может быть Y - год (не високосный), M - месяц (30 дней), w - неделя, d - день, h - час, m - минута, s - секунда, S - миллисекунда.

Строка может быть, например, формата "Y-d-m". Такая строка должна вернуть вместо букв числа:

  • количество лет,
  • количество дней, которых не хватило до 1 года,
  • количество минут, которых не хватило до 1 дня.

Или "Y-M-d-h-s" должен вернуть:

  • кол-во лет,
  • кол-во месяцев, которых не хватило до 1 года,
  • количество дней, которых не хватило до 1 месяца,
  • количество часов, не хвативших до 1 дня,
  • количество секунд, не хвативших до часа.

Ну и все в таком духе.

Можно ли такое сделать с применение какого-либо встроенного или уже готового класса или мне нужно иди самому писать такую штуку?


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

Автор решения: Vadik

Пусть у вас есть класс с константами, которые показывают количество миллисекунд в секунде, минуте и так далее. И соответствие символов паттерна с количеством миллисекунд:

class Constants {
    static final long SECOND = 1000;
    static final long MINUTE = SECOND * 60;
    static final long HOUR = MINUTE * 60;
    static final long DAY = HOUR * 24;
    static final long MONTH = DAY * 30;
    static final long YEAR = DAY * 365;
    static final Map<Character, Long> MAP = new HashMap<>();
    static {
        MAP.put('s', SECOND);
        MAP.put('m', MINUTE);
        MAP.put('h', HOUR);
        MAP.put('d', DAY);
        MAP.put('M', MONTH);
        MAP.put('Y', YEAR);
    }
}

Например, чтобы реализовать форматирование по паттерну Y-d-m, можно написать следующий код:

long millis = 31622460000L;
long Y = millis / YEAR;
long d = millis % YEAR / DAY;
long m = millis % YEAR % DAY / MINUTE;
String.format("%d-%d-%d", Y, d, m); // => "1-1-1"

А чтобы реализовать форматирование по паттерну Y-M-d-h-s, получается следующее:

long millis = 34218001000L;
long Y = millis / YEAR;
long M = millis % YEAR / MONTH;
long d = millis % YEAR % MONTH / DAY;
long h = millis % YEAR % MONTH % DAY / HOUR;
long s = millis % YEAR % MONTH % DAY % HOUR / SECOND;
String.format("%d-%d-%d-%d-%d", Y, M, d, h, s); // => "1-1-1-1-1"

Обобщая код выше, можно написать статический метод format, который будет форматировать по произвольному паттерну:

static String format(String pattern, long millis) {
    StringBuilder output = new StringBuilder();
    long remainder = millis;
    for (char p : pattern.toCharArray()) {
        if (p == '-') continue;
        long value = MAP.get(p);
        output.append('-');
        output.append(remainder / value);
        remainder %= value;
    }
    return output.substring(1);
}

Пользоваться так:

format("Y-d-m", 31622460000L); // => "1-1-1"
format("Y-M-d-h-s", 34218001000L); // => "1-1-1-1-1"

Для краткости в моей реализации пропущены недели и миллисекунды. При необходимости их можно добавить в класс с константами.

→ Ссылка