想象一下,如果你想模拟一个非分数时间范围,可能是以下任何一个:
"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;
}
答案 0 :(得分:5)
我认为您所描述的内容可以使用Joda Time的Interval课程进行建模。它支持Instant s,Period和Duration s的概念:
间隔表示从1开始的时间间隔 毫秒瞬间到另一个瞬间。两个时刻都是完整的 日期时间连续统中的指定时刻,包括时区。
瞬间表示时间线上的精确点,但仅限于毫秒精度。
期间表示按术语定义的时间段 田地,例如,3年5个月2天7小时。这个 不同于持续时间,因为它是不精确的 毫秒。句点只能解析为确切的数字 指定瞬间(包括时间顺序和时间)的毫秒数 区域)它是相对的。
持续时间表示测量的持续时间 毫秒。持续时间通常是从一个区间获得的。
此外,它的界面支持overlap中定义的abuts,gap,AbstractInterval和其他Interval
关系方法。
您可能还需要考虑Partial的方法,一般用here来解释。这将对您有所帮助:
部分未完全指定日期时间中的单个点 连续体,但可以匹配多个点(部分+缺失字段+时区=即时)
与您原始问题相关的一些示例:
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);
}
}