mar*_*hon 2 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"
Run Code Online (Sandbox Code Playgroud)
你明白了.另一个目标是轻松有效地计算这些范围的重叠和子集.例如"1小时,从星期三下午1点开始"与"1小时,从下午1点开始"重叠
附加信息:这适用于基线系统中的时间段.我希望基线段具有多个粒度的时间段.与下午1点的任何1小时时段的基线或11月3日星期三下午1点开始的1小时时段的基线一样.
另外一个考虑因素是这些基线周期将存储在无sql存储中,并且以存储中存在的最小粒度有效地细化周期将是很好的.(特定的日 - 周 - 小时期间是否存在?不,周小时怎么样?,不是?如何只是一小时的时间段 - 如果这是有道理的.也许是某种树状的层次结构.
编辑:存储和查询部分可能是最重要的要求.将存储数十亿个时间段,并且需要尽可能快地查找它们(找到最精细的粒度).我很乐意为了提高速度而牺牲完整性.
编辑:考虑更多,以及如何将其存储在数据存储区中,树状结构可能有利于高效查找.我可以沿着树走下去,以获得最好的粒度.
1hr
/
1hr@1pm
/
1hr@1pm@wednesday
/
1hr@1pm@wednesday@November
Run Code Online (Sandbox Code Playgroud)
这就是我想出来的,但我觉得它很弱.我将继续摆弄它并在这里进行更新,但我很想知道是否有人有更聪明的方法对此进行建模.
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;
}
Run Code Online (Sandbox Code Playgroud)
编辑:基于树的结构(如我上面的编辑)会简单得多.没有未使用的字段用于大粒度跨度.粒度将在树中,而不是在数据结构中...
public class RangeTreeNode {
TimeUnit fTimeUnit;
int fStartTime;
int fSpanTime;
List<RangeTreeNode> fChildren;
}
Run Code Online (Sandbox Code Playgroud)
我认为你所描述的内容可以用Joda Time的Interval课程来建模.它支持Instant s,Period s和Duration s的概念:
的间隔表示时间从一毫秒时刻到另一时刻的间隔.两个时刻都是日期时间连续体中的完全指定的时刻,并带有时区.
一个即时表示关于时间线的精确点,而是限于毫秒的精度.
甲周期表示的时间段中的字段来定义,例如,3年5月2天及7小时.这与持续时间的不同之处在于它以毫秒为单位是不精确的.通过指定相对于的时刻(包括时间顺序和时区),只能将句点解析为精确的毫秒数.
甲持续时间表示以毫秒计的时间的持续时间.持续时间通常从间隔获得.
此外,它的接口支持AbstractInterval中定义的重叠,abuts,gap和其他Interval关系方法.
您可能还需要考虑部分为你的方法,这是笼统解释这里.这将有助于您:
甲部分没有完全指定的日期时间的连续的单个点,而是可以匹配的多个点(局部+丢失的字段+时区=时刻)
一些与您原始问题相关的示例:
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);
}
}
Run Code Online (Sandbox Code Playgroud)