给定当前日期和周开始,获取周开始和结束日期
如果可能的话,我更喜欢针对以下场景的 joda 或非 joda 解决方案
假设我的一周从 02/05/2012 开始,并且给定的当前日期是 02/22/2011。我需要计算给定当前日期的一周开始和结束日期。所以我的解决方案应该让一周从 02/19 开始,到 02/25 结束。 为简单起见,我将一周的开始时间设置为 02/05/2011,但也可以是任何一天,而且我的一周总是有 7 天。
我现有的代码如下,但似乎没有按预期工作。
public Interval getWeekInterval(Date calendarStartDate, Date date)
{
Calendar sDate = Calendar.getInstance();
sDate.setTime(getMidnightDate(calendarStartDate));
Calendar eDate = Calendar.getInstance();
eDate.setTime(date);
Calendar weekStartDate = (Calendar) sDate.clone();
logger.debug("Date:" + sDate.getTime());
while (sDate.before(eDate)) {
weekStartDate = sDate;
sDate.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
}
return new Interval(weekStartDate.getTime(), sDate.getTime());
}
If possible I would prefer a joda or non-joda solution for the scenario below
Lets say if my week starts on 02/05/2012 and the given current date is 02/22/2011. I need to calculate the week start and end date for the given current date. So my solution should have the week start as 02/19 and week ends at 02/25.
For simplicity, I have set my week start here as 02/05/2011 but it could be any day potentially and my week always has 7 days.
My existing code is below but doesnt seem to work as expected.
public Interval getWeekInterval(Date calendarStartDate, Date date)
{
Calendar sDate = Calendar.getInstance();
sDate.setTime(getMidnightDate(calendarStartDate));
Calendar eDate = Calendar.getInstance();
eDate.setTime(date);
Calendar weekStartDate = (Calendar) sDate.clone();
logger.debug("Date:" + sDate.getTime());
while (sDate.before(eDate)) {
weekStartDate = sDate;
sDate.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
}
return new Interval(weekStartDate.getTime(), sDate.getTime());
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
定义一周
如果您使用日期时间对象,则应将一周定义为一周结束后当天的第一时刻(但不包括该时刻)。如下图所示。
这种方法称为 半开。这种方法通常用于处理时间跨度。
原因是,从逻辑上讲,新的一天之前的最后一刻可以无限整除为几分之一秒。您可能认为使用“.999”可以处理毫秒级的问题,但是在编写 Java 8 中具有纳秒分辨率而不是毫秒分辨率的新 java.time.* 类时,您可能会犯错误。您可能认为使用“.999999999”可以处理这种情况,但在处理来自许多数据库(例如使用微秒分辨率的 Postgres)“.999999”的日期时间值时,您会犯错误。
在第三方开源Joda-Time库中,这种Half-Open逻辑是它的
间隔
类作品。开始是包容性的,结束是排他性的。这效果很好。同样,在DateTime
上调用plusWeeks(1)
将一周添加到一天的第一个时刻,即可获得第 8 天之后的第一个时刻(请参见下面的示例) 。时区
该问题和其他答案忽略了时区问题。如果您不指定,您将获得默认时区。通常最好使用正确的时区名称(不是 3-字母代码)。
Joda-Time
避免 java.util.Date &与 Java 捆绑在一起的日历类。他们是出了名的麻烦。
下面是一些使用 Joda-Time 2.3 的示例代码。
警告:我没有彻底测试以下代码。这只是我的第一次尝试,草稿。很可能存在缺陷。
标准周(周一至周日)
Joda-Time 库是围绕 ISO 8601 标准构建的。该标准将一周的第一天定义为星期一,最后一天定义为星期日。
如果这符合您对一周的定义,那么开始和结束就很容易了。
更新作为下面讨论的替代方案,请参阅这个非常聪明且非常简单的单行SpaceTrucker的解决方案< /a>.
简单地强制星期几是有效的,因为 Joda-Time 假设您希望:
转储到控制台...
运行时...
要查看日期时间是否在该间隔内,请调用
contains
方法。非标准周
如果这不符合您对周的定义,那么您就对该代码进行了修改。
转储到控制台...
运行时...
Defining A Week
If you are using date-time objects, you should define a week as up to but not including the first moment of the day after the end of week. As seen in this diagram.
This approach is known as Half-Open. This approach is commonly used for working with spans of time.
The reason is because, logically, that last moment of the day before the new day is infinitely divisible as a fraction of a second. You may think that using ".999" would handle that for milliseconds, but then you'd mistaken when writing for the new java.time.* classes in Java 8 that have nanosecond resolution rather than millisecond. You may think think that using ".999999999" would handle that case, but then you’d be mistaken when handling date-time values from many databases such as Postgres that use microsecond resolution, ".999999".
In the third-party open-source Joda-Time library, this Half-Open logic is how its
Interval
class works. The beginning is inclusive and the ending is exclusive. This works out nicely. Similarly, callingplusWeeks(1)
on aDateTime
to add a week to the first moment of a day gives you the first moment of the 8th day later (see example below).Time Zone
The question and other answers ignores the issue of time zone. If you do not specify, you'll be getting the default time zone. Usually better to specify a time zone, using a proper time zone name (not 3-letter code).
Joda-Time
Avoid the java.util.Date & Calendar classes bundled with Java. They are notoriously troublesome.
Here is some example code using Joda-Time 2.3.
CAVEAT: I have not tested of of the below code thoroughly. Just my first take, a rough draft. May well be flawed.
Standard Week (Monday-Sunday)
The Joda-Time library is built around the ISO 8601 standard. That standard defines the first day of the week as Monday, last day as Sunday.
If that meets your definition of a week, then getting the beginning and ending is easy.
UPDATE As an alternative to the discussion below, see this very clever and very simple one-liner solution by SpaceTrucker.
Simply forcing the day-of-week works because Joda-Time assumes you want:
Dump to console…
When run…
To see if a date-time lands inside that interval, call the
contains
method.Non-Standard Week
If that does not meet your definition of a week, you a twist on that code.
Dump to console…
When run…
一周的第一天取决于国家/地区。
使计算变得脆弱的原因是,人们可能会打破年份边界和周数 (
Calendar.WEEK_OF_YEAR
)。可以执行以下操作:日历中的错误破坏了您的代码,
克隆
似乎只是给出了相同的对象,因此最终您拥有相同的日期。 (至少 Java 7)。First day of week depends on the country.
What makes the calculation fragile, is that one may break the year boundary, and the week number (
Calendar.WEEK_OF_YEAR
). The following would do:One bug in Calendar breaks your code,
clone
, seems to simply give the identical object, hence at the end you have identical dates. (Java 7 at least).试试这个(伪代码):
现在,我们可以将所有这些缩短为两行:
注意我们减去了整数等日期值来显示算法。你必须正确编写你的java代码。
Try this (pseudo-code):
Now, we can shorten all of this to two lines:
Note that we subtracted date values like integers to show algorithm. You have to write your java code properly.