I have the following java code to get the date of a specific week day:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.YEAR, 2010);
cal.set(Calendar.WEEK_OF_YEAR, 37); //week 37 of year 2010
cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
System.out.println("date="+sdf.format(cal.getTime()));
When I put this code in a main(String[] args)
method, like the following:
import java.util.*;
import java.lang.*;
import java.text.SimpleDateFormat;
public class test{
public static void main(String[] args){
/** get dates from a known week ID **/
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.YEAR, 2010);
cal.set(Calendar.WEEK_OF_YEAR, 37);
cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
System.out.println("date="+sdf.format(cal.getTime()));
}
}
and run it, I get the correct result which is date=09/09/2010
. There is no problem.
HOWEVER...
When I put this code in a function of a Class, like the following:
Public Class MyService{
MyService(){}
...
...
public String getDateOfWeekDay(int weekId, int year, int weekDay){
//weekId = 37; year=2010; weekDay = Calendar.THURSDAY
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, weekId);
cal.set(Calendar.DAY_OF_WEEK, weekDay);
//I am developing android app. so I use Log to printout
logPrinter.println("date="+sdf.format(cal.getTime()));
return sdf.format(cal.getTime());
}
}
in another class MainClass, MainClass will invoke this service function like following:
Public Class MainClass{
MyService myService = new MyService();
myService.getDateOfWeekDay(37,2010,Calendar.THURSDAY);
}
But the result returned is always the date of the current week's thursday (date=14/10/2010), not the Thursday of the week which I specified (week 37, year 2010, Thursday). WHY???? I use exactly the same java code to get the date of the specific week day, only used it in different ways, why the result is different???? I can not understand this...Anybody can explain to me??
Yes, JodaTime is wonderful, but I'll bet you'd rather know what's wrong with your stuff.
Adding another JAR dependency might be a problem for a mobile device.
That method isn't good, IMO. The name is a misnomer, and it's doing too many things. You're creating a String, not a Date, and you're printing to a log. I'd recommend returning a Date and let clients worry about whether they want to turn it into a String. Logging is a cross-cutting concern.
Here's a class (and a JUnit test) that works. See what's different:
package util;
import java.util.Calendar;
import java.util.Date;
public class DateUtils
{
public static Date getDateOfWeekDay(int weekId, int year, int weekDay)
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, weekId);
cal.set(Calendar.DAY_OF_WEEK, weekDay);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
}
JUnit test:
package util;
import org.junit.Assert;
import org.junit.Test;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* DateUtilsTest
* User: Michael
* Date: 10/16/10
* Time: 10:40 AM
*/
public class DateUtilsTest
{
public static final DateFormat DEFAULT_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
@Test
public void testNewYearsDayLastYear() throws ParseException
{
Date expected = DEFAULT_FORMAT.parse("1/1/2009");
Date actual = DateUtils.getDateOfWeekDay(1, 2009, Calendar.THURSDAY);
Assert.assertEquals(expected, actual);
}
@Test
public void testTaxDay() throws ParseException
{
Date expected = DEFAULT_FORMAT.parse("15/4/2010");
Date actual = DateUtils.getDateOfWeekDay(16, 2010, Calendar.THURSDAY);
Assert.assertEquals(expected, actual);
}
@Test
public void testGetDateOfWeekDay() throws ParseException
{
Date expected = DEFAULT_FORMAT.parse("16/10/2010");
Calendar calendar = Calendar.getInstance();
calendar.setTime(expected);
int week = calendar.get(Calendar.WEEK_OF_YEAR);
int year = calendar.get(Calendar.YEAR);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
Date actual = DateUtils.getDateOfWeekDay(week, year, dayOfWeek);
Assert.assertEquals(expected, actual);
}
}
It's becoming a rote answer around here, but: Use JodaTime or one of the alternatives. Investing precious cycles into understanding the JDK calendar API is throwing good money after bad.
Related on SO: Should I use native date/time; I see (now) you're doing Android development, which I can't speak to, but on SO: JodaTime on Android?
If you're insisting on JDK, I did try your code, with a slight modification. First, I'd eliminate the cal.setTime(new Date())
-- it's not doing anything, and it's confusing since it might (seem to) correlate to always getting a date around "now," since new Date()
gives you now. However, in your code, it still should be overridden by the following setX calls.
class DateTest
{
DateTest(){}
public String getDateOfWeekDay(int weekId, int year, int weekDay){
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, weekId);
cal.set(Calendar.DAY_OF_WEEK, weekDay);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
System.out.println("date="+sdf.format(cal.getTime()));
return sdf.format(cal.getTime());
}
public static void main(String args[])
{
DateTest dt = new DateTest();
for (int weekCount = 1; weekCount <= 53; weekCount++) {
dt.getDateOfWeekDay(weekCount,2010,Calendar.THURSDAY);
}
}
}
And I get exactly what I expect:
date=31/12/2009
date=07/01/2010
...
date=23/12/2010
date=30/12/2010
Do you see different?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With