【问题标题】:How do I trim a string to parse a time with a SimpleDateFormat in java?如何修剪字符串以在 java 中使用 SimpleDateFormat 解析时间?
【发布时间】:2021-10-21 15:41:45
【问题描述】:

我正在尝试输入一个包含混合字符的字符串,并使用一些代码删除所有匹配所需 SimpleDateFormat 的部分

String wholeString = new String("The time is 7:00.");
String timeOnlyString = CODE TO TRIM STRING;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Date timeAsObject = sdf.parse(timeOnlyString);
String timeAsString = sdf.format(timeAsObject);
System.out.println(timeAsString);`

我想要这段代码

07:00

在控制台中打印。

【问题讨论】:

  • 使用正则表达式,或者如果整个字符串是等宽使用子字符串,
  • 假设 CODE TO TRIM STRING 实际上返回 7:00,你的代码对我有用。它将 07:00 打印到控制台。你的实际问题是什么?你的代码会抛出异常吗?它不会将 07:00 打印到控制台吗?
  • CODE TO TRIM STRING 应该返回 7:00,但我不知道要放什么代码才能真正做到这一点。我只是把它作为一个代理来填充示例代码。
  • 我建议你不要使用SimpleDateFormatDate。这些类设计不佳且早已过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time APILocalTimeDateTimeFormatter

标签: java string time datetime-parsing


【解决方案1】:

java.time

我建议您使用现代 Java 日期和时间 API java.time 来处理您的时间问题。

    String wholeString = "The time is 7:00.";
    Matcher m = TIME_PATTERN.matcher(wholeString);
    while (m.find()) {
        String timeOnlyString = m.group();
        try {
            LocalTime timeAsObject
                    = LocalTime.parse(timeOnlyString, TIME_FORMATTER);
            System.out.println("Time found: " + timeAsObject);
        } catch (DateTimeParseException dtpe) {
            System.out.println("Looked a bit like a time but couldn’t be parsed as one: " + timeOnlyString);
        }
    }

我使用了这两个静态声明:

private static final Pattern TIME_PATTERN
        = Pattern.compile("\\b\\d{1,2}:\\d{2}\\b");
private static final DateTimeFormatter TIME_FORMATTER
        = DateTimeFormatter.ofPattern("H:mm");

我的 sn-p 的输出是:

发现时间:07:00

我用来从整个字符串中提取时间的正则表达式匹配 1 位或 2 位数字、一个冒号和 2 位数字。它需要前后有一个单词边界,所以我们不会碰巧从987:12354letters1:11moreletters 中提取时间。

用于DateTimeFormatter 的格式模式字符串在一天中只有一个H。这接受 1 或 2 位数字,因此我们也可以解析 15:00

我认为我们应该考虑到正则表达式可能在字符串中匹配不止一次,所以我在循环中提取。

我正在解析java.time.LocalTime。该课程适用于一天中的某个时间(从 00:00 到 23:59:59.999999999),因此比过时的 Date 课程(既不代表日期也不代表一天中的时间,而是一个点)更适合您的需求没有时区的时间)。

【讨论】:

    【解决方案2】:

    您可以使用正则表达式 .*?(\d{1,2}:\d{1,2}(?:\:\d{1,2}(?:\.\d{1,9})?)?).* 匹配整个字符串,并将其替换为 group#1 匹配的模式。

    regex的描述:

    • .*? :匹配(惰性)任意字符任意次数
    • (: 开始捕获组#1
      • \d{1,2}:\d{1,2} :一到两位数,后跟一到两位数
      • (?: :可选非捕获组的开始
        • \:\d{1,2} : : 后跟一到两位数(秒)
          • (?: :可选非捕获组的开始
            • \.\d{1,9} : . 后跟一到九位数字(纳秒)
          • )? : 关闭可选非捕获组
      • )? : 关闭可选非捕获组
    • ):关闭捕获组#1
    • .*: 匹配任意字符任意次数

    演示:

    public class Main {
        public static void main(String[] args) {
            // Test strings
            String[] wholeStringArr = { "The time is 7:00.", "The time is 7:00:05.", "The time is 7:00:05.1.",
                    "The time is 7:00:05.123.", "The time is 7:00:05.123456789." };
    
            for (String wholeString : wholeStringArr) {
                String timeOnlyString = wholeString.replaceAll(".*?(\\d{1,2}:\\d{1,2}(?:\\:\\d{1,2}(?:\\.\\d{1,9})?)?).*",
                        "$1");
                System.out.println(timeOnlyString);
            }
        }
    }
    

    输出:

    7:00
    7:00:05
    7:00:05.1
    7:00:05.123
    7:00:05.123456789
    

    ONLINE DEMO

    java.time

    java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

    使用现代日期时间 API java.time 的解决方案:

    import java.time.LocalTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            String wholeString = "The time is 7:00.";
            String timeOnlyString = wholeString.replaceAll(".*?(\\d{1,2}:\\d{1,2}(?:\\:\\d{1,2}(?:\\.\\d{1,9})?)?).*",
                    "$1");
    
            DateTimeFormatter dtf = DateTimeFormatter
                    .ofPattern("H:m[:s[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]", Locale.ENGLISH);
            LocalTime time = LocalTime.parse(timeOnlyString, dtf);
            System.out.println(time);
        }
    }
    

    输出:

    07:00
    

    ONLINE DEMO

    注意方括号中的可选模式。

    通过 Trail: Date Time 了解有关 modern Date-Time API* 的更多信息。


    * 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

    【讨论】:

      【解决方案3】:
      String wholeString = "The time is 7:00.";
      Pattern pattern = Pattern.compile("(0?[1-9]|1[0-2]):[0-5][0-9]");
      Matcher matcher = pattern.matcher(wholeString);
      if(matcher.find()) {
          String timeOnlyString = matcher.group();
          SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
          Date timeAsObject = sdf.parse(timeOnlyString);
          String timeAsString = sdf.format(timeAsObject);
          System.out.println(timeAsString);
      }
      

      【讨论】:

      • 如果您解释您正在使用正则表达式以及该表达式的工作原理,这可能有助于使答案更加清晰。另外,我认为您应该提到,从 Java 8 开始,建议使用 SimpleDateFormat 类。
      猜你喜欢
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多