2

我想将一个看起来像“5W3D10H5M10S”的字符串转换为秒,当将前一个字符串作为参数时,该函数将返回“3319510”。

  • W = 周
  • D = 天数
  • H = 小时
  • M = 分钟
  • S = 秒

我一直在想办法做到这一点,但没有一个是有效的,如果有人能指出我正确的方向,那就太好了。

4

6 回答 6

4

您可以在正则表达式的帮助下将其解析回来,请参见下面的 Java 7 实现:

    String str = "5W3D10H5M10S";
    String pat = "((?<week>\\d+)W)?((?<day>\\d+)D)?((?<hour>\\d+)H)?((?<min>\\d+)M)?((?<sec>\\d+)S)?";

    Matcher m = Pattern.compile (pat).matcher(str);

    if(m.matches()) {
        int week = Integer.parseInt( m.group("week") );
        int day  = Integer.parseInt( m.group("day") );
                    //And so on ..
    }
于 2012-11-03T16:39:26.910 回答
1

你可以用一个正则表达式和一个简单的循环来做到这一点:

private static final int[] timeMul = new int[] {7, 24, 60, 60, 1};
private static final Pattern rx = Pattern.compile(
    "(?:(\\d+)W)?(?:(\\d+)D)?(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?"
);
public static int getSeconds(String str) {
    Matcher m = rx.matcher(str);
    if (!m.find()) {
        return -1;
    }
    int res = 0;
    for (int i = 0 ; i != m.groupCount() ; i++) {
        String g = m.group(i+1);
        res += g == null ? 0 : Integer.parseInt(g);
        res *= timeMul[i];
    }
    return res;
}

链接到ideone。

于 2012-11-03T16:36:18.037 回答
1

如何将您的字符串转换为表达式并ScriptEngineManager进行计算?

public void testIt() throws Exception {
        final String in = "5W3D10H5M10S";
        final String after = in.replaceAll("W", "*7D").
                replaceAll("D", "*24H").
                replaceAll("H", "*60M").
                replaceAll("M", "*60+").
                replaceAll("S", "");
        final ScriptEngineManager manager = new ScriptEngineManager();
        final ScriptEngine engine = manager.getEngineByName("js");
        final Object result = engine.eval(after);
        System.out.println("Result:" + String.valueOf(result));
    }

输出:

Result:3319510.0
于 2012-11-03T16:45:48.467 回答
0

最简单的方法是简单地遍历文本,直到它到达一个非数字字符,然后获取前一个字符位置的子字符串并获取该文本部分,将其解析为 int 并将其乘以根据字符所需的数量。

例子:

public long getSeconds(String funnyFormat) 
{
    long seconds = 0;
    int lastIndex = 0;
    for(int i = 0;i<funnyFormat.length;i++) {
        char cur = funnyFormat.charAt(i);
        if(cur < '0' && cur > '9') {
            //If it's not a Number
            int seg = Integer.parseInt(funnyFormat.substring(lastIndex,i));
            lastIndex = i+1;
            switch(cur){
            case 'H':
                long += seg*3600;
                break;
            case 'M':
                long += seg*60;
                break;
            case 'S':
                long += seg;
                break;
            //And so on and so forth
            }
        }
    }
}
于 2012-11-03T16:38:14.153 回答
0

您必须对此进行调整以处理一些边界条件和意外输入...

long wdh(String fmt) {

    long tot = 0;
    int current = 0;
    for (char c : fmt.toCharArray()) {

        if (Character.isDigit(c)) {
            current *= 10;
            current += c - '0';
            continue;
        }

        switch (c) {

            case 'W': tot += WEEK_SECONDS * current; current = 0; continue;
            case 'D': tot += DAY_SECONDS * current; current = 0; continue;
            case 'H': tot += HOUR_SECONDS * current; current = 0; continue;
            case 'M': tot += MINUTE_SECONDS * current; current = 0; continue;
            case 'S': tot += current; break;
        }
    }

    return tot;
}
于 2012-11-03T16:41:29.880 回答
0

编辑:一点简化(更少的字符串操作)

    DateFormat dateFormat = new SimpleDateFormat("d'D'HH'H'mm'M'ss'S'");
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    String dateString = "5W3D10H5M10S";
    String[] dateAndWeek = dateString.split("W");
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    cal.setTime(dateFormat.parse(dateAndWeek[1]));
    cal.add(Calendar.DATE, 1);
    cal.add(Calendar.WEEK_OF_YEAR, Integer.parseInt(dateAndWeek[0]));
    long dateSeconds = cal.getTimeInMillis()/1000;//<--3319510
于 2012-11-03T17:22:13.327 回答