use*_*587 0 java date jodatime
如果可能的话,我希望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());
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是日期时间对象,则应将周定义为最多但不包括星期结束后的第一天.如图所示.

这种方法称为半开放式.这种方法通常用于处理时间跨度.
原因是,从逻辑上讲,新一天前一天的最后一刻可以在几分之一秒内被无限分割.您可能认为使用".999"会处理毫秒,但是当您在Java 8中编写具有纳秒分辨率而非毫秒级的新java.time.*类时,您会犯错误.您可能会认为使用".999999999"会处理这种情况,但是当处理来自许多数据库(如使用微秒分辨率的Postgres,".999999")的日期时间值时,您会被误解.
在第三方开源Joda-Time库中,这个半开放逻辑就是它的Interval类如何工作.开头是包容性的,结尾是独家的.这很好用.同样地,呼叫plusWeeks(1)a DateTime将一周添加到一天中的第一个时刻会给出第8天的第一个时刻(参见下面的示例).
问题和其他答案忽略了时区问题.如果您未指定,则您将获得默认时区.通常最好使用适当的时区名称(不是3个字母的代码)来指定时区.
避免使用Java捆绑的java.util.Date和Calendar类.众所周知,它们很麻烦.
以下是使用Joda-Time 2.3的一些示例代码.
CAVEAT:我没有彻底测试下面的代码.只是我的第一次采访,草稿.可能有缺陷.
Joda-Time库是围绕ISO 8601标准构建的.该标准将星期的第一天定义为星期一,最后一天定义为星期日.
如果这符合您对一周的定义,那么开始和结束很容易.
更新作为下面讨论的替代方案,请参阅SpaceTrucker的这个非常聪明且非常简单的单线解决方案.
简单地强制每周工作,因为Joda-Time假设你想要:
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime now = new DateTime( timeZone );
DateTime weekStart = now.withDayOfWeek( DateTimeConstants.MONDAY ).withTimeAtStartOfDay();
DateTime weekEnd = now.withDayOfWeek(DateTimeConstants.SUNDAY).plusDays( 1 ).withTimeAtStartOfDay();
Interval week = new Interval( weekStart, weekEnd );
Run Code Online (Sandbox Code Playgroud)
转储到控制台......
System.out.println( "now: " + now );
System.out.println( "weekStart: " + weekStart );
System.out.println( "weekEnd: " + weekEnd );
System.out.println( "week: " + week );
Run Code Online (Sandbox Code Playgroud)
跑的时候......
now: 2014-01-24T06:29:23.043+01:00
weekStart: 2014-01-20T00:00:00.000+01:00
weekEnd: 2014-01-27T00:00:00.000+01:00
week: 2014-01-20T00:00:00.000+01:00/2014-01-27T00:00:00.000+01:00
Run Code Online (Sandbox Code Playgroud)
要查看日期时间是否落在该间隔内,请调用该contains方法.
boolean weekContainsDate = week.contains( now );
Run Code Online (Sandbox Code Playgroud)
如果这不符合您对一周的定义,那么您就可以对该代码进行改动.
DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );
DateTime now = new DateTime( timeZone );
DateTime weekStart = now.withDayOfWeek( DateTimeConstants.SUNDAY ).withTimeAtStartOfDay();
if ( now.isBefore( weekStart )) {
// If we got next Sunday, go back one week to last Sunday.
weekStart = weekStart.minusWeeks( 1 );
}
DateTime weekEnd = weekStart.plusWeeks( 1 );
Interval week = new Interval( weekStart, weekEnd );
Run Code Online (Sandbox Code Playgroud)
转储到控制台......
System.out.println( "now: " + now );
System.out.println( "weekStart: " + weekStart );
System.out.println( "weekEnd: " + weekEnd );
System.out.println( "week: " + week );
Run Code Online (Sandbox Code Playgroud)
跑的时候......
now: 2014-01-24T00:54:27.092-05:00
weekStart: 2014-01-19T00:00:00.000-05:00
weekEnd: 2014-01-26T00:00:00.000-05:00
week: 2014-01-19T00:00:00.000-05:00/2014-01-26T00:00:00.000-05:00
Run Code Online (Sandbox Code Playgroud)