java - 如何对时间范围进行一般性建模,以允许任何时间段或更具体的时间段的范围

标签 java time data-modeling baseline

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

"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"

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

附加信息:这是针对基线系统中的时间段。我想要基线段的多个时间段粒度。就像下午 1 点任意 1 小时时段的基线或 11 月第 3 个星期三下午 1 点开始的 1 小时时段的基线。

另一个考虑因素是这些基线周期将存储在 no-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;
}

最佳答案

摘要

我认为你所描述的可以用 Joda Time 来建模的Interval类(class)。它支持 Instant 的概念s,Period s,和Duration s:

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.

此外,它的接口(interface)支持overlap , abuts , gap以及 AbstractInterval 中定义的其他 Interval 关系方法.

您可能还想考虑Partial对于您的方法,这是一般性的解释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);
    }

}

关于java - 如何对时间范围进行一般性建模,以允许任何时间段或更具体的时间段的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12878088/

相关文章:

java - Firestore-查询子集合

time - 在 C++/CX 中实现异步延迟

java - SimpleDateFormat - 解析日期时出现奇怪的结果

sql-server - 我应该在电话的 SQL varchar(length) 中考虑最长的全局电话号码是多少

database - 有哪些适用于 Linux 且可与 SQLAlchemy 配合使用的优秀免费数据建模程序?

java - 如何使用 Java HttpServer/HttpExchange 在 GET 中获取查询字符串?

java - JTextfield 文本到 Controller

java - 无法解析包修订版,因为它通过两个依赖链暴露给包

ruby-on-rails - Rails,在非事件记录模型上使用 time_select

mysql - 如何修复在 symfony2 中给出 doctrine2 迁移的错误