34

我的 API 允许库客户端传递日期:

method(java.util.Date date)

Joda-Time合作,从这个日期开始,我想提取月份并遍历本月包含的所有日期。

现在,传递的日期通常是new Date() - 表示当前时刻。我的问题实际上是将新的DateMidnight(jdkDate)实例设置为月初。

有人可以用Joda-Time演示这个用例吗?

4

6 回答 6

47

当月第一天开始时的午夜由下式给出:

// first midnight in this month
DateMidnight first = new DateMidnight().withDayOfMonth(1);

// last midnight in this month
DateMidnight last = first.plusMonths(1).minusDays(1);

如果从 java.util.Date 开始,则使用不同的 DateMidnight 构造函数:

// first midnight in java.util.Date's month
DateMidnight first = new DateMidnight( date ).withDayOfMonth(1);

Joda Time java 文档 - https://www.joda.org/joda-time/apidocs/overview-summary.html

于 2010-02-14T15:22:19.220 回答
33

另一种获取月份第一天的方法(不考虑 DateMidnight)是使用:

  DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue();
于 2011-04-27T13:49:10.503 回答
10

一天的第一刻

ngeek的答案是正确的,但未能将时间放在一天的第一刻。要调整时间,请将调用附加到withTimeAtStartOfDay

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.

org.joda.time.DateTime startOfThisMonth = new org.joda.time.DateTime().dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
org.joda.time.DateTime startofNextMonth = startOfThisMonth.plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();

System.out.println( "startOfThisMonth: " + startOfThisMonth );
System.out.println( "startofNextMonth: " + startofNextMonth );

在美国西雅图跑步时……</p>

startOfThisMonth: 2013-11-01T00:00:00.000-07:00
startofNextMonth: 2013-12-01T00:00:00.000-08:00

请注意这两行控制台输出的区别: -7 与 -8 因为Daylight Saving Time


通常,应始终指定时区,而不是依赖默认值。为简单起见,此处省略。应该像这样添加一行,并将时区对象传递给上面示例中使用的构造函数。

// Time Zone list: http://joda-time.sourceforge.net/timezones.html  (Possibly out-dated, read note on that page)
// UTC time zone (no offset) has a constant, so no need to construct: org.joda.time.DateTimeZone.UTC
org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" );

java.time

以上是正确的,但已过时。Joda-Time 库现在被 Java 8 及更高版本中内置的 java.time 框架所取代。

LocalDate表示没有时间和时区的仅日期值。时区对于确定日期至关重要。对于任何给定的时刻,日期因全球区域而异。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );

使用其中一个TemporalAdjusters来获得月份的第一个月。

LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );

LocalDate可以生成一个ZonedDateTime代表一天中的第一个时刻。

ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );
于 2013-11-25T23:59:11.203 回答
5

哦,我没有看到这是关于jodatime的。反正:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);

int min = c.getActualMinimum(Calendar.DAY_OF_MONTH);
int max = c.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = min; i &lt;= max; i++) {
    c.set(Calendar.DAY_OF_MONTH, i);
    System.out.println(c.getTime());
}

或使用 commons-lang:

Date min = DateUtils.truncate(date, Calendar.MONTH);
Date max = DateUtils.addMonths(min, 1);
for (Date cur = min; cur.before(max); cur = DateUtils.addDays(cur, 1)) {
    System.out.println(cur);
}

于 2010-02-14T15:58:49.223 回答
1

DateMidnight现在已弃用。相反,您可以这样做:

LocalDate firstOfMonth = new LocalDate(date).withDayOfMonth(1);
LocalDate lastOfMonth = firstOfMonth.plusMonths(1).minusDays(1);

如果您知道时区,请new LocalDate(date, timeZone)改用以获得更高的准确性。

你也可以做.dayOfMonth().withMinimumValue()而不是.withDayOfMonth(1)

编辑:

这会给你12/1/YYYY 00:0012/31/YYYY 00:00。如果您宁愿本月的最后一天实际上是下个月的第一天(因为您正在执行 between 子句),minusDays(1)则从 lastOfMonth 计算中删除

于 2014-10-09T21:32:30.917 回答
0

您可以使用以下方法获取月份的开始日期和结束日期:

DateTime monthStartDate = new DateTime().dayOfMonth().withMinimumValue();
DateTime monthEndDate = new DateTime().dayOfMonth().withMaximumValue();
                        
于 2020-08-20T12:12:04.443 回答