我想在Java方法中将一个年龄作为int返回。 我现在有以下内容:getBirthDate()返回Date对象(带有出生日期; - )):
public int getAge() {
long ageInMillis = new Date().getTime() - getBirthDate().getTime();
Date age = new Date(ageInMillis);
return age.getYear();
}
但是因为getYear()被弃用了,我想知道是否有更好的方法来做到这一点?我甚至不确定这是否正常,因为我还没有进行单元测试。
答案 0 :(得分:166)
查看Joda,这简化了日期/时间计算(Joda也是新标准Java日期/时间apis的基础,因此您将学习即将成为标准的API)。
编辑:Java 8有something very similar,值得一试。
e.g。
LocalDate birthdate = new LocalDate (1970, 1, 20);
LocalDate now = new LocalDate();
Years age = Years.yearsBetween(birthdate, now);
这就是你想要的那么简单。 Java 8之前的内容(正如您所确定的那样)有点不直观。
答案 1 :(得分:139)
JDK 8使这简单而优雅:
public class AgeCalculator {
public static int calculateAge(LocalDate birthDate, LocalDate currentDate) {
if ((birthDate != null) && (currentDate != null)) {
return Period.between(birthDate, currentDate).getYears();
} else {
return 0;
}
}
}
用于演示其用途的JUnit测试:
public class AgeCalculatorTest {
@Test
public void testCalculateAge_Success() {
// setup
LocalDate birthDate = LocalDate.of(1961, 5, 17);
// exercise
int actual = AgeCalculator.calculateAge(birthDate, LocalDate.of(2016, 7, 12));
// assert
Assert.assertEquals(55, actual);
}
}
现在每个人都应该使用JDK 8。所有早期版本都已经过了他们的支持生命。
答案 2 :(得分:41)
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(...);
if (dob.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
int age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
age--;
} else if (month1 == month2) {
int day1 = now.get(Calendar.DAY_OF_MONTH);
int day2 = dob.get(Calendar.DAY_OF_MONTH);
if (day2 > day1) {
age--;
}
}
// age is now correct
答案 3 :(得分:36)
a)Java-8(java.time-package)
LocalDate start = LocalDate.of(1996, 2, 29);
LocalDate end = LocalDate.of(2014, 2, 28); // use for age-calculation: LocalDate.now()
long years = ChronoUnit.YEARS.between(start, end);
System.out.println(years); // 17
请注意,表达式LocalDate.now()
与系统时区(用户经常忽略)隐式相关。为清楚起见,通常最好使用指定显式时区的重载方法now(ZoneId.of("Europe/Paris"))
(此处以“Europe / Paris”为例)。如果请求系统时区,那么我个人的偏好是写LocalDate.now(ZoneId.systemDefault())
以使与系统时区的关系更清晰。这是更多的写作努力,但使阅读更容易。
b)Joda-Time
请注意,建议和接受的Joda-Time解决方案会产生上述日期(罕见情况)的不同计算结果,即:
LocalDate birthdate = new LocalDate(1996, 2, 29);
LocalDate now = new LocalDate(2014, 2, 28); // test, in real world without args
Years age = Years.yearsBetween(birthdate, now);
System.out.println(age.getYears()); // 18
我认为这是一个小错误,但Joda团队对这种奇怪的行为有不同的看法并且不想修复它(很奇怪,因为结束日期的日期小于开始日期所以一年应少一个)。另见此结束issue。
c)java.util.Calendar等。
为了比较,请参阅其他各种答案。我不建议使用这些过时的类,因为在一些奇特的情况下,结果代码仍然是错误的和/或考虑到原始问题听起来如此简单的事实而过于复杂。在2015年,我们拥有更好的图书馆。
d)关于Date4J:
建议的解决方案很简单,但在闰年的情况下有时会失败。仅评估一年中的某一天并不可靠。
e)我自己的图书馆Time4J :
这与Java-8解决方案类似。只需将LocalDate
替换为PlainDate
,将ChronoUnit.YEARS
替换为CalendarUnit.YEARS
。但是,获取“今天”需要明确的时区参考。
PlainDate start = PlainDate.of(1996, 2, 29);
PlainDate end = PlainDate.of(2014, 2, 28);
// use for age-calculation (today):
// => end = SystemClock.inZonalView(EUROPE.PARIS).today();
// or in system timezone: end = SystemClock.inLocalView().today();
long years = CalendarUnit.YEARS.between(start, end);
System.out.println(years); // 17
答案 4 :(得分:17)
/**
* This Method is unit tested properly for very different cases ,
* taking care of Leap Year days difference in a year,
* and date cases month and Year boundary cases (12/31/1980, 01/01/1980 etc)
**/
public static int getAge(Date dateOfBirth) {
Calendar today = Calendar.getInstance();
Calendar birthDate = Calendar.getInstance();
int age = 0;
birthDate.setTime(dateOfBirth);
if (birthDate.after(today)) {
throw new IllegalArgumentException("Can't be born in the future");
}
age = today.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);
// If birth date is greater than todays date (after 2 days adjustment of leap year) then decrement age one year
if ( (birthDate.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR) > 3) ||
(birthDate.get(Calendar.MONTH) > today.get(Calendar.MONTH ))){
age--;
// If birth date and todays date are of same month and birth day of month is greater than todays day of month then decrement age
}else if ((birthDate.get(Calendar.MONTH) == today.get(Calendar.MONTH )) &&
(birthDate.get(Calendar.DAY_OF_MONTH) > today.get(Calendar.DAY_OF_MONTH ))){
age--;
}
return age;
}
答案 5 :(得分:11)
我只是使用一年中常量值的毫秒数来实现我的优势:
Date now = new Date();
long timeBetween = now.getTime() - age.getTime();
double yearsBetween = timeBetween / 3.15576e+10;
int age = (int) Math.floor(yearsBetween);
答案 6 :(得分:10)
如果你正在使用GWT,你将被限制使用java.util.Date,这是一个以日期为整数但仍然使用java.util.Date的方法:
public int getAge(int year, int month, int day) {
Date now = new Date();
int nowMonth = now.getMonth()+1;
int nowYear = now.getYear()+1900;
int result = nowYear - year;
if (month > nowMonth) {
result--;
}
else if (month == nowMonth) {
int nowDay = now.getDate();
if (day > nowDay) {
result--;
}
}
return result;
}
答案 7 :(得分:4)
使用JodaTime的正确答案是:
public int getAge() {
Years years = Years.yearsBetween(new LocalDate(getBirthDate()), new LocalDate());
return years.getYears();
}
如果您愿意,甚至可以将其缩短为一行。我从BrianAgnew's answer复制了这个想法,但我相信这更正确,正如你从那里的评论中看到的那样(它完全回答了这个问题)。
答案 8 :(得分:4)
使用date4j库:
int age = today.getYear() - birthdate.getYear();
if(today.getDayOfYear() < birthdate.getDayOfYear()){
age = age - 1;
}
答案 9 :(得分:3)
尝试在代码中复制此内容,然后使用该方法获取年龄。
public static int getAge(Date birthday)
{
GregorianCalendar today = new GregorianCalendar();
GregorianCalendar bday = new GregorianCalendar();
GregorianCalendar bdayThisYear = new GregorianCalendar();
bday.setTime(birthday);
bdayThisYear.setTime(birthday);
bdayThisYear.set(Calendar.YEAR, today.get(Calendar.YEAR));
int age = today.get(Calendar.YEAR) - bday.get(Calendar.YEAR);
if(today.getTimeInMillis() < bdayThisYear.getTimeInMillis())
age--;
return age;
}
答案 10 :(得分:3)
你可能会惊讶地发现,你不需要知道一年中有多少天或几个月或那几个月有多少天,同样地,你不需要知道闰年,闰秒或使用这种简单,100%准确的方法的任何东西:
public static int age(Date birthday, Date date) {
DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
int d1 = Integer.parseInt(formatter.format(birthday));
int d2 = Integer.parseInt(formatter.format(date));
int age = (d2-d1)/10000;
return age;
}
答案 11 :(得分:2)
我使用这段代码进行年龄计算,希望这有助于..没有使用库
private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
public static int calculateAge(String date) {
int age = 0;
try {
Date date1 = dateFormat.parse(date);
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(date1);
if (dob.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
int year1 = now.get(Calendar.YEAR);
int year2 = dob.get(Calendar.YEAR);
age = year1 - year2;
int month1 = now.get(Calendar.MONTH);
int month2 = dob.get(Calendar.MONTH);
if (month2 > month1) {
age--;
} else if (month1 == month2) {
int day1 = now.get(Calendar.DAY_OF_MONTH);
int day2 = dob.get(Calendar.DAY_OF_MONTH);
if (day2 > day1) {
age--;
}
}
} catch (ParseException e) {
e.printStackTrace();
}
return age ;
}
答案 12 :(得分:2)
字段诞生和效果都是日期字段:
Calendar bir = Calendar.getInstance();
bir.setTime(birth);
int birthNm = bir.get(Calendar.DAY_OF_YEAR);
int birthYear = bir.get(Calendar.YEAR);
Calendar eff = Calendar.getInstance();
eff.setTime(effect);
这基本上是对John O解决方案的修改,而不使用折旧方法。我花了相当多的时间试图让他的代码在我的代码中工作。也许这会为其他人节省时间。
答案 13 :(得分:2)
这是上面一个的改进版本...考虑到你希望年龄是'int'。因为有时你不想用一堆库来填充你的程序。
public int getAge(Date dateOfBirth) {
int age = 0;
Calendar born = Calendar.getInstance();
Calendar now = Calendar.getInstance();
if(dateOfBirth!= null) {
now.setTime(new Date());
born.setTime(dateOfBirth);
if(born.after(now)) {
throw new IllegalArgumentException("Can't be born in the future");
}
age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);
if(now.get(Calendar.DAY_OF_YEAR) < born.get(Calendar.DAY_OF_YEAR)) {
age-=1;
}
}
return age;
}
答案 14 :(得分:1)
我感谢所有正确的答案,但这是同一问题的科特林答案
我希望对Kotlin开发人员有所帮助
fun calculateAge(birthDate: Date): Int {
val now = Date()
val timeBetween = now.getTime() - birthDate.getTime();
val yearsBetween = timeBetween / 3.15576e+10;
return Math.floor(yearsBetween).toInt()
}
答案 15 :(得分:1)
public class CalculateAge {
private int age;
private void setAge(int age){
this.age=age;
}
public void calculateAge(Date date){
Calendar calendar=Calendar.getInstance();
Calendar calendarnow=Calendar.getInstance();
calendarnow.getTimeZone();
calendar.setTime(date);
int getmonth= calendar.get(calendar.MONTH);
int getyears= calendar.get(calendar.YEAR);
int currentmonth= calendarnow.get(calendarnow.MONTH);
int currentyear= calendarnow.get(calendarnow.YEAR);
int age = ((currentyear*12+currentmonth)-(getyears*12+getmonth))/12;
setAge(age);
}
public int getAge(){
return this.age;
}
答案 16 :(得分:1)
优雅,看似正确,基于时间戳差异的Yaron Ronen解决方案。
我正在进行单元测试以证明其不正确的时间和原因。由于(可能)在任何时间戳差异中的不同数量的闰天(和秒)是不可能的。这个算法的差异应该是最大+ 1天(和1秒),参见test2(),而基于timeDiff / MILLI_SECONDS_YEAR
的完全恒定假设的Yaron Ronen解决方案对于40岁的人来说可能会有10天不同,不过这个变体也是不正确的。
这很棘手,因为这个使用公式diffAsCalendar.get(Calendar.YEAR) - 1970
的改进变体在大多数情况下会返回正确的结果,因为两个日期之间的平均闰年数相同。
/**
* Compute person's age based on timestamp difference between birth date and given date
* and prove it is INCORRECT approach.
*/
public class AgeUsingTimestamps {
public int getAge(Date today, Date dateOfBirth) {
long diffAsLong = today.getTime() - dateOfBirth.getTime();
Calendar diffAsCalendar = Calendar.getInstance();
diffAsCalendar.setTimeInMillis(diffAsLong);
return diffAsCalendar.get(Calendar.YEAR) - 1970; // base time where timestamp=0, precisely 1/1/1970 00:00:00
}
final static DateFormat df = new SimpleDateFormat("dd.MM.yyy HH:mm:ss");
@Test
public void test1() throws Exception {
Date dateOfBirth = df.parse("10.1.2000 00:00:00");
assertEquals(87, getAge(df.parse("08.1.2088 23:59:59"), dateOfBirth));
assertEquals(87, getAge(df.parse("09.1.2088 23:59:59"), dateOfBirth));
assertEquals(88, getAge(df.parse("10.1.2088 00:00:01"), dateOfBirth));
}
@Test
public void test2() throws Exception {
// between 2000 and 2021 was 6 leap days
// but between 1970 (base time) and 1991 there was only 5 leap days
// therefore age is switched one day earlier
// See http://www.onlineconversion.com/leapyear.htm
Date dateOfBirth = df.parse("10.1.2000 00:00:00");
assertEquals(20, getAge(df.parse("08.1.2021 23:59:59"), dateOfBirth));
assertEquals(20, getAge(df.parse("09.1.2021 23:59:59"), dateOfBirth)); // ERROR! returns incorrect age=21 here
assertEquals(21, getAge(df.parse("10.1.2021 00:00:01"), dateOfBirth));
}
}
答案 17 :(得分:1)
String
dateofbirth
有出生日期。和格式是什么(在以下行中定义):
org.joda.time.format.DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern("mm/dd/yyyy");
以下是格式化方法:
org.joda.time.DateTime birthdateDate = formatter.parseDateTime(dateofbirth );
org.joda.time.DateMidnight birthdate = new org.joda.time.DateMidnight(birthdateDate.getYear(), birthdateDate.getMonthOfYear(), birthdateDate.getDayOfMonth() );
org.joda.time.DateTime now = new org.joda.time.DateTime();
org.joda.time.Years age = org.joda.time.Years.yearsBetween(birthdate, now);
java.lang.String ageStr = java.lang.String.valueOf (age.getYears());
变量ageStr
将有多年。
答案 18 :(得分:1)
这个怎么样?
public Integer calculateAge(Date date) {
if (date == null) {
return null;
}
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date);
Calendar cal2 = Calendar.getInstance();
int i = 0;
while (cal1.before(cal2)) {
cal1.add(Calendar.YEAR, 1);
i += 1;
}
return i;
}
答案 19 :(得分:0)
/**
* Compute from string date in the format of yyyy-MM-dd HH:mm:ss the age of a person.
* @author Yaron Ronen
* @date 04/06/2012
*/
private int computeAge(String sDate)
{
// Initial variables.
Date dbDate = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Parse sDate.
try
{
dbDate = (Date)dateFormat.parse(sDate);
}
catch(ParseException e)
{
Log.e("MyApplication","Can not compute age from date:"+sDate,e);
return ILLEGAL_DATE; // Const = -2
}
// Compute age.
long timeDiff = System.currentTimeMillis() - dbDate.getTime();
int age = (int)(timeDiff / MILLI_SECONDS_YEAR); // MILLI_SECONDS_YEAR = 31558464000L;
return age;
}
答案 20 :(得分:0)
以下是用于计算年,月和日的年龄的java代码。
public static AgeModel calculateAge(long birthDate) {
int years = 0;
int months = 0;
int days = 0;
if (birthDate != 0) {
//create calendar object for birth day
Calendar birthDay = Calendar.getInstance();
birthDay.setTimeInMillis(birthDate);
//create calendar object for current day
Calendar now = Calendar.getInstance();
Calendar current = Calendar.getInstance();
//Get difference between years
years = now.get(Calendar.YEAR) - birthDay.get(Calendar.YEAR);
//get months
int currMonth = now.get(Calendar.MONTH) + 1;
int birthMonth = birthDay.get(Calendar.MONTH) + 1;
//Get difference between months
months = currMonth - birthMonth;
//if month difference is in negative then reduce years by one and calculate the number of months.
if (months < 0) {
years--;
months = 12 - birthMonth + currMonth;
} else if (months == 0 && now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
years--;
months = 11;
}
//Calculate the days
if (now.get(Calendar.DATE) > birthDay.get(Calendar.DATE))
days = now.get(Calendar.DATE) - birthDay.get(Calendar.DATE);
else if (now.get(Calendar.DATE) < birthDay.get(Calendar.DATE)) {
int today = now.get(Calendar.DAY_OF_MONTH);
now.add(Calendar.MONTH, -1);
days = now.getActualMaximum(Calendar.DAY_OF_MONTH) - birthDay.get(Calendar.DAY_OF_MONTH) + today;
} else {
days = 0;
if (months == 12) {
years++;
months = 0;
}
}
}
//Create new Age object
return new AgeModel(days, months, years);
}
答案 21 :(得分:0)
没有任何库的最简单方法:
long today = new Date().getTime();
long diff = today - birth;
long age = diff / DateUtils.YEAR_IN_MILLIS;
答案 22 :(得分:0)
使用Java 8,我们可以用一行代码计算一个人的年龄:
public int calCAge(int year, int month,int days){
return LocalDate.now().minus(Period.of(year, month, days)).getYear();
}
答案 23 :(得分:-1)
public int getAge(String birthdate, String today){
// birthdate = "1986-02-22"
// today = "2014-09-16"
// String class has a split method for splitting a string
// split(<delimiter>)
// birth[0] = 1986 as string
// birth[1] = 02 as string
// birth[2] = 22 as string
// now[0] = 2014 as string
// now[1] = 09 as string
// now[2] = 16 as string
// **birth** and **now** arrays are automatically contains 3 elements
// split method here returns 3 elements because of yyyy-MM-dd value
String birth[] = birthdate.split("-");
String now[] = today.split("-");
int age = 0;
// let us convert string values into integer values
// with the use of Integer.parseInt(<string>)
int ybirth = Integer.parseInt(birth[0]);
int mbirth = Integer.parseInt(birth[1]);
int dbirth = Integer.parseInt(birth[2]);
int ynow = Integer.parseInt(now[0]);
int mnow = Integer.parseInt(now[1]);
int dnow = Integer.parseInt(now[2]);
if(ybirth < ynow){ // has age if birth year is lesser than current year
age = ynow - ybirth; // let us get the interval of birth year and current year
if(mbirth == mnow){ // when birth month comes, it's ok to have age = ynow - ybirth if
if(dbirth > dnow) // birth day is coming. need to subtract 1 from age. not yet a bday
age--;
}else if(mbirth > mnow){ age--; } // birth month is comming. need to subtract 1 from age
}
return age;
}
答案 24 :(得分:-1)
import java.io.*;
class AgeCalculator
{
public static void main(String args[])
{
InputStreamReader ins=new InputStreamReader(System.in);
BufferedReader hey=new BufferedReader(ins);
try
{
System.out.println("Please enter your name: ");
String name=hey.readLine();
System.out.println("Please enter your birth date: ");
String date=hey.readLine();
System.out.println("please enter your birth month:");
String month=hey.readLine();
System.out.println("please enter your birth year:");
String year=hey.readLine();
System.out.println("please enter current year:");
String cYear=hey.readLine();
int bDate = Integer.parseInt(date);
int bMonth = Integer.parseInt(month);
int bYear = Integer.parseInt(year);
int ccYear=Integer.parseInt(cYear);
int age;
age = ccYear-bYear;
int totalMonth=12;
int yourMonth=totalMonth-bMonth;
System.out.println(" Hi " + name + " your are " + age + " years " + yourMonth + " months old ");
}
catch(IOException err)
{
System.out.println("");
}
}
}
答案 25 :(得分:-1)
<form name="questionForm" ng-submit="ok()">
<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>
// the rest of the code here
</form>
答案 26 :(得分:-1)
public int getAge(Date birthDate) {
Calendar a = Calendar.getInstance(Locale.US);
a.setTime(date);
Calendar b = Calendar.getInstance(Locale.US);
int age = 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))) {
age--;
}
return age;
}
答案 27 :(得分:-1)
public int getAge(Date dateOfBirth)
{
Calendar now = Calendar.getInstance();
Calendar dob = Calendar.getInstance();
dob.setTime(dateOfBirth);
if (dob.after(now))
{
throw new IllegalArgumentException("Can't be born in the future");
}
int age = now.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
if (now.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR))
{
age--;
}
return age;
}