求一个方法,需求是:传入两个参数,第一个参数是开始日期,第二个参数是结束日期,计算两个日期之间的自然年,自然月,自然天,比如:从2008年1月1日到2010年2月2日,之间的自然年份是2008年和2009年,自然月是2010年1月,自然日是2010年2月1日和2月2日。
急需答案,谢谢了。
有了答案马上结贴

解决方案 »

  1.   

    年、月,是两个很模糊的概念。除非你给出详细的解释。比如2009-12-31 - 2010-01-01是隔了多少年,多少月?
    2000-01-01 - 2000-12-31 是0年还是1年(间隔366天)
    2010-01-01 - 2010-12-31 是0年还是1年(间隔365天)
    2010-01-02 - 2011-01-01 是0年还是1年,2年(间隔365天)2010-01-31 - 2010-02-01 (间隔2天) 0个月,还是1个月,还是2个月
    2010-01-01 - 2010-02-28 (间隔58天) 1个月还是2个月
    2010-01-02 - 2010-03-01 (间隔58天) 1个月,2个月还是3个月。参考.NET的TimeSpan,最高单位只到天,是有些道理的。
      

  2.   

    根本就不明白LZ的意思,汗了,自然到底是啥意思? 整年 ?整月?整天? 怎么样才算是整年?365?366? 参数是两个年,return的值又是什么呢?一个list?
      

  3.   

    迷茫,不懂什么叫自然年,自然月
    2008-05-10-->2010-02-02自然年:2008,2009
    自然月??
    自然日??你帖子所举的例子都是刚好月也大,天数也大的.
    回答一下我的这个例子看看
    还有2008-05-01-->2010-02-02自然年:2008,2009
    自然月??
    自然日??
      

  4.   

    再贴一次,写了我半天了import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;class Test {    public static void main(String[] args) {
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.set(2008, 1, 1);//2008年2月1日
            end.set(2010, 4, 5);//2010年4月5日
            List<String>[] rtnLists = getDateFigure(start.getTime(),
                    end.getTime());        for (int i = 0; i < rtnLists.length; i++) {
                List<String> lt = rtnLists[i];
                switch (i) {
                case 0:
                    System.out.println("整年");
                    break;
                case 1:
                    System.out.println("整月");
                    break;
                default:
                    System.out.println("整日");
                    break;
                }
                for (String string : lt) {
                    System.out.println(string);
                }
            }
        }    public static List<String>[] getDateFigure(Date dStart, Date dEnd) {
            List<String>[] rtnLists = (List<String>[])new List[3];
            List<String> ltYear = new ArrayList<String>();
            List<String> ltMonth = new ArrayList<String>();
            List<String> ltDay = new ArrayList<String>();
            rtnLists[0] = ltYear;
            rtnLists[1] = ltMonth;
            rtnLists[2] = ltDay;        if (dStart.after(dEnd)) {
                return rtnLists;
            }        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            Calendar start = Calendar.getInstance();
            start.setTime(dStart);
            Calendar end = Calendar.getInstance();
            end.setTime(dEnd);
            end.add(Calendar.DAY_OF_MONTH, 1);
            String s = sdf.format(start.getTime());
            start.add(Calendar.YEAR, 1);        while (end.compareTo(start) > -1) {
                start.add(Calendar.DAY_OF_MONTH, -1);
                ltYear.add(s + "-" + sdf.format(start.getTime()));
                start.add(Calendar.DAY_OF_MONTH, 1);
                s = sdf.format(start.getTime());
                start.add(Calendar.YEAR, 1);
            }
            start.add(Calendar.YEAR, -1);
            start.add(Calendar.MONTH, 1);
            while (end.compareTo(start) > -1) {
                start.add(Calendar.DAY_OF_MONTH, -1);
                ltMonth.add(s + "-" + sdf.format(start.getTime()));
                start.add(Calendar.DAY_OF_MONTH, 1);
                s = sdf.format(start.getTime());
                start.add(Calendar.MONTH, 1);
            }
            start.add(Calendar.MONTH, -1);
            while (end.after(start)) {
                start.add(Calendar.DAY_OF_MONTH, 1);
                ltDay.add(s);
                s = sdf.format(start.getTime());
            }
            return rtnLists;
        }
    }
      

  5.   

    看懂了题意,用calendar类就行,我去写了
      

  6.   

    end.set(2010, 4, 5);//2010年4月5日
    注释写错,是5月5日
      

  7.   

    那么就是说
    2010-01-01 - 2010-12-31 = 1年
    2010-01-02 - 2010-12-31 = 0年
    2010-01-01 - 2011-01-01 = 1年
    2010-07-01 - 2011-06-30 = 0年
    2010-07-01 - 2011-12-30 = 0年
    2010-07-01 - 2011-12-31 = 1年import java.util.Calendar;
    import java.util.Date;/**
     * @author michael
     * 
     */
    public class NaturalCalendar {
    public static int naturalYears(Date from, Date to) {
    if (from.after(to)) {
    throw new IllegalArgumentException("from > to");
    }
    Calendar c = Calendar.getInstance();
    c.setTime(from);
    int years = 0;
    if (c.get(Calendar.DAY_OF_YEAR) == 1) {
    years = 1;
    }
    // 以下两行设置1月1日
    c.set(Calendar.DAY_OF_YEAR, 0);
    c.add(Calendar.YEAR, 1);
    for (;;) {
    c.add(Calendar.YEAR, 1);
    if (c.getTime().after(to)) {
    break;
    }
    years++;
    }
    return years;
    }
    }
      

  8.   

    改了下,全面测试自己来了import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;class Test {    public static void main(String[] args) {
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.set(2008, 11, 1);// 2008年2月1日
            end.set(2010, 11, 30);// 2010年5月5日
            List<String>[] rtnLists = getDateFigure(start.getTime(), end.getTime());        for (int i = 0; i < rtnLists.length; i++) {
                List<String> lt = rtnLists[i];
                switch (i) {
                case 0:
                    System.out.println("整年");
                    break;
                case 1:
                    System.out.println("整月");
                    break;
                default:
                    System.out.println("整日");
                    break;
                }
                for (String string : lt) {
                    System.out.println(string);
                }
            }
        }    public static List<String>[] getDateFigure(Date dStart, Date dEnd) {
            @SuppressWarnings("unchecked")
            List<String>[] rtnLists = new List[3];        List<String> ltYear = new ArrayList<String>();
            List<String> ltMonths = new ArrayList<String>();
            List<String> ltDays = new ArrayList<String>();
            rtnLists[0] = ltYear;
            rtnLists[1] = ltMonths;
            rtnLists[2] = ltDays;
            if (dStart.after(dEnd)) {
                return rtnLists;
            }        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年");
            Calendar start = Calendar.getInstance();
            start.setTime(dStart);
            Calendar end = Calendar.getInstance();        //非1月1号
            if (start.get(Calendar.DAY_OF_YEAR) != 1) {
                //非每月1号
                if (start.get(Calendar.DAY_OF_MONTH) != 1) {
                    //设置到当年月末
                    end.set(start.get(Calendar.YEAR), start.get(Calendar.MONTH)+1, 1);
                    end.add(Calendar.DAY_OF_MONTH, -1);
                    addDays(ltDays, start, end);
                }
                //设置结束日期到年末
                end.set(start.get(Calendar.YEAR)+1, 0, 1);
                end.add(Calendar.DAY_OF_MONTH, -1);
                addMonths(ltMonths, start, end);
            }
            
            //设置结束日期
            end.setTime(dEnd);
            end.set(Calendar.DAY_OF_YEAR, 1);
            while (end.compareTo(start) >0) {
                ltYear.add(sdf.format(start.getTime()));
                start.add(Calendar.YEAR, 1);
            }
                    end.set(Calendar.DAY_OF_MONTH, 1);
            addMonths(ltMonths, start, end);
           
            //设置结束日期
            end.setTime(dEnd);
            addDays(ltDays, start, end);
            
            return rtnLists;
        }
        private static void addDays(List<String> ltDays,Calendar start,Calendar end) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            while (end.after(start)) {     
                ltDays.add(sdf.format(start.getTime()));
                start.add(Calendar.DAY_OF_MONTH, 1);
            }    }
        private static void addMonths(List<String> ltMonths,Calendar start,Calendar end) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
            while (end.after(start)) {
                ltMonths.add(sdf.format(start.getTime()));
                start.add(Calendar.MONTH, 1);
            }    }
    }
      

  9.   

     @SuppressWarnings("unchecked")在5.0的版本才能用,我的是1.4的版本,
      

  10.   

    这个去掉也不报错
    刚才有个小bug改了下
    1.4的话,你把泛型也去掉import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;class Test {    public static void main(String[] args) {
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.set(2008, 11, 1);// 2008年2月1日
            end.set(2010, 11, 30);// 2010年5月5日
            List<String>[] rtnLists = getDateFigure(start.getTime(), end.getTime());        for (int i = 0; i < rtnLists.length; i++) {
                List<String> lt = rtnLists[i];
                switch (i) {
                case 0:
                    System.out.println("整年");
                    break;
                case 1:
                    System.out.println("整月");
                    break;
                default:
                    System.out.println("整日");
                    break;
                }
                for (String string : lt) {
                    System.out.println(string);
                }
            }
        }    public static List<String>[] getDateFigure(Date dStart, Date dEnd) {
            
            List<String>[] rtnLists = new List[3];        List<String> ltYear = new ArrayList<String>();
            List<String> ltMonths = new ArrayList<String>();
            List<String> ltDays = new ArrayList<String>();
            rtnLists[0] = ltYear;
            rtnLists[1] = ltMonths;
            rtnLists[2] = ltDays;
            if (dStart.after(dEnd)) {
                return rtnLists;
            }        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年");
            Calendar start = Calendar.getInstance();
            start.setTime(dStart);
            Calendar end = Calendar.getInstance();        // 非1月1号
            if (start.get(Calendar.DAY_OF_YEAR) != 1) {
                // 非每月1号
                if (start.get(Calendar.DAY_OF_MONTH) != 1) {
                    // 设置到当年月末
                    end.set(start.get(Calendar.YEAR),
                            start.get(Calendar.MONTH) + 1, 1);
                    end.add(Calendar.DAY_OF_MONTH, -1);
                    addDays(ltDays, start, end);
                }
                // 设置结束日期到年末
                if (start.get(Calendar.MONTH) != 0) {
                    end.set(start.get(Calendar.YEAR), 11, 31);
                    addMonths(ltMonths, start, end);
                }
            }        // 设置结束日期
            end.setTime(dEnd);
            end.set(Calendar.DAY_OF_YEAR, 1);
            while (end.compareTo(start) > 0) {
                ltYear.add(sdf.format(start.getTime()));
                start.add(Calendar.YEAR, 1);
            }        end.set(Calendar.DAY_OF_MONTH, 1);
            addMonths(ltMonths, start, end);        // 设置结束日期
            end.setTime(dEnd);
            addDays(ltDays, start, end);        return rtnLists;
        }    private static void addDays(List<String> ltDays, Calendar start,
                Calendar end) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            while (end.after(start)) {
                ltDays.add(sdf.format(start.getTime()));
                start.add(Calendar.DAY_OF_MONTH, 1);
            }    }    private static void addMonths(List<String> ltMonths, Calendar start,
                Calendar end) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
            while (end.after(start)) {
                ltMonths.add(sdf.format(start.getTime()));
                start.add(Calendar.MONTH, 1);
            }    }
    }
      

  11.   

    逻辑太多了,没全考虑到,哈哈,再看看import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;class Test {    public static void main(String[] args) {
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.set(2008, 1, 2);// 2008年2月1日
            end.set(2010, 4, 5);// 2010年5月5日
            List<String>[] rtnLists = getDateFigure(start.getTime(), end.getTime());        for (int i = 0; i < rtnLists.length; i++) {
                List<String> lt = rtnLists[i];
                switch (i) {
                case 0:
                    System.out.println("整年");
                    break;
                case 1:
                    System.out.println("整月");
                    break;
                default:
                    System.out.println("整日");
                    break;
                }
                for (String string : lt) {
                    System.out.println(string);
                }
            }
        }    public static List<String>[] getDateFigure(Date dStart, Date dEnd) {
            @SuppressWarnings("unchecked")
            List<String>[] rtnLists = new List[3];        List<String> ltYear = new ArrayList<String>();
            List<String> ltMonths = new ArrayList<String>();
            List<String> ltDays = new ArrayList<String>();
            rtnLists[0] = ltYear;
            rtnLists[1] = ltMonths;
            rtnLists[2] = ltDays;
            if (dStart.after(dEnd)) {
                return rtnLists;
            }        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年");
            Calendar start = Calendar.getInstance();
            start.setTime(dStart);
            Calendar end = Calendar.getInstance();        // 非1月1号
            if (start.get(Calendar.DAY_OF_YEAR) != 1) {
                // 非每月1号
                if (start.get(Calendar.DAY_OF_MONTH) != 1) {
                    // 设置到当年月末
                    end.set(start.get(Calendar.YEAR),
                            start.get(Calendar.MONTH) + 1, 1);
                    end.add(Calendar.DAY_OF_MONTH, -1);
                    addDays(ltDays, start, end);
                }
                // 设置结束日期到年末
                if (start.get(Calendar.MONTH) != 0) {
                    end.set(start.get(Calendar.YEAR), 11, 31);
                    addMonths(ltMonths, start, end);
                }
            }        // 设置结束日期
            end.setTime(dEnd);
            if (end.get(Calendar.MONTH)==11 && end.get(Calendar.DAY_OF_MONTH)==31) {
                end.add(Calendar.YEAR, 1);
            }
            end.set(Calendar.DAY_OF_YEAR, 1);
            end.set(Calendar.MONTH, 0);
            while (end.after(start)) {
                ltYear.add(sdf.format(start.getTime()));
                start.add(Calendar.YEAR, 1);
            }        // 设置结束日期
            end.setTime(dEnd);
            end.set(Calendar.DAY_OF_MONTH, 1);
            addMonths(ltMonths, start, end);        // 设置结束日期
            end.setTime(dEnd);
            end.add(Calendar.DAY_OF_YEAR, 1);
            addDays(ltDays, start, end);
            
            return rtnLists;
        }    private static void addDays(List<String> ltDays, Calendar start,
                Calendar end) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            while (end.after(start)) {
                ltDays.add(sdf.format(start.getTime()));
                start.add(Calendar.DAY_OF_MONTH, 1);
            }    }    private static void addMonths(List<String> ltMonths, Calendar start,
                Calendar end) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
            while (end.after(start)) {
                ltMonths.add(sdf.format(start.getTime()));
                start.add(Calendar.MONTH, 1);
            }    }
    }
      

  12.   

    就是这个结果,非常感谢你,帮了我很大的忙,我对Date相关的类不太熟,自己写起来很吃力,以后还要好好的学习,不懂的太多了。晚上还要好好的研究一下你的代码,看看你是怎么具体实现的,向你学习了。80%的分数都会赠送给你。
      

  13.   

    楼主把LIST改为数组来存放,速度要更快..
      

  14.   

    没办法用数组,长度不固定。
    ArrayList本身也是数组实现。
      

  15.   

    刚才的source漏了同一年的计算,补上import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;class Test {    public static void main(String[] args) {
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            start.set(2008, 1, 1);// 2008年2月1日
            end.set(2010, 4, 5);// 2010年5月5日
            List<String>[] rtnLists = getDateFigure(start.getTime(), end.getTime());        for (int i = 0; i < rtnLists.length; i++) {
                List<String> lt = rtnLists[i];
                switch (i) {
                case 0:
                    System.out.println("整年");
                    break;
                case 1:
                    System.out.println("整月");
                    break;
                default:
                    System.out.println("整日");
                    break;
                }
                for (String string : lt) {
                    System.out.println(string);
                }
            }
        }    public static List<String>[] getDateFigure(Date dStart, Date dEnd) {
            @SuppressWarnings("unchecked")
            List<String>[] rtnLists = new List[3];        List<String> ltYear = new ArrayList<String>();
            List<String> ltMonths = new ArrayList<String>();
            List<String> ltDays = new ArrayList<String>();
            rtnLists[0] = ltYear;
            rtnLists[1] = ltMonths;
            rtnLists[2] = ltDays;
            if (dStart.after(dEnd)) {
                return rtnLists;
            }        SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy年");
            SimpleDateFormat sdfMonth = new SimpleDateFormat("yyyy年MM月");
            SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy年MM月dd日");
            Calendar start = Calendar.getInstance();
            start.setTime(dStart);
            Calendar end = Calendar.getInstance();        // 非1月1号
            if (start.get(Calendar.DAY_OF_YEAR) != 1) {
                // 非每月1号
                if (start.get(Calendar.DAY_OF_MONTH) != 1) {
                    // 设置到当年月末
                    end.set(start.get(Calendar.YEAR),
                            start.get(Calendar.MONTH) + 1, 1);
                    end.add(Calendar.DAY_OF_MONTH, -1);
                    if (end.getTime().after(dEnd)) {
                        end.setTime(dEnd);
                    }
                    add(sdfDay,Calendar.DAY_OF_MONTH,ltDays, start, end);
                }
                // 设置结束日期到年末
                if (start.get(Calendar.MONTH) != 0) {
                    end.set(start.get(Calendar.YEAR), 11, 31);
                    if (end.getTime().after(dEnd)) {
                        end.setTime(dEnd);
                        end.set(Calendar.DAY_OF_MONTH, 1);
                    }
                    add(sdfMonth,Calendar.MONTH,ltMonths, start, end);
                }
            }        // 设置结束日期
            end.setTime(dEnd);
            if (end.get(Calendar.MONTH)==11 && end.get(Calendar.DAY_OF_MONTH)==31) {
                end.add(Calendar.YEAR, 1);
            }
            end.set(Calendar.DAY_OF_YEAR, 1);
            end.set(Calendar.MONTH, 0);
            add(sdfYear,Calendar.YEAR,ltYear,start,end);
            // 设置结束日期
            end.setTime(dEnd);
            end.set(Calendar.DAY_OF_MONTH, 1);
            add(sdfMonth,Calendar.MONTH,ltMonths, start, end);        // 设置结束日期
            end.setTime(dEnd);
            end.add(Calendar.DAY_OF_YEAR, 1);
            add(sdfDay,Calendar.DAY_OF_MONTH,ltDays, start, end);
            
            return rtnLists;
        }
            private static void add(SimpleDateFormat sdf,int step,List<String> lts, Calendar start,
                Calendar end) {
           
            while (end.after(start)) {
                lts.add(sdf.format(start.getTime()));
                start.add(step, 1);
            }    }
    }