如何检测时间戳是否位于其他两个时间戳之间?

时间:2013-06-06 19:36:18

标签: java

我有一个看起来或多或少的HashMap:

private HashMap<String, String> fu = new HashMap<String, String>();

fu.put("16:04:00.476", "A");
fu.put("16:09:58.228", "B");
fu.put("16:17:58.227", "C");
fu.put("16:22:42.478", "D");
fu.put("16:27:23.728", "E");
fu.put("16:38:34.977", "F");
fu.put("16:46:46.227", "G");

现在我有另一个名为bar的时间戳,我想找到合适的字母:

private String findLetter(String timestamp) {
   return "";
}

HashMap中的时间戳可以视为开始时间。这意味着,A从16:04:00.476开始并持续到B开始。 B持续到C开始,依此类推。现在,此方法应返回作为参数传递的时间戳所在的字母。

我做的第一件事就是将时间戳转换为Date对象以使用Date#after方法来查看它是否在某个开始时间之后,但我怎样才能确保它也在下一次启动之前时间?

5 个答案:

答案 0 :(得分:6)

HashMap没有排序,所以首先应该使用TreeMap。然后查看下一个条目,检查它是否在您当前的时间戳之后

答案 1 :(得分:0)

如果您的按键格式没有改变,您只需执行以下操作:

private NavigableMap<String, String> fu = new TreeMap<>();

然后

private String findLetter(String timestamp) {
    return map.get(map.lowerKey(timestamp));
}

如果您打算将来更改格式,可以执行以下操作(但必须调整时间格式)

private static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");

private NavigableMap<String, String> fu = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        try {
            long t1 = DATE_FORMAT.parse(o1).getTime();
            long t2 = DATE_FORMAT.parse(o2).getTime();
            return Long.compare(t1, t2);
        } catch (ParseException e) {
            throw new IllegalArgumentException(e);
        }
    }
});

然后你可以简单地做

private String findLetter(String timestamp) {
       return map.get(map.lowerKey(timestamp));
}

答案 2 :(得分:0)

这是基于TreeMap的简单解决方案,如建议的那样。它假定您显示的所有时间点都在同一天内。

class Sample {

    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");

    private static final String DEFAULT_DAY_PREFIX = "1980-05-15 ";

    public static void main(String[] args) throws ParseException {

        TreeMap<Long, String> orderedDates = new TreeMap<Long, String>();

        orderedDates.put(parseToDate("16:04:00.476"), "A");
        orderedDates.put(parseToDate("16:09:58.228"), "B");
        orderedDates.put(parseToDate("16:17:58.227"), "C");

        System.out.println(orderedDates.floorEntry(parseToDate("16:04:00.500")).getValue());
        System.out.println(orderedDates.floorEntry(parseToDate("16:09:58.100")).getValue());
        System.out.println(orderedDates.floorEntry(parseToDate("16:09:58.300")).getValue());
        System.out.println(orderedDates.floorEntry(parseToDate("16:17:58.300")).getValue());
    }

    private static long parseToDate(String dayPoint) throws ParseException {
        return SDF.parse(DEFAULT_DAY_PREFIX + dayPoint).getTime();
    }
}

答案 3 :(得分:0)

如果您已将String解析为Date,那么您可以使用唯一一种未弃用的方法getTime(),这将返回long代表毫秒。

然后你可以比较这个值,因为0是the Epoch,而我写这个答案是1370548040476

答案 4 :(得分:0)

我已经以更方便的方式修改了您的源代码,以向您展示如何正确执行此操作。我会让你按照自己想要的方式进行练习,但IMO可以非常直接地了解如何做到这一点。这使用JodaTime库。

package com.sandbox;

import org.joda.time.DateTime;
import org.joda.time.Interval;

import java.util.ArrayList;
import java.util.List;

public class Sandbox {

    public static void main(String[] args) {
        List<DateTime> dateTimes = new ArrayList<DateTime>();
        dateTimes.add(new DateTime(100000));
        dateTimes.add(new DateTime(105000));
        dateTimes.add(new DateTime(110000));
        dateTimes.add(new DateTime(115000));
        dateTimes.add(new DateTime(120000));

        List<Interval> intervals = new ArrayList<Interval>();

        for (int i = 0; i < dateTimes.size() - 1; i++) {
            DateTime start = dateTimes.get(i);
            DateTime end = dateTimes.get(i + 1);
            intervals.add(new Interval(start, end));
        }

        assert 0 == findIndex(100000L, intervals);
        assert 0 == findIndex(100001L, intervals);
        assert 3 == findIndex(115000L, intervals);
        assert 3 == findIndex(115001L, intervals);
    }

    private static Integer findIndex(Long timestamp, List<Interval> intervals) {
        DateTime dateTime = new DateTime(timestamp);

        for (int i = 0; i < intervals.size(); i++) {
            Interval interval = intervals.get(i);
            if (interval.contains(dateTime)) {
                return i;
            }
        }
        return -1;
    }


}

当您考虑@ Thierry的解决方案时,这比您需要的工作更多。但是,如果您的需求发生变化,这些代码可能会更灵活。不过,如果你不认为你的要求会改变,我会先使用他的建议。