我编写了以下Java代码,以获得一年中第一天的第一天。
Calendar cal = Calendar.getInstance(Locale.GERMAN);
cal.clear();
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, Calendar.MONDAY);
cal.set(Calendar.YEAR, 2016);
cal.set(Calendar.WEEK_OF_YEAR, weekNumber);
DateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
System.out.println( sdf.format(cal.getTime()) );
通过使用53年的输入周,它应该导致错误,因为2016年不存在这一周。相反,它显示了明年可能的第一个日期。
是否有一种简洁的方法来纠正我的代码,或者我必须自己检查一年中的输入周?
感谢您的帮助。
答案 0 :(得分:0)
如果您的意思是标准的ISO 8601周,请使用YearWeek
库中的ThreeTen-Extra课程。
针对特定周工作年的特定周数:
YearWeek.of( // Standard ISO 8601 week, where week # 1 has the first Thursday of the calendar year, and runs Monday-Sunday.
2018 , // Week-based year, NOT calendar year.
37 // Week-of-week-based-year. Runs 1-52 or 1-53.
)
.atDay( DayOfWeek.MONDAY ) // Returns a `LocalDate` object.
if如果输入无效,则java.time.DateTimeException
的陷阱,如果该周基于年份没有这样的一周。
本周:
YearWeek.now( // Standard ISO 8601 week, where week # 1 has the first Thursday of the calendar year, and runs Monday-Sunday.
ZoneId.of( "Pacific/Auckland" ) // Determining a week means determining a date, and that requires a time zone. For any given moment, the date varies around the globe by zone.
)
.atDay( DayOfWeek.MONDAY ) // Returns a `LocalDate` object.
用“周”定义你的意思。第1周是1月1日吗?在新的一年中,第一周是第一个将所有七天组成的日子吗?如果是这样,一周的最后几天,周日 - 周六或周一 - 周日或其他什么?或者第一周是第一周的某一天?
麻烦的旧日期时间类根据Locale
定义一周。如果未指定Locale
,则会默默隐式应用JVM的当前默认值Locale
。所以你的结果在运行时会有所不同。
如果可能,我建议使用标准ISO 8601 week定义。本周从周一至周日开始,第一周包含该日历年的第一个星期四。所以每年有52或53周。
获取当前日期意味着获取当前日期。时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
如果未指定时区,则JVM会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果要使用JVM的当前默认时区,请求它并作为参数传递。如果省略,则隐式应用JVM的当前默认值。最好是明确的,因为默认情况下可以在运行时期间由JVM中任何应用程序的任何线程中的任何代码随时更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
如果你只是想在那个日期或之前的某个星期,那么就不要在意这一周。使用TemporalAdjuster
中的TemporalAjdusters
实施。通过DayOfWeek
枚举确定您的星期几。
LocalDate mondayOnOrBeforeToday = today.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) ) ;
如果您确实希望使用ISO 8601 weeks,IsoFields
课程中提供的支持有限。但我建议您将ThreeTen-Extra库添加到项目中。该库提供了额外的日期时间类,补充了Java SE 8及更高版本中内置的类。特别是,你得到了YearWeek
类。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
YearWeek yw = YearWeek.now( z ) ;
要求该周的某一天的LocalDate
。
LocalDate ld = yw.atDay( DayOfWeek.MONDAY ) ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。