如何将年和星期转换为Java日期对象?我正在使用JodaTime,但使用解决方案的标准Java类也很好。
使用标准java类的解决方案。这只是获取当前时间,并将年份和年份中的星期字段设置为已知值。
Calendar cld = Calendar.getInstance();
cld.set(Calendar.YEAR, year);
cld.set(Calendar.WEEK_OF_YEAR, week);
Date result = cld.getTime();
br
YearWeek.of( 2016 , 1 )
.atDay( DayOfWeek.MONDAY )
2016-01-04
年-周不是日期
严格地说,不能从年份和星期数中得到日期。但我将继续假设你打算得到任何一年的一周的第一天。周号码。
使用java.time现代的方法是java。时间类取代了麻烦的旧的遗留日期-时间类。
WeekFields
类使您能够使用一年中的周。
Locale
定义周
一年中的星期有许多定义。这个示例代码使用JVM当前默认的Locale
来确定定义。
int year = 2016;
int week = 1;
int dayOfWeek = 1; // 1-7, locale-dependent such as Sunday-Monday in US.
WeekFields weekFields = WeekFields.of ( Locale.CANADA_FRENCH );
LocalDate ld = LocalDate.now ( )
.withYear ( year )
.with ( weekFields.weekOfYear ( ), week )
.with ( weekFields.dayOfWeek ( ), 1 );
System.out.println ( "ld: " + ld );
请注意,在周的定义中,一年(2016)开始时一周的第一天实际上是靠近上一年(2015)结束的一天。
2015-12-27
ISO 8601标准周
您的企业可以选择采用ISO 8601周标准。在这个简单的方案中,周编号# 1包含日历年的第一个星期四,并且一周从星期一到星期天。一年有52周或53周。
与上面的代码相同,但是我们用ISO定义的常量WeekFields.ISO
替换掉依赖于语言环境的WeekFields
对象。但是我们得到了一个非常不同的结果,2016-01-04
而不是2015-12-27
。
int year = 2016;
int week = 1;
int dayOfWeek = 1; // 1-7, locale-dependent such as Sunday-Monday in US.
WeekFields weekFields = WeekFields.ISO;
LocalDate ld = LocalDate.now ( )
.withYear ( year )
.with ( weekFields.weekOfYear ( ), week )
.with ( weekFields.dayOfWeek ( ), 1 );
System.out.println ( "ld: " + ld );
2016-01-04
YearWeek
如果您将ThreeTen-Extra库添加到您的项目中,这项工作将更容易。您可以将YearWeek
类用于标准ISO 8601周。
不要将日历年的数字与以周为基础的年的数字混淆。
YearWeek yw = YearWeek.of( 2016 , 1 ); // Passing a week-based-year number, *NOT* a calendar year.
toString
方法生成yyyy-Www
(如2016-W01
)的标准ISO 8601格式的字符串。
要获得特定的日期,使用Java的DayOfWeek
枚举对象指定星期几。
LocalDate ld = yw.atDay( DayOfWeek.MONDAY );
您可以询问以周为基础的年份是52周还是53周。
int weeksInWeekBasedYear = yw.lengthOfYear();
关于java.time
java。时间框架内置于Java 8及以后版本中。这些类取代了麻烦的旧的遗留日期时间类,如java.util.Date
, Calendar
, &SimpleDateFormat
.
Joda-Time项目现在处于维护模式,建议迁移到java。时间类。
要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获得许多示例和解释。规格为JSR 310。
从哪里获取java。时间类?
- Java SE 8和SE 9及以后版本
- 内置。
- 标准Java API的一部分,捆绑实现。
Java 9增加了一些小的特性和修复。
- 大部分java。时间功能向后移植到Java 6;7在 ThreeTen-Backport 。
- ThreeTenABP项目专门为Android适配ThreeTen-Backport(上文提到)。
Interval
、YearWeek
、YearQuarter
等。
您可以使用已弃用的java.util.Date(int,int,int,int,int,int)
构造函数,例如new Date(2011,2,12,10,13,13);
或
使用java.util.Calendar
并使用其set(int,int)
方法(例如,c.set(Calendar.DAY_OF_MONTH,22);
将日期设置为22),您可以使用Calendar.getTime()
将当前日历时间设置为java.util.Date
。日期构造函数和日历之间的区别在于,只有日历能够创建与UTC不同时区的日期(这也是日期构造函数被弃用的原因)。
我没有使用过Joda-Time(尽管我听说它很棒),但我认为将DateTime
构造函数和方便的plusWeeks
方法结合起来应该可以达到目的。例如:
DateTime dt = new DateTime(theYear, 1, 1, 0, 0, 0, 0).plusWeeks(theWeeks);
…因为Joda-Time显然使用基于1的月份和天数,以及基于0的时间。
这段带有org.joda.time.DateTime的丑陋代码为我工作了。方法plusWeeks不起作用,因为它没有将日期移动到一周的开始。如果在星期四后面加上几周,那么结果日期也是星期四。
DateTime startOfTheWeek = new DateTime().withYear(2016).withWeekOfWeekyear(52)
.withDayOfWeek(1).withTimeAtStartOfDay();
DateTime endOfTheWeek = startOfTheWeek.withDayOfWeek(7).withTime(23,59,59,999);
System.out.println("Start date: " + startOfTheWeek.toDate());
System.out.println("End date: " + endOfTheWeek.toDate());
输出如下:
Start date: Mon Dec 26 00:00:00 EET 2016
End date: Sun Jan 01 23:59:59 EET 2017