有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何对时间范围进行通用建模,以允许任何时间段或更具体的时间段的范围

想象一下,如果要对非分数时间范围建模,可以是以下任意一种:

"1 hour" (all/any 1 hour period)
"1 hour, starting 1pm")  (all/any 1 hour periods that start at 1pm)
"1 hour, starting 1pm, on Wednesdays" (all/any 1 hour periods that start at 1pm on wednesdays)
"1 hour, starting 1pm, on 3rd Wednesday in November"
"1 week, starting the first week in November"

你明白了。另一个目标是轻松有效地计算这些范围的重叠和子集。e、 g.“星期三下午1点开始的1小时”与“下午1点开始的1小时”重叠

附加信息:这是基线系统中的时间段。我希望基线段具有多个时间段粒度。与下午1点的任何1小时周期的基线或11月3日星期三下午1点开始的1小时周期的基线相同

另一个需要考虑的问题是,这些基线周期将存储在无sql存储中,最好以存储中存在的最小粒度高效地细化周期。(是否存在特定的日-周-小时周期?否,周-小时周期如何?否?仅一天-小时周期如何)-如果有意义的话。也许是某种类似树的层次结构

编辑:存储和查询部分可能是最重要的需求。将存储数十亿个时间段,需要尽可能快地查找它们(找到存在的最精细的粒度)。我很乐意牺牲完整性来换取快速的查找

编辑:更多地考虑它,以及它必须如何存储在数据存储中,树状结构可能有助于高效查找。我可以沿着这棵树走下去,得到最精细的粒度

          1hr
          /
       1hr@1pm
       /
     1hr@1pm@wednesday
     /
   1hr@1pm@wednesday@November

这是我想到的,但我觉得它很弱。我将继续摆弄它,并在这里更新,但我很好奇,看看是否有人有一个更聪明的方法来建模

public class DateRange {

    Integer fTimeSpan;
    TimeUnit fTimeUnit;
    Integer fStartHour;
    Integer fStartDay;
    Integer fStartWeek;
    Integer fStartMonth;

    boolean intersects(DateRange other) { ... }

}
enum TimeUnit {
    HOURS,
    DAYS,
    WEEKS,
    MONTHS;

}

在“我的树”中,编辑与上面的“编辑”结构类似。对于大粒度跨度,没有未使用的字段。粒度将在树中,而不是在数据结构中

public class RangeTreeNode {

    TimeUnit fTimeUnit;
    int fStartTime;
    int fSpanTime;
    List<RangeTreeNode> fChildren;
}

共 (1) 个答案

  1. # 1 楼答案

    抽象

    我认为您所描述的可以用Joda TimeInterval类建模。它支持Instants、Periods和Durations的概念:

    An interval represents an interval of time from one millisecond instant to another instant. Both instants are fully specified instants in the datetime continuum, complete with time zone.

    An instant represents an exact point on the time-line, but limited to the precision of milliseconds.

    A period represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to.

    A duration represents a duration of time measured in milliseconds. The duration is often obtained from an interval.

    此外,它的接口支持overlapabutsgapAbstractInterval中定义的其他Interval关系方法

    你也可以考虑你的方法的{a10},用一般术语here来解释。这将帮助您,因为:

    A partial does not fully specify a single point in the datetime continuum, but instead may match multiple points (partial + missing fields + time zone = instant)

    例子

    与原始问题相关的一些示例:

    import static org.joda.time.DateTimeConstants.NOVEMBER;
    import static org.joda.time.DateTimeConstants.WEDNESDAY;
    import static org.joda.time.DateTimeFieldType.dayOfMonth;
    import static org.joda.time.DateTimeFieldType.dayOfWeek;
    import static org.joda.time.DateTimeFieldType.hourOfDay;
    import static org.joda.time.DateTimeFieldType.monthOfYear;
    import static org.joda.time.Duration.standardDays;
    import static org.joda.time.Duration.standardHours;
    
    import org.joda.time.Duration;
    import org.joda.time.Partial;
    
    public class Periods {
    
        public static void main(String[] args) {
    
            // "1 hour" (all/any 1 hour period)
            Duration d1 = standardHours(1);
            Partial p1 = new Partial();
    
            // "1 hour, starting 1pm" (all/any 1 hour periods that start at 1pm)
            Duration d2 = standardHours(1);
            Partial p2 = new Partial().withField(hourOfDay(), 13);
    
            // "1 hour, starting 1pm, on Wednesdays" (all/any 1 hour periods that start at 1pm on Eednesdays)
            Duration d3 = standardHours(1);
            Partial p4 = new Partial().withField(hourOfDay(), 13).withField(hourOfDay(), 1).withField(dayOfWeek(), WEDNESDAY);
    
            // "1 hour, starting 1pm, on Wednesday in November"
            Duration d4 = standardHours(1);
            Partial p3 = new Partial().withField(hourOfDay(), 13).withField(hourOfDay(), 1).withField(dayOfWeek(), WEDNESDAY).withField(monthOfYear(), NOVEMBER);
    
            // "1 week, starting the first week in November"
            Duration d5 = standardDays(7);
            Partial p5 = new Partial().withField(dayOfMonth(), 1).withField(monthOfYear(), NOVEMBER);
        }
    
    }