如何解析包含时间单位的字符串(ms/ns/ps/fs等)在Java中翻倍



如何解析表示时间的字符串(包含双精度和时间单位后缀(ms/ns/ps/picosecond(s)/us/fs/msec/毫秒等))变成双倍秒

。输入字符串

"1.23 ms"
"0.98 ns"
"33 s"

输出双:

0.00123
0.0000000098
33.0

谢谢

可以使用正则表达式来提取值和单位作为下一个:

Pattern pattern = Pattern.compile("(\d+(?:\.\d+)?) (s|ms|us|ns|ps|fs)");
List<String> values = Arrays.asList(
    "1.23 ms", "0.98 ns", "33 s", "1.3 us", "20.5 ps", "4.5 fs"
);
values.forEach(
    value -> {
        Matcher matcher = pattern.matcher(value);
        if (matcher.find()) {
            // Convert the value into a double
            double result = Double.valueOf(matcher.group(1));
            double factor;
            // Convert the unit to a factor
            switch (matcher.group(2)) {
                case "ms" :
                    factor = Math.pow(10.0, -3.0);
                    break;
                case "us" :
                    factor = Math.pow(10.0, -6.0);
                    break;
                case "ns" :
                    factor = Math.pow(10.0, -9.0);
                    break;
                case "ps" :
                    factor = Math.pow(10.0, -12.0);
                    break;
                case "fs" :
                    factor = Math.pow(10.0, -15.0);
                    break;
                default:
                    factor = 1.0;
                    break;
            }
            // Apply the factor
            result *= factor;
            System.out.printf("%s = %s seconds%n", value, result);
        }
    }
);
输出:

1.23 ms = 0.00123 seconds
0.98 ns = 9.800000000000001E-10 seconds
33 s = 33.0 seconds
1.3 us = 1.3E-6 seconds
20.5 ps = 2.05E-11 seconds
4.5 fs = 4.5000000000000005E-15 seconds

考虑过删除答案,但我觉得编辑并使用额外信息使其正确可能更有意义。

是正确的。JODA API不支持超过毫秒的精度。找到另一个stackoverflow链接并仔细阅读它,我发现移动到java。Java 8中的time api应该是正确的选择。

我刚刚检查了他们的官方网站,它本身建议迁移到基于Java 8的Java。时间(JSR-310)

这里是另一个链接,可以帮助您更多地了解基于Java 8的日期/时间api与JODA的差异

如果需要基于毫秒精度的计算,并且使用Java 8之前的JDK版本,那么可以尝试JODA。

像这样一个简单的代码应该可以做到。

private double convertExpression(String str) throws Exception{
    String []stringArr = str.split(" ");
    if(stringArr.length <= 1){
        throw new Exception("Incorrect format");
    }
    String unit = stringArr[1];
    String stringVal = stringArr[0];
    double intVal = Double.parseDouble(stringVal);
    switch(unit){
    case "ms":
        return intVal/1000;
    case "ns":
        return intVal/10e9;
    case "s":
        return intVal;
    }
    return 0;
}

如果您的需求很简单,我建议您将其作为代码的一部分构建。

您可以使用TimeUnit类在不同的时间度量之间进行转换。

但是,您需要解析字符串以确定数值和单位。

这并不像将字符串解析为双精度类型那么简单,因为在这种情况下,您还将其转换为秒,而不是保留原始单位。

在这个特定的例子中,我将使用正则表达式。您可以使用RegEx从字符串和单元中提取值,以便您可以相应地处理它。

下面应该可以工作:(d+(?:.d+)?)s?(w?s)

第一个捕获组将提供十进制部分,第二个捕获组将提供单位(ns/ms/s)。您可以将第一个捕获组存储为双精度体,第二个捕获组存储为字符串,并根据获得的单位对双精度体进行数学运算。如果是ns那么x10^(-9)等等

或者,一个更简单但不太灵活的解决方案是基于空格拆分字符串,然后使用结果数组中的第一个值作为双精度,第二个值作为单位。但是,如果您删除字符串中的空格,这将不起作用。我更喜欢RegEx解决方案,因为您知道,如果找到匹配,那么第一个捕获组将包含一个值,第二个捕获组将包含一个单位。

如果您对RegEx解决方案感兴趣,那么我将在这里分解它:

(d+(?:.d+)?)s?(w?s)

"("表示捕获组开始d+表示它正在获取一个或多个十进制值"(?:"表示非抓包组的开始.表示它正在寻找一个点)表示一个组的结束(捕获或不捕获)?表示"其中一个或没有"s?表示一个或多个空格w?表示一个或多个字母s表示它正在寻找s

总之,它查找一个十进制值,后跟一个可选的空格字符,然后是任意字母和一个's'。这意味着它将接受以下任何内容:

5.00毫秒

5.00 s

5.10 ns

5.1259 fs

241.015552 p

1 s

它不接受:

12 wpwa

12

511.2012 wprpwaroawroaroas

它不接受最后一个,因为单位最多只能有两个字符——一个用来表示有多小,比如m或n,另一个用来表示它的单位是秒(s)。如果你决定要在数字之后显示任何文本,以支持"512.032 millis"这样的文本,那么你可以在我提供的语句中将最终的(w?s)更改为(w*s)

相关内容

最新更新