How can I 开发者_如何学编程convert year and week to Java Date object? I'm using JodaTime, but standard Java classes using solution is fine too.
Solution using standard java classes. This just gets the current time and sets the fields of year and week of year to known values.
Calendar cld = Calendar.getInstance();
cld.set(Calendar.YEAR, year);
cld.set(Calendar.WEEK_OF_YEAR, week);
Date result = cld.getTime();
you could use the deprecated java.util.Date(int,int,int,int,int,int)
constructor, e.g new Date(2011,2,12,10,13,13);
or
use a java.util.Calendar
and use its set(int,int)
methods (e.g. c.set(Calendar.DAY_OF_MONTH,22);
to set the day to 22) The you can use Calendar.getTime()
to get the current calendar time back as java.util.Date
. The difference between the date contructor and the calendar is, that only calendar is capable of creating dates for different time zones than UTC (whic also is the reason for the date constructor to be deprecated).
I haven't used Joda-Time (although I hear it's great), but I'm thinking a combination of the DateTime
constructor and the handy plusWeeks
method should do the trick. E.g.:
DateTime dt = new DateTime(theYear, 1, 1, 0, 0, 0, 0).plusWeeks(theWeeks);
...since Joda-Time apparently uses 1-based months and days, and zero-based times.
This piece of pretty ugly code with org.joda.time.DateTime worked for me. Method plusWeeks doesn't work since it doesn't move the date to start of the week. If you add weeks to Thursday then the resulting date is Thursday too.
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());
This prints out something like:
Start date: Mon Dec 26 00:00:00 EET 2016
End date: Sun Jan 01 23:59:59 EET 2017
tl;dr
YearWeek.of( 2016 , 1 )
.atDay( DayOfWeek.MONDAY )
2016-01-04
Year-Week is not a date
You cannot, strictly speaking, get a date from a year and a week number. But I will proceed assuming you meant to get the first day of the week for any given year & week number.
Using java.time
The modern approach is with the java.time classes that supplant the troublesome old legacy date-time classes.
The WeekFields
class gives you way to work with week-of-year.
Locale
defined weeks
There are many definitions of week-of-year. This example code uses the JVM’s current default Locale
to determine a definition.
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 );
Notice how in this definition of weeks, the first day of the week at the beginning of the year (2016) is actually a day near the end of the previous year (2015).
2015-12-27
ISO 8601 standard weeks
Your business may choose to adopt standard ISO 8601 weeks. In this simple scheme, week number # 1 contains the first Thursday of the calendar year, and the week runs Monday-Sunday. A year has either 52 or 53 weeks.
Same code as above, but we switch out the Locale-dependent WeekFields
object with the constant ISO defined one, WeekFields.ISO
. But we get a very different result, 2016-01-04
rather than 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
This work is easier if you add the ThreeTen-Extra library to your project. You can use the YearWeek
class for standard ISO 8601 weeks.
Do not confuse the calendar year number with the number of a week-based-year.
YearWeek yw = YearWeek.of( 2016 , 1 ); // Passing a week-based-year number, *NOT* a calendar year.
The toString
method produces a String in standard ISO 8601 format of yyyy-Www
such as 2016-W01
.
To get a certain date, specify the day-of-week using Java’s DayOfWeek
enum objects.
LocalDate ld = yw.atDay( DayOfWeek.MONDAY );
You can ask if the week-based-year has 52 or 53 weeks.
int weeksInWeekBasedYear = yw.lengthOfYear();
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
- Java SE 8 and SE 9 and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
- See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
精彩评论