【问题标题】:Print all timestamps between two timestamps打印两个时间戳之间的所有时间戳
【发布时间】:2019-01-18 18:04:45
【问题描述】:

正如标题所说,给定两个日期,时间如

time1= "2017-01-31 12:00:00" 
time2= "2017-01-31 15:00:00”

我想返回数组中介于这两个时间和日期之间的所有时间戳。例如,这是数组的样子:

2017-01-31 01:33:30 random text log message x

2017-01-31 08:34:30 sdfsd log message y

2017-01-31 11:35:30 sdfsdfsdf log message z

2017-01-31 12:30:30 random text log message x

2017-01-31 13:31:30 sdfsd log message y

2017-01-31 14:32:30 sdfsdfsdf log message z

2017-01-31 16:32:35 sdfsdfsdf log message a

2017-01-31 16:33:30 random text log message x

2017-01-31 16:34:30 sdfsd log message y

2017-01-31 16:35:30 sdfsdfsdf log message z

2017-01-31 16:36:35 sdfsdfsdf log message a

输出:

2017-01-31 12:30:30 random text log message x

2017-01-31 13:31:30 sdfsd log message y

2017-01-31 14:32:30 sdfsdfsdf log message z

我是否必须使用正则表达式来存储每个单独的时间/日期戳的时间和日期,然后将它们与数组中的每个时间戳进行比较?或者什么是最佳解决方案?

【问题讨论】:

  • 嗯,你知道日期是 20 个字符长,所以你可以使用子字符串获取日期字符串,然后用 DateFormat 解析它以检查它是否在两个日期之间
  • 它们也必须在两次之间
  • 你将time1、time2和你的时间戳解析成日期,然后像这样检查它是否在两个时间之间。 timestamp.after(time1) && timestamp .before(time2)
  • 你能不能把它变成一个正式的答案?但是是说我可以制作以下形式的 DateFormat 对象:“yyyy-mm-dd hh:mm:ss”,然后我可以使用 .before 和 .after?
  • 我们可以假设数组总是按日期和时间排序吗?

标签: java timestamp


【解决方案1】:

java.time

    DateTimeFormatter logDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");

    String[] logMessages = {
            "2017-01-31 01:33:30 random text log message x",
            "2017-01-31 08:34:30 sdfsd log message y",
            "2017-01-31 11:35:30 sdfsdfsdf log message z",
            "2017-01-31 12:30:30 random text log message x",
            "2017-01-31 13:31:30 sdfsd log message y",
            "2017-01-31 14:32:30 sdfsdfsdf log message z",
            "2017-01-31 16:32:35 sdfsdfsdf log message a",
            "2017-01-31 16:33:30 random text log message x",
            "2017-01-31 16:34:30 sdfsd log message y",
            "2017-01-31 16:35:30 sdfsdfsdf log message z",
            "2017-01-31 16:36:35 sdfsdfsdf log message a"
    };

    String time1 = "2017-01-31 12:00:00";
    String time2 = "2017-01-31 15:00:00";

    LocalDateTime start = LocalDateTime.parse(time1, logDtf);
    LocalDateTime end = LocalDateTime.parse(time2, logDtf);

    Arrays.stream(logMessages)
            .filter(lm -> {
                TemporalAccessor parsedDateTime = logDtf.parse(lm, new ParsePosition(0));
                LocalDateTime logDateTime = LocalDateTime.from(parsedDateTime);
                return ! logDateTime.isBefore(start)
                        && logDateTime.isBefore(end);
            })
            .forEach(System.out::println);

此代码的输出是您所要求的:

2017-01-31 12:30:30 random text log message x
2017-01-31 13:31:30 sdfsd log message y
2017-01-31 14:32:30 sdfsdfsdf log message z

我正在使用 java.time,现代 Java 日期和时间 API。我总是推荐它用于 Java 中的任何日期时间工作。我觉得和它一起工作很愉快。

我正在过滤到您的时间之间的 半开 间隔。这意味着,将包含准确标记为 2017-01-31 12:00:00 的日志消息,而不会包含标记为 2017-01-31 15:00:00 的消息。这是通常和推荐使用的时间间隔。一个优点是,如果您过滤到相邻(非重叠)的时间间隔,则可以保证每条日志消息只包含一次。

如果您的数组非常大并且总是排序并且性能很重要,那么您可以从使用二进制搜索来查找所需间隔的开始和结束时受益。查找它是否相关并且您还不知道它是什么。

链接:Oracle tutorial: Date Time解释如何使用java.time

【讨论】:

  • 只有对数组进行排序后,二进制搜索才可行吗?
  • @Jack 是的,确实。这就是为什么我在你的问题下问它是否会一直如此。您的示例数组看起来像,所以我敢于将其放入答案中,而无需等待您的回答。如果你不能完全确定,当然不应该依赖它。
【解决方案2】:

好吧,您知道日期有 20 个字符长,因此您可以使用子字符串获取日期字符串,然后使用 DateFormat 对其进行解析以检查它是否在两个日期之间。您将 time1、time2 和您的时间戳解析为日期,然后检查它是否在这两个时间之间。 timestamp.after(time1) && timestamp .before(time2)

    String time1= "2017-01-31 12:00:00" 
        String time2= "2017-01-31 15:00:00”

        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date minDate = format.parse(time1);
        Date maxDate = format.parse(time2);

        for(String row : somearray){
            String rowDateString = row.substring(0,19);
            Date rowDate = format.parse(rowDateString);
            if(rowDate.after(minDate) && rowDate .before(maxDate){
                //get this row because it is between dates
            }
        }

【讨论】:

  • 请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API 和它的DateTimeFormatter 中做得更好。
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 2016-11-20
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
相关资源
最近更新 更多