简体   繁体   English

使用Joda-Time根据给定的时间舍入DateTime

[英]Round down a DateTime based on a given Period using Joda-Time

Given a period such as 3 days, or 5 weeks (a period with only one field type), I want to round a given DateTime to the nearest unit of that period (ie, ignore the 5 in '5 days'). 给定一个周期,例如3天或5周(一个字段只有一种字段类型的周期),我想将给定的DateTime舍入到该周期的最接近单位(即,忽略“ 5天”中的5个)。 Examples: 例子:

Example 1: 范例1:

  • Period: 3 days. 期限: 3天。
  • DateTime: Wednesday 4:26 AM UTC (2013-05-15T04:26:00Z) 日期时间: UTC星期三4:26(2013-05-15T04:26:00Z)
  • Rounded DateTime: Wednesday Midnight UTC (2013-05-15T00:00:00Z) 舍入日期时间: UTC星期三午夜(2013-05-15T00:00:00Z)

Example 2: 范例2:

  • Period: 5 weeks. 期间: 5周。
  • DateTime: Wednesday 4:26 AM UTC (2013-05-15T04:26:00Z) 日期时间: UTC星期三4:26(2013-05-15T04:26:00Z)
  • Rounded DateTime: Monday Midnight UTC (2013-05-13T00:00:00Z) 舍入日期时间: UTC星期一午夜(2013-05-13T00:00:00Z)

My initial idea was to use Period 's DurationFieldType getFieldTypes() method, and for every matching field in a DateTime (below the largest field), set them to zero. 我最初的想法是使用PeriodDurationFieldType getFieldTypes()方法,并为DateTime每个匹配字段(在最大字段下方)将它们设置为零。 However, I don't know how to get the DateTimeFieldType s from a DateTime and how to compare them to a DurationFieldType . 不过,我不知道如何让DateTimeFieldType从A S DateTime以及如何将它们比作DurationFieldType

I would prefer not to do a huge if else approach. 我宁愿不采取if else措施。

Example bellow is a solution in case you can express period in days (can be modified to weeks, months etc.). 波纹管示例是一种解决方案,以防您可以以天为单位表示期限(可以修改为几周,几个月等)。 Using DateTime Joda Java Library. 使用DateTime Joda Java库。

Unfortunately with rounding you require I see possible issue. 不幸的是,四舍五入需要您看到可能的问题。 You need to have a starting point in time since when you calculate the periods. 自计算周期以来,您需要有一个起点。 In example bellow we calculate periods since 1970/01/01 00:00:00 UTC. 在下面的示例中,我们计算自1970/01/01 00:00:00 UTC以来的时间段。 Or are you actually asking to get period of 3 days from first day of a month (year) etc? 还是您实际上是在要求从一个月(年)的第一天开始算起3天的期限? It would make more sense. 这会更有意义。

Questions you need to ask your self: What will happen on leap days? 您需要问自己的问题:leap日会发生什么?

Java Method 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();
}

Example use: 使用示例:

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

Too long for comment: 评论时间过长:

It's not clear what that "rounding" means. 目前尚不清楚“四舍五入”是什么意思。 To start with, you should deal with LocalDateTime s, not with DateTime s (they are very different things, see my answer here ). 首先,您应该处理LocalDateTime ,而不要处理DateTime (它们是非常不同的东西,请在此处查看我的答案)。

It seems to me you want to set to zero all fields with resolution lower than that of your "period" unit, and then set the next field to a multiple of the given value... is that so? 在我看来,您希望将所有分辨率低于“周期”单位的字段设置为零,然后将下一个字段设置为给定值的倍数……是这样吗? Then, I don't understand your second example (where are the 5 weeks?), and anyway, that would be badly specified: what to do with a period of "40 months" ? 然后,我不明白您的第二个示例(5个星期在哪里?),无论如何,这将被错误地指定:如何处理“ 40个月”?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM