是否有一个java库可以将描述时间度量的字符串(例如“1d 1m 1s”)转换为毫秒?

时间:2020-12-16 00:15:46

When setting issue estimates in JIRA, you can enter a string like "1d 2h 30m" and JIRA will translate this (I'm assuming) into a corresponding number of milliseconds.

在JIRA中设置问题评估时,您可以输入一个字符串,比如“1d2h30m”,JIRA将这个(我假设)转换成相应的毫秒数。

Is there an available Java library that does this?

是否有一个可用的Java库可以做到这一点?

I'm using a Spring managed bean that takes a property indicating how often a directory ought to be purged, and I'd like to allow the configuration to take a human-readable string rather than an explicit number of milliseconds.

我使用的是Spring管理的bean,它获取一个属性,该属性指示一个目录应该被清除的频率,并且我希望允许配置使用人类可读的字符串,而不是显式的毫秒数。

Alternatively, if there's a better approach I'm not thinking of, I'd love to hear it.

或者,如果有更好的方法,我没有考虑,我很乐意听到。

6 个解决方案

#1


6  

The parser is not too complex:

解析器不太复杂:

public static long parse(String input) {
   long result = 0;
   String number = "";
   for (int i = 0; i < input.length(); i++) {
     char c = input.charAt(i);
     if (Character.isDigit(c)) { 
       number += c; 
     } else if (Character.isLetter(c) && !number.isEmpty()) {
       result += convert(Integer.parseInt(number), c);
       number = "";
     }
   }
   return result;
}

private static long convert(int value, char unit) {
  switch(unit) {
    case 'd' : return value * 1000*60*60*24;
    case 'h' : return value * 1000*60*60;         
    case 'm' : return value * 1000*60;
    case 's' : return value * 1000;
  }
  return 0;
}

The code is pretty fault tolerant, it just ignores almost anything it can't decode (and it ignores any whitspace, so it accepts "1d 1s", "1s 1d", "1d20m300s" and so on).

代码是相当容错的,它忽略了几乎任何它无法解码的东西(它忽略了任何空白,所以它接受了“1d 1s”、“1s 1d”、“1d20m300s”等等)。

#2


3  

Here's another solution, this one's configurable:

这是另一个解决方案,这个是可配置的:

public class TimeReader{

    private final Map<String, Long> units = new HashMap<String, Long>();

    private static final String UNIT_PATTERN = "\\w+";
    private static final Pattern ITEM_PATTERN = Pattern.compile("(\\d+)\\s*("
        + UNIT_PATTERN + ")");

    /**
     * Add a new time unit.
     * 
     * @param unit
     *            the unit, e.g. "s"
     * @param value
     *            the unit's modifier value (multiplier from milliseconds, e.g.
     *            1000)
     * @return self reference for chaining
     */
    public TimeReader addUnit(final String unit, final long value){
        if(value < 0 || !unit.matches(UNIT_PATTERN)){
            throw new IllegalArgumentException();
        }
        units.put(unit, Long.valueOf(value));
        return this;
    }

    /**
     * Parse a string using the defined units.
     * 
     * @return the resulting number of milliseconds
     */
    public long parse(final String input){
        long value = 0l;
        final Matcher matcher = ITEM_PATTERN.matcher(input);
        while(matcher.find()){
            final long modifier = Long.parseLong(matcher.group(1));
            final String unit = matcher.group(2);
            if(!units.containsKey(unit)){
                throw new IllegalArgumentException("Unrecognized token: "
                    + unit);
            }
            value += units.get(unit).longValue() * modifier;
        }
        return value;
    }

}

Sample Usage:

示例用法:

public static void main(final String[] args){
    final TimeReader timeReader =
        new TimeReader()
            .addUnit("h", 3600000l)
            .addUnit("m", 60000l)
            .addUnit("s", 1000l);

    System.out.println(timeReader.parse("3h, 2m   25  s"));
}

Output:

输出:

10945000

10945000

#3


1  

Take a look at joda-time's PeriodConverter. I have never used this part of the joda-time library myself, but it looks like it does what you need.

看看joda-time的周期转换器。我自己从来没有使用过这部分的joda-time库,但是它看起来就像您所需要的那样。

In general, for date/time stuff, look at joda-time first :)

一般来说,对于日期/时间的东西,先看一下joda-time:)

#4


0  

As far as I know, no. I believe you would have to convert those numbers yourself into Calendar (GregorianCalendar) and then from there you can proceed to get the milliseconds, which you probably already know which is why you posted this for the hope of a better answer.

据我所知,没有。我相信你必须把这些数字转换成日历(GregorianCalendar)然后从那里你可以得到毫秒,你可能已经知道这就是为什么你把它寄给了希望更好的答案。

My vote: If no one else can find one perhaps now is a good time to start one yourself and contribute it to the community. :)

我的投票:如果没有人能找到一个人,也许现在是一个开始自己并为社区贡献自己的好时机。:)

#5


0  

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest {
    public static void main(String[] args) {
        DateFormat df = new SimpleDateFormat("dd'd' HH'h' mm'm'");
        try {
            Date d = df.parse("1d 2h 30m");
            System.out.println(d.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

#6


0  

Maybe cron expressions would be more helpful for your current task at hand: specyfing how often something should happen. This format is quite flexible, well known and understood. To drive your bean that is doing the periodic chore you could, use the Quartz scheduler, EJB3 timer annotations or the Spring timer annotations.

也许cron表达式对你当前的任务更有帮助:对某事应该发生的频率进行分析。这种格式非常灵活,众所周知和理解。为了驱动您的bean,您可以使用Quartz scheduler、EJB3定时器注释或Spring定时器注解来完成周期性的工作。

#1


6  

The parser is not too complex:

解析器不太复杂:

public static long parse(String input) {
   long result = 0;
   String number = "";
   for (int i = 0; i < input.length(); i++) {
     char c = input.charAt(i);
     if (Character.isDigit(c)) { 
       number += c; 
     } else if (Character.isLetter(c) && !number.isEmpty()) {
       result += convert(Integer.parseInt(number), c);
       number = "";
     }
   }
   return result;
}

private static long convert(int value, char unit) {
  switch(unit) {
    case 'd' : return value * 1000*60*60*24;
    case 'h' : return value * 1000*60*60;         
    case 'm' : return value * 1000*60;
    case 's' : return value * 1000;
  }
  return 0;
}

The code is pretty fault tolerant, it just ignores almost anything it can't decode (and it ignores any whitspace, so it accepts "1d 1s", "1s 1d", "1d20m300s" and so on).

代码是相当容错的,它忽略了几乎任何它无法解码的东西(它忽略了任何空白,所以它接受了“1d 1s”、“1s 1d”、“1d20m300s”等等)。

#2


3  

Here's another solution, this one's configurable:

这是另一个解决方案,这个是可配置的:

public class TimeReader{

    private final Map<String, Long> units = new HashMap<String, Long>();

    private static final String UNIT_PATTERN = "\\w+";
    private static final Pattern ITEM_PATTERN = Pattern.compile("(\\d+)\\s*("
        + UNIT_PATTERN + ")");

    /**
     * Add a new time unit.
     * 
     * @param unit
     *            the unit, e.g. "s"
     * @param value
     *            the unit's modifier value (multiplier from milliseconds, e.g.
     *            1000)
     * @return self reference for chaining
     */
    public TimeReader addUnit(final String unit, final long value){
        if(value < 0 || !unit.matches(UNIT_PATTERN)){
            throw new IllegalArgumentException();
        }
        units.put(unit, Long.valueOf(value));
        return this;
    }

    /**
     * Parse a string using the defined units.
     * 
     * @return the resulting number of milliseconds
     */
    public long parse(final String input){
        long value = 0l;
        final Matcher matcher = ITEM_PATTERN.matcher(input);
        while(matcher.find()){
            final long modifier = Long.parseLong(matcher.group(1));
            final String unit = matcher.group(2);
            if(!units.containsKey(unit)){
                throw new IllegalArgumentException("Unrecognized token: "
                    + unit);
            }
            value += units.get(unit).longValue() * modifier;
        }
        return value;
    }

}

Sample Usage:

示例用法:

public static void main(final String[] args){
    final TimeReader timeReader =
        new TimeReader()
            .addUnit("h", 3600000l)
            .addUnit("m", 60000l)
            .addUnit("s", 1000l);

    System.out.println(timeReader.parse("3h, 2m   25  s"));
}

Output:

输出:

10945000

10945000

#3


1  

Take a look at joda-time's PeriodConverter. I have never used this part of the joda-time library myself, but it looks like it does what you need.

看看joda-time的周期转换器。我自己从来没有使用过这部分的joda-time库,但是它看起来就像您所需要的那样。

In general, for date/time stuff, look at joda-time first :)

一般来说,对于日期/时间的东西,先看一下joda-time:)

#4


0  

As far as I know, no. I believe you would have to convert those numbers yourself into Calendar (GregorianCalendar) and then from there you can proceed to get the milliseconds, which you probably already know which is why you posted this for the hope of a better answer.

据我所知,没有。我相信你必须把这些数字转换成日历(GregorianCalendar)然后从那里你可以得到毫秒,你可能已经知道这就是为什么你把它寄给了希望更好的答案。

My vote: If no one else can find one perhaps now is a good time to start one yourself and contribute it to the community. :)

我的投票:如果没有人能找到一个人,也许现在是一个开始自己并为社区贡献自己的好时机。:)

#5


0  

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest {
    public static void main(String[] args) {
        DateFormat df = new SimpleDateFormat("dd'd' HH'h' mm'm'");
        try {
            Date d = df.parse("1d 2h 30m");
            System.out.println(d.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

#6


0  

Maybe cron expressions would be more helpful for your current task at hand: specyfing how often something should happen. This format is quite flexible, well known and understood. To drive your bean that is doing the periodic chore you could, use the Quartz scheduler, EJB3 timer annotations or the Spring timer annotations.

也许cron表达式对你当前的任务更有帮助:对某事应该发生的频率进行分析。这种格式非常灵活,众所周知和理解。为了驱动您的bean,您可以使用Quartz scheduler、EJB3定时器注释或Spring定时器注解来完成周期性的工作。