2011-10-26 51 views
39

我想从某个日期开始确定年龄。有谁知道一个干净的方式来做到这一点在Android?我明显可以看到Java API,但直接使用的java api非常薄弱,我希望Android能够帮助我。如何找到两个日期之间的年数?

编辑:在Android中使用Joda时间的多个建议令我担心Android Java - Joda Date is slow和相关问题。另外,拉入一个没有与该平台一起发布的库可能会造成这种大小的问题。

+0

一个类似的问题:http://stackoverflow.com/questions/1116123/how-do-i-calculate-someones-age-in-java – jeha

回答

72
public static int getDiffYears(Date first, Date last) { 
    Calendar a = getCalendar(first); 
    Calendar b = getCalendar(last); 
    int diff = b.get(YEAR) - a.get(YEAR); 
    if (a.get(MONTH) > b.get(MONTH) || 
     (a.get(MONTH) == b.get(MONTH) && a.get(DATE) > b.get(DATE))) { 
     diff--; 
    } 
    return diff; 
} 

public static Calendar getCalendar(Date date) { 
    Calendar cal = Calendar.getInstance(Locale.US); 
    cal.setTime(date); 
    return cal; 
} 
+4

什么是常量MONTH,YEAR和DATE? –

+4

@ChrisSim:它们是Calendar.MONTH等的静态导入。 – sinuhepop

+1

我认为应该是DAY_OF_MONTH而不是DATE。 – jiahao

14

我会推荐使用伟大的Joda-Time库来处理与Java相关的所有日期。

为了您的需要,您可以使用Years.yearsBetween()方法。

+0

我用乔达很多这样的最后一个项目。这是真的结束了在设置方面杀... – StarWind0

+1

只是为了阐述: '公众诠释getYears(org.java.util.Date时间){ org.joda.time.DateTime现在= org.joda.time。 DateTime.now(); org.joda.time.DateTime then = new org.joda.time.DateTime(time.getTime()); return org.joda.time.Years.yearsBetween(now,then).getYears(); }' – Nielsvh

0

如果你不想使用Java的日历来计算它,你可以使用Androids Time class这应该是更快,但我没有注意到,当我切换时没有太大的区别。

我无法找到任何预定义的函数来确定Android中某个年龄段的2个日期之间的时间。在DateUtils之间有一些不错的帮助函数可以在日期之间获得格式化时间,但这可能不是您想要的。

0

我知道你问一个干净的解决方案,但这里有两个脏一次:

 static void diffYears1() 
{ 
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 
    Calendar calendar1 = Calendar.getInstance(); // now 
    String toDate = dateFormat.format(calendar1.getTime()); 

    Calendar calendar2 = Calendar.getInstance(); 
    calendar2.add(Calendar.DAY_OF_YEAR, -7000); // some date in the past 
    String fromDate = dateFormat.format(calendar2.getTime()); 

    // just simply add one year at a time to the earlier date until it becomes later then the other one 
    int years = 0; 
    while(true) 
    { 
     calendar2.add(Calendar.YEAR, 1); 
     if(calendar2.getTimeInMillis() < calendar1.getTimeInMillis()) 
      years++; 
     else 
      break; 
    } 

    System.out.println(years + " years between " + fromDate + " and " + toDate); 
} 

static void diffYears2() 
{ 
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 
    Calendar calendar1 = Calendar.getInstance(); // now 
    String toDate = dateFormat.format(calendar1.getTime()); 

    Calendar calendar2 = Calendar.getInstance(); 
    calendar2.add(Calendar.DAY_OF_YEAR, -7000); // some date in the past 
    String fromDate = dateFormat.format(calendar2.getTime()); 

    // first get the years difference from the dates themselves 
    int years = calendar1.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR); 
    // now make the earlier date the same year as the later 
    calendar2.set(Calendar.YEAR, calendar1.get(Calendar.YEAR)); 
    // and see if new date become later, if so then one year was not whole, so subtract 1 
    if(calendar2.getTimeInMillis() > calendar1.getTimeInMillis()) 
     years--; 

    System.out.println(years + " years between " + fromDate + " and " + toDate); 
} 
-1

试试这个:

int getYear(Date date1,Date date2){ 
     SimpleDateFormat simpleDateformat=new SimpleDateFormat("yyyy"); 
     Integer.parseInt(simpleDateformat.format(date1)); 

     return Integer.parseInt(simpleDateformat.format(date2))- Integer.parseInt(simpleDateformat.format(date1)); 

    } 
+1

@Johnny Graber谨慎解释你为什么选择了这个... ehem ...次优的答案? – kleopatra

+0

Downvoted,因为这不需要考虑日子。 – leparlon

1

我显然不能发表评论还,但我认为你可以使用DAY_OF_YEAR锻炼,如果你应该调整一年(从当前最佳答案复制并修改)

public static int getDiffYears(Date first, Date last) { 
    Calendar a = getCalendar(first); 
    Calendar b = getCalendar(last); 
    int diff = b.get(Calendar.YEAR) - a.get(Calendar.YEAR); 
    if (a.get(Calendar.DAY_OF_YEAR) > b.get(Calendar.DAY_OF_YEAR)) { 
     diff--; 
    } 
    return diff; 
} 

public static Calendar getCalendar(Date date) { 
    Calendar cal = Calendar.getInstance(Locale.US); 
    cal.setTime(date); 
    return cal; 
} 

类似地,您可能只是将时间的ms表示除以一年中的ms数。把所有东西放在很长的时间里,大多数情况下都应该足够好(闰年,哎哟),但是这取决于你的应用程序的年数以及这个函数的性能表现如何,值得这种破解。

+0

使用DAY_OF_YEAR导致闰年的错误。 – sinuhepop

0
// int year =2000; int month =9 ; int day=30; 

    public int getAge (int year, int month, int day) { 

      GregorianCalendar cal = new GregorianCalendar(); 
      int y, m, d, noofyears;   

      y = cal.get(Calendar.YEAR);// current year , 
      m = cal.get(Calendar.MONTH);// current month 
      d = cal.get(Calendar.DAY_OF_MONTH);//current day 
      cal.set(year, month, day);// here ur date 
      noofyears = y - cal.get(Calendar.YEAR); 
      if ((m < cal.get(Calendar.MONTH)) 
          || ((m == cal.get(Calendar.MONTH)) && (d < cal 
              .get(Calendar.DAY_OF_MONTH)))) { 
        --noofyears; 
      } 
      if(noofyears < 0) 
        throw new IllegalArgumentException("age < 0"); 
      System.out.println(noofyears); 
      return noofyears; 
1

这就是我认为这是一个更好的方法:

public int getYearsBetweenDates(Date first, Date second) { 
    Calendar firstCal = GregorianCalendar.getInstance(); 
    Calendar secondCal = GregorianCalendar.getInstance(); 

    firstCal.setTime(first); 
    secondCal.setTime(second); 

    secondCal.add(Calendar.DAY_OF_YEAR, 1 - firstCal.get(Calendar.DAY_OF_YEAR)); 

    return secondCal.get(Calendar.YEAR) - firstCal.get(Calendar.YEAR); 
} 

编辑

除了我固定,这种方法不能与闰年以及工作中的错误。这是一个完整的测试套件。我想你最好用接受的答案。

import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.GregorianCalendar; 

class YearsBetweenDates { 
    public static int getYearsBetweenDates(Date first, Date second) { 
     Calendar firstCal = GregorianCalendar.getInstance(); 
     Calendar secondCal = GregorianCalendar.getInstance(); 

     firstCal.setTime(first); 
     secondCal.setTime(second); 

     secondCal.add(Calendar.DAY_OF_YEAR, 1 - firstCal.get(Calendar.DAY_OF_YEAR)); 

     return secondCal.get(Calendar.YEAR) - firstCal.get(Calendar.YEAR); 
    } 

    private static class TestCase { 
     public Calendar date1; 
     public Calendar date2; 
     public int expectedYearDiff; 
     public String comment; 

     public TestCase(Calendar date1, Calendar date2, int expectedYearDiff, String comment) { 
      this.date1 = date1; 
      this.date2 = date2; 
      this.expectedYearDiff = expectedYearDiff; 
      this.comment = comment; 
     } 
    } 

    private static TestCase[] tests = { 
     new TestCase(
       new GregorianCalendar(2014, Calendar.JULY, 15), 
       new GregorianCalendar(2015, Calendar.JULY, 15), 
       1, 
       "exactly one year"), 
     new TestCase(
       new GregorianCalendar(2014, Calendar.JULY, 15), 
       new GregorianCalendar(2017, Calendar.JULY, 14), 
       2, 
       "one day less than 3 years"), 
     new TestCase(
       new GregorianCalendar(2015, Calendar.NOVEMBER, 3), 
       new GregorianCalendar(2017, Calendar.MAY, 3), 
       1, 
       "a year and a half"), 
     new TestCase(
       new GregorianCalendar(2016, Calendar.JULY, 15), 
       new GregorianCalendar(2017, Calendar.JULY, 15), 
       1, 
       "leap years do not compare correctly"), 
    }; 

    public static void main(String[] args) { 
     SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); 
     for (TestCase t : tests) { 
      int diff = getYearsBetweenDates(t.date1.getTime(), t.date2.getTime()); 
      String result = diff == t.expectedYearDiff ? "PASS" : "FAIL"; 
      System.out.println(t.comment + ": " + 
        df.format(t.date1.getTime()) + " -> " + 
        df.format(t.date2.getTime()) + " = " + 
        diff + ": " + result); 
     } 
    } 
} 
+0

这似乎没有工作 –

+0

有一个与天是基于一个的相关的错误。但是这对于闰年来说也不太合适。请参阅我的编辑。 – SnakE

4

TL;博士

ChronoUnit.YEARS.between(LocalDate.of(2010 , 1 , 1) , LocalDate.now(ZoneId.of("America/Montreal"))) 

java.time

旧日期,时间类真的是坏,坏两个太阳&甲骨文同意java.time排挤他们类。如果您使用日期时间值进行任何重要工作,则为您的项目添加库是值得的。Joda-Time图书馆非常成功,并被推荐,但现在处于维护模式。该团队建议迁移到java.time类。

大部分的java.time功能后移植到Java 6 和ThreeTenABP还适于Android(见How to use…)。

LocalDate start = LocalDate.of(2010 , 1 , 1) ; 
LocalDate stop = LocalDate.now(ZoneId.of("America/Montreal")); 
long years = java.time.temporal.ChronoUnit.YEARS.between(start , stop); 

转储到控制台。

System.out.println("start: " + start + " | stop: " + stop + " | years: " + years) ; 

开始:2010-01-01 |停止:2016-09-06 |年:6

相关问题