下个月的第一天用java Joda-Time

时间:2011-01-24 19:25:21

标签: java calendar jodatime

如何使用Joda-Time中的org.joda.time包重写下面的方法,该方法会返回下个月的第一天?

public static Date firstDayOfNextMonth() {
    Calendar nowCal = Calendar.getInstance();
    int month = nowCal.get(Calendar.MONTH) + 1;
    int year = nowCal.get(Calendar.YEAR);

    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    Date dueDate = new Date(cal.getTimeInMillis());

    return dueDate;
}

6 个答案:

答案 0 :(得分:45)

   LocalDate today = new LocalDate();
   LocalDate d1 = today.plusMonths(1).withDayOfMonth(1);

有点容易和清洁,不是吗? : - )

更新:如果您想要返回日期:

return new Date(d1.toDateTimeAtStartOfDay().getMillis());

但我强烈建议您避免将纯DATE类型(即日历中的一天,没有时间信息)与DATETIME类型混合,特别是“物理”日期时间类型与可疑java.util.Date混合。它有点像转换为整数和浮动类型,你必须小心。

答案 1 :(得分:21)

我假设你想要返回一个Date对象,所以:

public static Date firstDayOfNextMonth() {
    MutableDateTime mdt = new MutableDateTime();
    mdt.addMonths(1);
    mdt.setDayOfMonth(1);
    mdt.setMillisOfDay(0); // if you want to make sure you're at midnight
    return mdt.toDate();
}

答案 2 :(得分:15)

约达时间

以下是我使用Joda-Time 2.3。

对此问题的看法

不可变

通常,您应该使用Joda-Time类的immutable版本。几乎所有方法都返回DateTime的新实例,而不是修改现有实例。简化事物,并实现自动线程安全。

开始的日

使用较新的方法withTimeAtStartOfDay(),而不是将时间设置为零。由于夏令时(DST)和其他异常,在某些时区的某些日子里,没有午夜时间或00:00:00时间。

转换:j.u.Date↔DateTime

要将Joda-Time DateTime实例转换为java.util.Date实例,只需调用toDate方法即可。在Date上不需要构造函数。

另一方面,如果你有一个java.util.Date并想要一个Joda-Time DateTime,只需将Date传递给DateTime的构造函数以及所需的DateTimeZone对象。

示例代码

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
// Usually better to specify a time zone rather than rely on default.
DateTime now = new DateTime( timeZone ); // Or, for default time zone: new DateTime()
DateTime monthFromNow = now.plusMonths(1);
DateTime firstOfNextMonth = monthFromNow.dayOfMonth().withMinimumValue();
DateTime firstMomentOfFirstOfNextMonth = firstOfNextMonth.withTimeAtStartOfDay();

或者,如果你是一个疯子,那么所有这些字符串都在一行代码中。

DateTime allInOneLine = new DateTime( DateTimeZone.forID( "Europe/Paris" ) ).plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();

转换为旧的java.util.Date以与其他类/库进行交互。

java.util.Date date = firstMomentOfFirstOfNextMonth.toDate();

转储到控制台...

System.out.println( "now: " + now );
System.out.println( "monthFromNow: " + monthFromNow );
System.out.println( "firstOfNextMonth: " + firstOfNextMonth );
System.out.println( "firstMomentOfFirstOfNextMonth: " + firstMomentOfFirstOfNextMonth );
System.out.println( "allInOneLine: " + allInOneLine );
System.out.println( "date: " + date );

跑步时......

now: 2014-01-21T02:46:16.834+01:00
monthFromNow: 2014-02-21T02:46:16.834+01:00
firstOfNextMonth: 2014-02-01T02:46:16.834+01:00
firstMomentOfFirstOfNextMonth: 2014-02-01T00:00:00.000+01:00
allInOneLine: 2014-02-01T00:00:00.000+01:00
date: Fri Jan 31 15:00:00 PST 2014

java.time

Java 8及更高版本中内置的java.time框架取代了旧的java.util.Date/.Calendar类。受Joda-Time的启发,并打算成为其继任者。

这些新类包括TemporalAdjuster接口(Tutorial)和TemporalAdjusters中的一堆实现(请注意复数s)。恰好只有我们需要的调节器:firstDayOfNextMonth

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
LocalDate firstOfNextMonth = today.with ( TemporalAdjusters.firstDayOfNextMonth () );

转储到控制台。

System.out.println ( "today: " + today + "  |  firstOfNextMonth: " + firstOfNextMonth );
  

今天:2015-12-22 | firstOfNextMonth:2016-01-01

如果您想要日期时间而不是仅限日期,请调整。

ZonedDateTime zdt = firstOfNextMonth.atStartOfDay( zoneId );

如果您需要使用旧的java.util.Date来操作尚未更新为java.time的旧类,请从ZonedDateTime对象中提取的Instant进行转换。 “即时”是UTC时间轴上的一个时刻。

java.util.Date date = java.util.Date.from( zdt.toInstant() );

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 3 :(得分:6)

在Joda API中有一种方法:

Date date = new LocalDate().plusMonths(1).dayOfMonth().withMinimumValue().toDate();

希望它有所帮助!

答案 4 :(得分:2)

与之前相同,但也转换为java.util.Date

日期firstDayOfNextMonth =(new LocalDate()。plusMonths(1).withDayOfMonth(1))。toDate();

答案 5 :(得分:1)

localDate = new LocalDate()。plusMonths(1).withDayOfMonth(1);