在Joda-Time中,将DateTime设置为月初

Max*_*ler 31 java date jodatime

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

method(java.util.Date date)
Run Code Online (Sandbox Code Playgroud)

Joda-Time合作,从这一天开始,我想提取月份并迭代本月所有日子.

现在,传递的日期通常是新的Date() - 意味着当前的瞬间.我的问题实际上是将新的DateMidnight(jdkDate)实例设置为月初.

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

Lac*_*che 45

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

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

// last midnight in this month
DateMidnight last = first.plusMonths(1).minusDays(1);
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 这个答案是正确的,但是现在已经过时了。并非每个时区的每一天都有一个午夜。Joda-Time 2添加了一种方法[`withTimeAtStartOfDay`](http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html#withTimeAtStartOfDay())来代替“午夜“ 特征。 (2认同)

nge*_*eek 32

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

  DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue();
Run Code Online (Sandbox Code Playgroud)

  • 虽然日期是本月的第一天,但​​时间仍然是在一天的中间.将.withTimeAtStartOfDay()添加到最后将解决此问题. (6认同)
  • joda时间太棒了 (5认同)

Bas*_*que 8

一天的第一时刻

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 );
Run Code Online (Sandbox Code Playgroud)

在美国西雅图运行时......

startOfThisMonth: 2013-11-01T00:00:00.000-07:00
startofNextMonth: 2013-12-01T00:00:00.000-08:00
Run Code Online (Sandbox Code Playgroud)

请注意这两行控制台输出的差异:-7 vs -8,因为夏令时.


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

// 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" );
Run Code Online (Sandbox Code Playgroud)

java.time

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

LocalDate表示没有时间且没有时区的仅日期值.时区对于确定日期至关重要.对于任何特定时刻,日期因地球区域而异.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
Run Code Online (Sandbox Code Playgroud)

使用其中一个TemporalAdjusters来获得第一个月.

LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
Run Code Online (Sandbox Code Playgroud)

LocalDate可生成ZonedDateTime代表这一天的第一刻.

ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );
Run Code Online (Sandbox Code Playgroud)


小智 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 <= max; i++) {
    c.set(Calendar.DAY_OF_MONTH, i);
    System.out.println(c.getTime());
}
Run Code Online (Sandbox Code Playgroud)

或者使用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);
}
Run Code Online (Sandbox Code Playgroud)