判断一系列日期是否覆盖一个区间

2024-01-12

我有两个对象日历

Calendar startCalendar = new GregorianCalendar(2013,0,31);

Calendar endCalendar = new GregorianCalendar();

我想知道上面列出的两个日期之间的间隔是否被 n 个其他对象对日历覆盖,间隔之间没有空洞

示例1:

Calendar startCalendar1(2013,0,31);
Calendar endCalendar1(2014,0,31);
Calendar startCalendar2(2013,5,31);
Calendar endCalendar2();

Is GOOD

示例2:

Calendar startCalendar1(2013,0,31);
Calendar endCalendar1(2014,0,31);
Calendar startCalendar2(2014,2,31);
Calendar endCalendar2();

NOT GOOD

我使用Java 6 谢谢


第一种方法:仅使用 Java 6

当我看到你的约会例子时2015-01-31然后我就强烈怀疑你所说的封闭日期间隔否则选择月底可能会显得有点奇怪。这是一种广泛传播且合理的做法。不幸的是选择了这样的数据类型java.util.Calendar表示瞬间(也是日期-时区-组合)与闭区间不一致。这种类似即时的类型在半开区间工作得更好。结果是:

如果您决定仅使用 Java-6 类型,那么您可以尝试转换所有类型Calendar-按照 @guillaume girod-vitouchkina 的建议,表示自 Unix 纪元以来经过的毫秒数的 Long 值的对象(已得到我的赞成票作为示例,说明如何在没有任何外部库的情况下执行此操作)。但你必须为每一个额外添加一天Calendar-object(如果代表结束边界)提前达到封闭日期间隔的效果。

当然,您仍然需要自己做一些自制的区间算术,如该答案中以粗略的方式所示。如果您仔细研究其他提案和您自己的要求,您会发现最终的解决方案甚至需要的不仅仅是一个新的区间类或区间的基本比较。您还需要一个更高的抽象层,即几个间隔之间定义的操作。自己做这一切可能会引起一些头痛。另一方面:如果您具有良好的编程技能,那么实现基于长的间隔算术可能会节省一些性能开销,就像额外间隔库的典型情况一样。

第二种方法:使用专用的间隔库

我只知道四个承诺处理间隔的库。三十额外正如 @Basil Bourque 所提到的,无法使用,因为它需要 Java-8。它的间隔类的缺点是只能处理瞬间,而不能处理日历日期。也几乎不支持处理间隔集合。同样可以这样说乔达时间(它至少在 Java-6 上运行,并且还提供了专用的日历日期类型,即LocalDate但没有日期间隔)。

一个有趣的选择是使用Guava及其类别RangeSet http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/RangeSet.html,特别是如果您决定继续使用Calendar- 对象和长整型。这个类对处理间隔之间的操作有一些支持 - 对我来说比使用 Joda-Time 的简单间隔类更有吸引力。

最后您还可以选择使用我的图书馆Time4J其中有范围包 http://time4j.net/javadoc-en/net/time4j/range/package-summary.html。我现在将展示您问题的完整解决方案:

// our test interval
PlainDate start = PlainDate.of(2013, Month.JANUARY, 31);
PlainDate end = SystemClock.inLocalView().today();
DateInterval test = DateInterval.between(start, end);
IntervalCollection<PlainDate> icTest = IntervalCollection.onDateAxis().plus(test);

// two intervals for your GOOD case
PlainDate s1 = PlainDate.of(2013, Month.JANUARY, 31);
PlainDate e1 = PlainDate.of(2014, Month.JANUARY, 31);
DateInterval i1 = DateInterval.between(s1, e1);

PlainDate s2 = PlainDate.of(2013, Month.MAY, 31);
PlainDate e2 = end; // today
DateInterval i2 = DateInterval.between(s2, e2);

IntervalCollection<PlainDate> goodCase = 
    IntervalCollection.onDateAxis().plus(i1).plus(i2);

boolean covered = icTest.minus(goodCase).isEmpty();
System.out.println("Good case: " + covered); // true

// two intervals for your BAD case
PlainDate s3 = PlainDate.of(2013, Month.JANUARY, 31);
PlainDate e3 = PlainDate.of(2014, Month.JANUARY, 31);
DateInterval i3 = DateInterval.between(s3, e3);

PlainDate s4 = PlainDate.of(2014, Month.MARCH, 31);
PlainDate e4 = end; // today
DateInterval i4 = DateInterval.between(s4, e4);

IntervalCollection<PlainDate> badCase = 
    IntervalCollection.onDateAxis().plus(i3).plus(i4);

covered = icTest.minus(badCase).isEmpty();
System.out.println("Bad case: " + covered); // false

代码的最大部分只是区间构造。真正的区间算术本身是由这个令人惊讶的小代码片段完成的:

boolean covered = 
  IntervalCollection.onDateAxis().plus(test).minus(
    IntervalCollection.onDateAxis().plus(i1).plus(i2)
  ).isEmpty();

解释:如果 test 中 i1 和 i2 相减的余数为空,则测试区间被区间 i1 和 i2 覆盖。

顺便说一下:Time4J 中的日期间隔默认为闭间隔。如果您确实想要,您可以将这些间隔更改为半开间隔(只需调用withOpenEnd()在给定的日期间隔内)。

如果您计划稍后迁移到 Java-8,您只需将 Time4J 版本更新到版本 4.x(版本 v3.x 适用于 Java-6),即可非常轻松地转换为 Java-8 类型,例如java.time.LocalDate(例如:PlainDate.from(localDate) or LocalDate ld = plainDate.toTemporalAccessor()),因此即使在将来,您也可以继续使用 Time4J 来获得标准 Java 未涵盖的额外功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

判断一系列日期是否覆盖一个区间 的相关文章

  • 了解 netty 通道缓冲区和水印

    我正在尝试了解网络缓冲区和水印 作为一个测试用例 我有一个 netty 服务器 它向客户端写入数据 客户端被阻止 基本上每次读取之间有 10 秒的睡眠时间 在正常 I O 下 如果接收方被阻塞 TCP 发送方将受到限制 由于流量控制 发送速
  • 类型已知,但方法指的是缺失类型

    我对 java 和 Eclipse 不太有经验 但遇到以下问题 我正在写类似的东西 Point3D myPoint myClass myMethod arg 我收到错误 方法 myMethod myType arg 引用缺失的类型 Poin
  • 是否可以使用 Java 读写 Parquet,而不依赖 Hadoop 和 HDFS?

    我一直在寻找这个问题的解决方案 在我看来 如果不引入对 HDFS 和 Hadoop 的依赖 就无法在 Java 程序中嵌入读写 Parquet 格式 它是否正确 我想在 Hadoop 集群之外的客户端计算机上进行读写 我开始对 Apache
  • Java 小程序在 Mac 上闪烁

    这个问题很奇怪 问题并非在每个平台上都会发生 我在使用 MacOSX 的 Google Chrome 中出现了这种情况 但在 Safari 中却没有出现这种情况 对于使用 Windows 的朋友来说 在 Google Chrome 上运行得
  • Apache Thrift Java-Javascript 通信

    我正在编写一个基于 Apache Thrift 的 Java 服务器 它将从 Javascript 客户端接收数据 我已经完成了 Java 服务器 但问题是我可以获得 Javascript 客户端的工作示例 我无法找到一个好的示例 构建文档
  • H2数据库:如何进行加密保护,而不暴露文件加密密钥

    我们在服务器模式下使用Java H2数据库 因为我们不希望用户访问数据库文件 为了对数据库文件添加更多保护 我们计划使用 AES 加密 将 CIPHER AES 添加到数据库 URL 以防存储被盗 但是 每个用户在连接时还需要提供文件保护密
  • 使用全局变量从内部函数获取空字符串

    请帮助我解决一些小问题 我确信你能做到 D 我试图在 firestore 文档 user cases information 上设置一个字段 其中包含一个字段 case number 首先我声明这个全局变量 private String c
  • 未注入带有 JPA2 的 Apache Ignite 2.7 IgniteRepository

    使用在 Web 上建立的 guildes 我使用 Spring Data JPA 2 应用程序制作了简单的 Spring Boot 2 仅在 2 7 版本中才向 Apache Ignite 添加了 Spring Boot JPA 2 支持
  • 绘制平滑曲线

    我想创建更平滑的曲线 而不仅仅是线角 这是我现在画的图 这是我的代码 case FREEHAND float pts float ptk ptk new float 2 imageMatrix invert inv if mCurrentS
  • for循环中更新JLabel的问题

    我的程序的想法是从之前在其他 JFrame 中保存的列表中选择一个名称 我想在标签中一个接一个地打印所有名称 它们之间有很小的延迟 然后停在其中一个名称上 问题是lbl setText String 如果有多个则不起作用setText co
  • JERSEY:错误跟踪:java.lang.IllegalStateException:实体输入流已关闭

    我正在使用 Jersey 2 x 以下是我的控制器 GET Path id Produces application json public Response getUser PathParam id int userId Context
  • 避免 @Secured 注释的重复值

    我正在尝试使用以下方法来保护我的服务方法 Secured如下 public interface IUserService Secured ROLE ROLE1 ROLE ROLE2 ResponseEntity saveUser Creat
  • Time.valueOf 方法返回错误值

    我使用 Time valueOf 方法将字符串 09 00 00 转换为 Time 对象 如下所示 Time valueOf LocalTime parse 09 00 00 当我调用 getTime 来显示我得到的值时 28800000
  • RxJava android mvp 单元测试 NullPointerException

    我是 mvp 单元测试的新手 我想对演示者进行一个非常基本的测试 它负责登录 我只想断言 view onLoginSuccess 这是演示者代码 public LoginPresenter LoginViewContract loginVi
  • 使用 Guava Ordering 对对象列表进行多条件排序

    我有一个类无法实现可比较 但需要根据 2 个字段进行排序 我怎样才能用番石榴实现这一目标 假设班级是 class X String stringValue java util Date dateValue 我有一个清单 List
  • Java HashSet 是线程安全的只读吗?

    如果我通过 Collections unmodifyingSet 运行 HashSet 实例后 它是线程安全的吗 我问这个是因为 Set 文档声明它不是 但我只是执行读取操作 来自 Javadoc 请注意 此实现不是同步的 如果多个线程同时
  • Java 8 方法签名不一致

    Java 8 为我们提供了具有很长签名的新方法 如下所示 static
  • Hibernate 标准接受 %% 值

    我正在使用下面的 Hibernate 代码来过滤workFlowName crt add Restrictions like workFlowName workFlow MatchMode ANYWHERE crt is the crite
  • Spring - 如何在不匹配列名的情况下使用 BeanPropertyRowMapper

    我正在开发一个应用程序 该应用程序已使用行映射器从纯 JDBC 转换为 Spring 模板 我遇到的问题是数据库中的列与属性名称不匹配 这阻止我使用BeanPropertyRowMapper容易地 我看到一些关于在查询中使用别名的帖子 这会
  • 如何使用eclipse调试JSP tomcat服务?

    我想使用 Eclipse IDE 调试器来调试单独运行的 JSP Struts Tomcat Hibernate 应用程序堆栈 如何设置 java JVM 和 eclipse 以便设置断点 监视变量值并查看当前正在执行的代码 我刚刚用谷歌搜

随机推荐