Как перевести строку “1d 2h 3m 4s” в миллисекунды?

216
19 апреля 2018, 13:01

Как перевести строку в миллисекунды?

Например строчка 1s => 1000ms, а 1m => 60000ms, а если 5s 1m или 1m 5s => 65000ms

Думаю надо переводить строку в массив, а потом проходиться по значениям и записывать в переменную миллисекунды, но не знаю как сделать :(

Answer 1

Можно воспользоваться методом Duration.parse(), класса java.time.Duration, только нужно предварительно подготовить строку, убрав пробелы, перегнав всё в верхний регистр и поставив символ T после числа дней:

String str = "1d 2h 3m 4s";
String durationStr = "P" + str
    .replace("d ", "dt")
    .replace(" ", "").toUpperCase();
// durationStr: P1DT2H3M4S
Duration duration = Duration.parse(durationStr);
System.out.println(duration.toMillis());
// результат: 93784000

Как уже сказали в комментариях - да, этот вариант не подразумевает другой порядок. Чтобы можно было менять порядок, можно доработать решение, например, так:

String str = "1d 2h 4s 3m";
Pattern pattern = Pattern.compile("(\\d+)([dhms])");
Matcher matcher = pattern.matcher(str);
HashMap<String, Long> map = new HashMap<>();
while(matcher.find()) {
    map.put(
        matcher.group(2),
        Long.parseLong(matcher.group(1)) + map.getOrDefault(matcher.group(2), 0L)
    );
}
String durationStr = "pdthms".chars()
    .mapToObj(c -> "" + ((char) c))
    .map(c -> "" + (map.containsKey(c) ? map.get(c) : "") + c)
    .map(String::toUpperCase)
    .collect(Collectors.joining());
Duration duration = Duration.parse(durationStr);
System.out.println(duration.toMillis());
Answer 2

Для вашего формата строки метод ниже будет универсальным. Постарайтесь не глупо скопировать, а ещё лучше — использовать другой способ, он тут явно не один.

/**
 * @param  str Исходная строка в формате `1d 2h 3m 4s`.
 * @return     Подсчитанное количество миллисекунд.
 */
private long calculateMillisecondsCount(String str) {
    String[] words = str.split(" ");
    long totalMillisecondsCount = 0;
    for (String word : words) {
        String literal = word.substring(word.length() - 1);
        TimeUnit unit;
        long count;
        switch (literal) {
            case "d": {
                unit = TimeUnit.DAYS;
                break;
            }
            case "h": {
                unit = TimeUnit.HOURS;
                break;
            }
            case "m": {
                unit = TimeUnit.MINUTES;
                break;
            }
            case "s": {
                unit = TimeUnit.SECONDS;
                break;
            }
            default:
                throw new UnsupportedOperationException();
        }
        count = Integer.parseInt(word.substring(0, word.indexOf(literal)));
        totalMillisecondsCount += TimeUnit.MILLISECONDS.convert(count, unit);
    }
    return totalMillisecondsCount;
}
READ ALSO
Объединение sql запросов в один класс JDBC

Объединение sql запросов в один класс JDBC

Для подключения к бд и работы с ней использую две библиотеки commons dbutils и commons dbcp2 (пул подключений к бд)

227
Планировщик задач на Java

Планировщик задач на Java

Здравствуйте! Нужно создать "Планировщик задач на Java"Мы с другом надумали:

455
Проблема с памятью в приложении java на centOS

Проблема с памятью в приложении java на centOS

Добрый день! Такая проблема: Есть spring-boot(15

220
Как сделать удаление смахиванием в android

Как сделать удаление смахиванием в android

Есть какая-то строка, как сделать анимацию смахивания, чтобы оно уезжало влево и удалялось (функционал удаления есть, но просто на кнопке)?

256