在没有固有的 WithDayOfMonth 方法的情况下使用 DateTime 将日期设置为每月第一天的最佳方法

Thi*_*mer 4 java datetime date jodatime method-signature

因此,我基本上尝试获取 2 个 DateTime 对象并将它们设置为各自月份的第一天,以便我最终可以计算两个日期之间的月份。

代码示例:

DateTime dt = new DateTime();
DateTime newDT = dt.withDayOfMonth(1);
Run Code Online (Sandbox Code Playgroud)

在任何人询问之前,实际代码将 Date 对象转换为 DateTime 对象,该对象在代码的另一部分中使用。

问题是,当我在单元测试中执行此操作时,它似乎工作得很好。但是,当我尝试使用 SOAP UI 对此进行测试时,我可以在调试过程中看到由于以下原因而出现运行时异常:

method lookup failed for selector "withDayOfMonth" with signature "(I)Lorg/joda/time/DateTime;"
Run Code Online (Sandbox Code Playgroud)

在相应的 server.txt 日志文件中,我可以看到堆栈跟踪,表明没有这样的方法没有发生

经过进一步研究,我发现我们的应用程序服务器当前使用过时版本的 JodaTime jar (1.2.1),而我的 eclipse 库包含正确的 jar (1.6.2)。

然而,现在的问题是,由于我无法访问 JodaTime 提供的 withDayOfMonth 方法,因此实现我的目标的最佳方法是什么(创建一个新的 DateTime 对象,并将该月的第一天设置为 0)?

Bas*_*que 5

太长了;博士

\n\n
LocalDate firstOfThisMonth = \n    LocalDate.now( ZoneId.of( "America/Montreal" ) )\n             .with( TemporalAdjusters.firstDayOfMonth() ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

细节

\n\n

其他答案解决了您的 Joda-Time 问题。然而,Joda-Time 项目现在处于维护模式,团队建议迁移到 java.time 类。所以这是 java.time 代码中的解决方案。

\n\n

LocalDate

\n\n

该类LocalDate表示仅日期值,没有时间和时区。

\n\n

时区对于确定日期至关重要。对于任何特定时刻,全球各地的日期都会因地区而异。例如,法国巴黎午夜过后几分钟是新的一天,而Montr\xc3\xa9al Qu\xc3\xa9bec中仍然是 \xe2\x80\x9cyesterday\xe2\x80\x9d中仍然是 \xe2\x80\x9cyesterday\xe2\x80\x9d 。

\n\n
ZoneId z = ZoneId.of( "America/Montreal" );\nLocalDate today = LocalDate.now( z );\n
Run Code Online (Sandbox Code Playgroud)\n\n

TemporalAdjuster

\n\n

java.time 中的接口TemporalAdjuster提供了类来操作值。该类TemporalAdjusters(注意复数s)提供了几种方便的调整器实现。一是firstDayOfMonth。

\n\n
LocalDate firstOfThisMonth = today.with( TemporalAdjusters.firstDayOfMonth() ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

FirstOfThisMonth.toString(): 2016-03-01

\n
\n\n

Period

\n\n

这Period跟踪未附加到时间线的时间跨度。它保留了若干年、月和日。

\n\n
LocalDate start = LocalDate.of ( 2016 , 1 , 1 ) ;\nLocalDate stop = LocalDate.of ( 2016 , 3 , 1 ) ;\nPeriod p = Period.between ( start , stop ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

调用toStringa会生成一个符合ISO 8601Period标准的字符串。

\n\n
\n

点对点

\n
\n\n

您可以要求其中一部分为数字,例如月数。

\n\n
int months = p.getMonths();\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

2

\n
\n\n

请注意,此处显示的经过时间明智地使用了半开放方法,其中开始是包含的,而结束是排除的。

\n\n

关于 java.time

\n\n

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

\n\n

Joda -Time项目目前处于维护模式,建议迁移到 java.time。

\n\n

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

\n\n

从哪里获取 java.time 类?

\n\n\n\n

ThreeTen -Extra项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如Interval、、、等等。YearWeekYearQuarter

\n