我怎样才能找到两次约会之间的年数?

我试图从某个特定的日期确定年龄。有没有人知道一个干净的方法在安卓系统中做到这一点?我当然有 Javaapi 可用,但是直接的 Javaapi 非常弱,我希望 Android 能够帮助我解决这个问题。

编辑: 在 Android 中使用 Joda 时间的多个建议让我有点担心,因为 Android Java-Joda Date 很慢和相关的问题。而且,为了这么大的东西而使用一个没有随平台一起提供的库可能有些过头了。

123055 次浏览

我建议对 Java 中与日期相关的所有内容都使用优秀的 Joda 时间库。

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

如果你不想计算它使用 Java 的日历,你可以使用 机器人时间类它应该是更快,但我没有注意到很大的差异时,我切换。

在 Android 中,我找不到任何预定义的函数来确定一个年龄段的两次约会之间的时间。在 日期工具中有一些很好的辅助函数来获取日期之间的格式化时间,但这可能不是您想要的。

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

        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);
}

试试这个:

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));


}
import java.util.Calendar;
import java.util.Locale;
import static java.util.Calendar.*;
import java.util.Date;


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;
}

注意 : 正如 Ole V.V.所注意到的,由于日历的工作原理,这不适用于基督之前的日期。

我显然还不能发表评论,但是我认为你可以使用 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 的数量。只要把所有的东西都保持在一个较长的时间里,那么大多数时候就足够好了(闰年,哎哟) ,但是这取决于你的应用程序运行了多少年,以及这个功能的性能如何,它是否值得这样的黑客攻击。

// 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;

下面是我认为更好的方法:

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);
}
}
}

博士

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

零年过去了,一年过去了。

ChronoUnit.YEARS.between(
LocalDate.of( 2010 , 1 , 1 )  ,
LocalDate.of( 2010 , 6 , 1 )
)

0

ChronoUnit.YEARS.between(
LocalDate.of( 2010 , 1 , 1 )  ,
LocalDate.of( 2011 , 1 , 1 )
)

1

看这个 在 Ideone.com 上运行代码

爪哇时间

旧的 date-time 类真的很糟糕,糟糕到 Sun 和 Oracle 都同意用 java.time 类取代它们。如果使用日期时间值执行任何重要工作,则向项目中添加库是值得的。Joda-Time 库非常成功并受到推荐,但是现在处于维护模式。团队建议迁移到 java.time 类。

Time 的大部分功能在 310-后端口中返回移植到 Java 6和7,并在 三个十分中进一步适应 仿生人(参见 如何使用..)。

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 ) ;

Start: 2010-01-01 | stop: 2016-09-06 | years: 6开始: 2010-01-01 | 停止: 2016-09-06 | 年份: 6


Table of all date-time types in Java, both modern and legacy


关于 爪哇时间

< em > java.time 框架内置于 Java8及更高版本中。这些类取代了令人讨厌的旧的 遗产日期时间类,如 java.util.DateCalendarSimpleDateFormat

现在在 维修模式中的 尤达时间项目建议迁移到 爪哇时间类。

要了解更多,请参阅 < em > Oracle 教程 。并搜索堆栈溢出许多例子和解释。规范是 JSR 310

您可以直接与数据库交换 爪哇时间对象。使用与 JDBC 4.2或更高版本兼容的 JDBC 驱动程序。不需要字符串,不需要 java.sql.*类。

从哪里获得 java.time 类?

Table of which java.time library to use with which version of Java or Android

这将工作,如果你想要的年数替换12到1

    String date1 = "07-01-2015";
String date2 = "07-11-2015";
int i = Integer.parseInt(date1.substring(6));
int j = Integer.parseInt(date2.substring(6));
int p = Integer.parseInt(date1.substring(3,5));
int q = Integer.parseInt(date2.substring(3,5));




int z;
if(q>=p){
z=q-p + (j-i)*12;
}else{
z=p-q + (j-i)*12;
}
System.out.println("The Total Months difference between two dates is --> "+z+" Months");

感谢@Ole V.v 审查它: 我已经找到了一些内置的库类,它们也可以做同样的事情

    int noOfMonths = 0;
org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat
.forPattern("yyyy-MM-dd");
DateTime dt = formatter.parseDateTime(startDate);


DateTime endDate11 = new DateTime();
Months m = Months.monthsBetween(dt, endDate11);
noOfMonths = m.getMonths();
System.out.println(noOfMonths);

如果你不想使用日历、语言环境或者外部库的边框,这是一个很方便的方法:

private static SimpleDateFormat YYYYMMDD = new SimpleDateFormat("yyyyMMdd");
public static Integer toDate8d(Date date) {
String s;
synchronized (YYYYMMDD) { s = YYYYMMDD.format(date); }  // SimpleDateFormat thread safety
return Integer.valueOf(s);
}
public static Integer yearDiff(Date pEarlier, Date pLater) {
return (toDate8d(pLater) - toDate8d(pEarlier)) / 10000;
}