使用Joda-Time基于给定的Period缩小DateTime

时间:2013-05-13 04:40:56

标签: java datetime jodatime

给定一段时间,例如3天或5周(只有一种字段类型的时间段),我想将给定的DateTime舍入到该时间段的最近单位(即忽略5中' 5天')。例子:

示例1:

  • 期间: 3天。
  • 日期时间:周三凌晨4:26 UTC(2013-05-15T04:26:00Z)
  • 圆形日期时间:周三午夜UTC(2013-05-15T00:00:00Z)

示例2:

  • 期间: 5周。
  • 日期时间:周三凌晨4:26 UTC(2013-05-15T04:26:00Z)
  • 圆形日期时间:星期一午夜UTC(2013-05-13T00:00:00Z)

我最初的想法是使用Period的{​​{1}}方法,并且对于DurationFieldType getFieldTypes()(最大字段下方)中的每个匹配字段,将它们设置为零。但是,我不知道如何从DateTime获取DateTimeFieldType以及如何将它们与DateTime进行比较。

我不想做一个巨大的DurationFieldType方法。

2 个答案:

答案 0 :(得分:1)

以下示例是一种解决方案,以便您可以表示以天为单位的时间段(可以修改为数周,数月等)。使用DateTime Joda Java Library。

不幸的是,通过四舍五入,你需要我看到可能的问题。从计算周期开始,您需要有一个起点。在下面的示例中,我们计算自1970/01/01 00:00:00 UTC以来的时段。或者你真的要求从一个月的第一天(年)开始等待3天?这会更有意义。

你需要问自己的问题:闰日会发生什么?

Java方法

DateTime roundDays(DateTime dt, int windowDays) {
    Duration p = Duration.standardDays(windowDays);

    long t = dt.getMillis() / p.getMillis() * p.getMillis();
    // Keep TimeZone and round floor to a day
    return new DateTime(t, dt.getZone()).dayOfMonth().roundFloorCopy();
}

使用示例:

DateTime dt = new DateTime(1385578964580L, DateTimeZone.UTC);

System.out.println(roundDays(dt, 3));
System.out.println(roundDays(dt.plusDays(2), 3));
System.out.println(roundDays(dt.plusDays(4), 3));
System.out.println(roundDays(dt.plusDays(6), 3));

// Prints data rounded to every 3 days
// 2013-11-26T00:00:00.000Z
// 2013-11-29T00:00:00.000Z
// 2013-11-29T00:00:00.000Z
// 2013-12-02T00:00:00.000Z

答案 1 :(得分:0)

评论太长了:

目前尚不清楚“四舍五入”是什么意思。首先,你应该处理LocalDateTime s,而不是DateTime s(它们是非常不同的东西,请参阅我的回答here)。

在我看来,你想要将分辨率低于“句号”单位的所有字段设置为零,然后将下一个字段设置为给定值的倍数......是这样的吗?然后,我不明白你的第二个例子(5周在哪里?),无论如何,这将被严格规定:如何处理一段“40个月”?