Cha*_*ava 6 java time object intervals
一些简短的背景:
我有一个java应用程序,用于查看某些位置(教室)何时使用.用户将位置标识符放入搜索框,程序显示匹配的任何事件(类).该应用程序将显示所有相关信息(班级名称,房间号,教授姓名,星期几,课程时间),会话中(或即将成为)的课程采用颜色编码,以便您可以告诉-a - 如果有任何事情发生的话.数据来自我正在抓取的html页面(我没有SQL访问权限).
到目前为止,一切都有效,我正在使用JavaSwing进行UI.事件存储为我保存它的基本对象,对我的问题唯一重要的部分是它存储到Java Date对象的每个事件的开始和结束时间.
我现在要做的是添加一种方法来检查并显示事件之间的差距(当教室为空时).我拥有我需要的所有数据(所有开始和结束时间),但是我无法想出一种方法来实际编写程序来查看差距.
如果这还不够具备挑战性:我想尽可能简单地实现它,而不是使用任何额外的库.我不想重新创建轮子,但是我宁愿手动散列代码,而不仅仅是输入一个导入和几个方法调用; 这个项目的一半要点是挑战自己.
目前我并不是在寻找有关如何实际显示数据的建议,因为现在我只是尝试以可用的方式对其进行逻辑组织.它最终将显示在JTable中,但我还没有开始实现该实现.
我刮刀从HTML表像拉<td id=time>10:00AM - 11:15AM</td>并解析出两个字符串10:00AM和11:15AM.这些与其他数据一起传递给我的Course对象.
我的Course对象有一个DateFormat设置,因此它可以将传入的字符串解释为日期.
public class Course {
static DateFormat tf = new SimpleDateFormat("h:mma");
private String name;
private String room;
private String instructor;
private Date start;
private Date end;
private String days;
public Course(String n, String r, String in, String st, String ed, String d) throws ParseException{
name=n;
room=r;
instructor=in;
start=tf.parse(st);
end=tf.parse(ed);
days=d;
}
//...basic getters, setters, and a toString()
Run Code Online (Sandbox Code Playgroud)
我的想法是,我会设置两次,设置我要检查间隙的窗口.我想选择一个间隔,比如说15分钟,并找到15分钟或更长时间内教室空置的所有间隙,即没有课程会议.
我没有完整的答案,但我有一些建议。
\n\nADate表示 UTC/GMT 格式的日期时间,即没有时区偏移。您的值位于时区。从长远来看,不要忽略该时区,您的情况会更好。调整你的价值观。通常以 UTC/GMT 来思考、工作和存储日期时间。根据需要转换为本地时间以便在用户界面中显示。
虽然 java.util.Date 没有时区,但 Joda-Time DateTime(下面讨论)确实知道它自己的时区和时区偏移量。
与 Java 捆绑在一起的 java.util.Date 和 Calendar 类是出了名的麻烦。避开他们。
\n\n相反,请使用:
\n\n不要将 Joda-Time 视为任何旧的“额外图书馆”。在 IDE 中创建新项目时,我做的第一件事是添加 Joda-Time 库。就是这么好。或者 juDate/Calendar 就那么糟糕,这取决于您的观点。
\n\n处理时间跨度的最佳方法是使开始具有包容性,使结束具有排他性。编写逻辑,检查开头是否大于或等于以及结尾是否小于(不测试结尾是否等于)。我在另一个答案中结合图表对此进行了更多讨论。
\n\nJoda-Time 提供了这些用于定义时间跨度的类:Period、Duration 和 Internal。Hours 和类似的类提供了一些方便的实用方法。
\n\n如果您的目标是列出一个空白列表,列出教室未分配给班级的时间跨度,那么在我看来,最明显的方法就是按时间顺序(并按教室)对班级进行排序,如 Rob 的回答所示怀特塞德。定义一个“可用”时间跨度,其开头是前一个 class\xe2\x80\x99 结尾,结尾是下一个 class\xe2\x80\x99 开头。我在这方面没有经验,所以可能有更聪明的方法。
\n\n请参阅有关对间隔列表进行排序的问题。
\n\n下面是一些使用 Joda-Time 2.3 的示例代码。
\n\n指定时区而不是依赖默认\xe2\x80\xa6
\n\nDateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );\nRun Code Online (Sandbox Code Playgroud)\n\n创建三个类作为样本数据,顺序任意\xe2\x80\xa6
\n\nInterval class_math = new Interval( new DateTime( 2014, 1, 24, 10, 0, 0, timeZone ), new DateTime( 2014, 1, 24, 11, 15, 0, timeZone ) );\nInterval class_chemistry = new Interval( new DateTime( 2014, 1, 24, 8, 0, 0, timeZone ), new DateTime( 2014, 1, 24, 9, 15, 0, timeZone ) );\nInterval class_french_lit = new Interval( new DateTime( 2014, 1, 24, 13, 0, 0, timeZone ), new DateTime( 2014, 1, 24, 14, 15, 0, timeZone ) );\nRun Code Online (Sandbox Code Playgroud)\n\n将样本数据收集到List\xe2\x80\xa6中
\n\njava.util.List<Interval> classes = new java.util.ArrayList<Interval>( 3 );\nclasses.add( class_math );\nclasses.add( class_chemistry );\nclasses.add( class_french_lit );\nSystem.out.println( "classes unsorted: " + classes );\nRun Code Online (Sandbox Code Playgroud)\n\n使用自定义比较器对列表进行排序(请参阅下面的类定义)\xe2\x80\xa6
\n\njava.util.Collections.sort( classes, new IntervalStartComparator() );\nSystem.out.println( "classes sorted: " + classes );\nRun Code Online (Sandbox Code Playgroud)\n\n创建代表我们找到的类之间的每个间隙的对象集合\xe2\x80\xa6
\n\njava.util.List<Interval> gaps = new java.util.ArrayList<Interval>();\n\nDateTime gapStart = null, gapStop = null;\nfor ( int i = 0; i < classes.size(); i++ ) {\n // For each class, take the prior class\' end as the gap\'s beginning, and the next class\' start as the gap\'s ending.\n Interval session = classes.get( i ); // Cannot name the var "class" because that is a keyword in Java.\n if ( i == 0 ) { // If first time through, grab the end of the first class as our first gap\'s start.\n gapStart = session.getEnd();\n continue;\n }\n gapStop = session.getStart();\n Interval gap = new Interval( gapStart, gapStop );\n gaps.add( gap );\n gapStart = session.getEnd();\n}\n\nSystem.out.println( "gaps: " + gaps );\nRun Code Online (Sandbox Code Playgroud)\n\n上面代码中使用的比较器的类定义是从 Jon Skeet \xe2\x80\xa6的答案中提取的
\n\nclass IntervalStartComparator implements java.util.Comparator<Interval> {\n\n @Override\n public int compare( Interval x, Interval y ) {\n return x.getStart().compareTo( y.getStart() );\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n当运行\xe2\x80\xa6时
\n\nDateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );\nRun Code Online (Sandbox Code Playgroud)\n\n你说过你只关心至少 15 分钟长的间隙。Joda-Time 中的Duration实例表示 Interval 的开始点和停止点之间的毫秒数。
\n\n这是一些未经测试的即兴代码。
\n\n将上面的“gap”变量重命名为“gapInterval”以提醒您它是一个Interval实例。
\n\n请注意,这Minutes是一个类。下面看到的“分钟”变量是一个实例,而不是整数原语(“int”)。调用该getMinutes方法会呈现一个int基元。
Interval class_math = new Interval( new DateTime( 2014, 1, 24, 10, 0, 0, timeZone ), new DateTime( 2014, 1, 24, 11, 15, 0, timeZone ) );\nInterval class_chemistry = new Interval( new DateTime( 2014, 1, 24, 8, 0, 0, timeZone ), new DateTime( 2014, 1, 24, 9, 15, 0, timeZone ) );\nInterval class_french_lit = new Interval( new DateTime( 2014, 1, 24, 13, 0, 0, timeZone ), new DateTime( 2014, 1, 24, 14, 15, 0, timeZone ) );\nRun Code Online (Sandbox Code Playgroud)\n\n您看到的字符串输出不是任意的。这些是ISO 8601格式。该方便的标准定义了单个日期时间值以及<start>/<end> 时间间隔的字符串表示形式。
该标准还定义了可能对您有用的持续时间的字符串表示形式,PnYnMnDTnHnMnS格式为“P3Y6M4DT12H30M5S”,意思是“三年、六个月、四天、十二小时、三十分钟和五秒”。或者更短,就像你的情况一样,一个类可能是PT1H15M一个又一刻钟。
Joda-Time 使用 ISO 8601 作为大多数内容的默认值,作为输入和输出。
\n| 归档时间: |
|
| 查看次数: |
3537 次 |
| 最近记录: |