我有以下java代码来获取特定工作日的日期:
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()));
当我将此代码放入main(String[] args)
方法时,如下所示:
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()));
}
}
并运行它,我得到正确的结果date=09/09/2010
。没问题。
无论其...
当我将此代码放在Class的函数中时,如下所示:
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());
}
}
在另一个类MainClass中,MainClass将调用此服务函数,如下所示:
Public Class MainClass{
MyService myService = new MyService();
myService.getDateOfWeekDay(37,2010,Calendar.THURSDAY);
}
但返回的结果始终是当前周的星期四(日期= 2010年10月14日)的日期,而不是我指定的周的星期四(第37周,2010年,星期四) )。 为什么????我使用完全相同的java代码来获取特定工作日的日期,只是以不同的方式使用它,为什么结果不同????我无法理解这一点......有人可以向我解释一下吗?
答案 0 :(得分:4)
是的,JodaTime很精彩,但我敢打赌,你宁愿知道你的东西有什么问题。
添加另一个JAR依赖项可能是移动设备的问题。
这种方法不好,IMO。这个名字用词不当,它做的事情太多了。您正在创建一个字符串,而不是日期,并且您正在打印到日志。我建议返回一个Date,让客户担心他们是否想把它变成一个String。记录是一个贯穿各领域的问题。
这是一个有效的类(和JUnit测试)。看看有什么不同:
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测试:
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);
}
}
答案 1 :(得分:3)
这是一个死记硬背的答案,但是:使用JodaTime或其中一个替代方案。投入宝贵的周期来理解JDK日历API在糟糕的情况下投入了大量资金。
与SO相关:Should I use native date/time;我看到(现在)你正在进行Android开发,我无法与之交谈,但在SO:JodaTime on Android?
如果您坚持使用JDK,我会尝试您的代码,稍作修改。首先,我要消除cal.setTime(new Date())
- 它没有做任何事情,而且它很混乱,因为它可能(似乎)与始终获得“现在”的约会相关,因为new Date()
现在给你。但是,在您的代码中,它仍然应该被以下setX调用覆盖。
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);
}
}
}
我完全得到了我的期望:
date=31/12/2009
date=07/01/2010
...
date=23/12/2010
date=30/12/2010
你看到不同吗?
答案 2 :(得分:1)
public class CalendarTest {
public static String getDateOfWeekDay(int weekId, int year, int weekDay) {
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);
return sdf.format(cal.getTime());
}
public static void main(String[] args) {
String someDay = getDateOfWeekDay(37,2010,Calendar.THURSDAY);
System.out.println(someDay);
}
}
输出 16/09/2010
public class CalendarTest {
public static void main(String[] args) {
MyService s = new MyService();
String someDay = s.getDateOfWeekDay(37, 2010, Calendar.THURSDAY);
System.out.println(someDay);
}
}
class MyService {
public String getDateOfWeekDay(int weekId, int year, int weekDay) {
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);
return sdf.format(cal.getTime());
}
}
答案 3 :(得分:0)
好吧,因为这些答案不是回答你的实际问题,而是建议使用JodaTime,我会推荐反对 JodaTime。
日期/日历以及JodaTime存在重大设计缺陷(引用作者),如果您计划使用时间和日期,请使用JSR-310。
JSR-310是Date / Calendar和JodaTime的替代品,它更加一致并且比两者都更好。需要考虑的问题包括JSR-310 in Java 7。
无论是否有效,今天都可以使用它。它只是一个像JodaTime这样的jar文件。
好处是:
如果您对此主题感兴趣: