问题
I have a JDateChooser in my program. Whenever the selects his date of birth from JDateChooser , I want his age to be displayed in a JTextField.
Initially, I tried to make it work with the MouseListener as :
private void jDateChooser1MouseExited(java.awt.event.MouseEvent evt)
{
Calendar dob = Calendar.getInstance();
//utilDob is a java.util.Date variable which stores date selected by user
dob.setTime(utilDob);
Calendar today = Calendar.getInstance();
int age = today.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
if (today.get(Calendar.MONTH) < dob.get(Calendar.MONTH))
age--;
else if (today.get(Calendar.MONTH) == dob.get(Calendar.MONTH)
&& today.get(Calendar.DAY_OF_MONTH) < dob.get(Calendar.DAY_OF_MONTH))
age--;
jTextField11.setText(Integer.toString(age));
displayAge=Integer.parseInt(jTextField11.getText());
}
But, the above mentioned function didn't help me. Is there any other event/action listener I can use?
回答1:
You are using outmoded classes.
java.time
Java 8 and later comes with the java.time framework built-in.
LocalDate
The LocalDate class represents a date-only value, without time-of-day and without time zone. But time zone is critical it determining "today". For any given moment the date may vary around the world by time zone. A few moments after midnight in Paris is still “yesterday” in Montréal.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
Build a date-of-birth from your user input.
LocalDate dob = LocalDate.of ( 1955 , 1 , 2 );
Or parse a string compliant with the ISO 8601 standard.
LocalDate dob = LocalDate.parse( "1955-01-02" );
Or use a DateTimeFormatter
to help parse a different string.
If you have a java.util.Date
object on hand use a new method added to that old class for conversion to java.time: java.util.Date::toInstant
. An Instant
is a moment on the timeline in UTC.
Instant instant = myJavaUtilDate.toInstant();
Apple a time zone.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Extract a LocalDate
.
LocalDate localDate = zdt.toLocalDate();
Period
Age is just one kind of elapsed time, a span of time. In java.time, the Period
class represents a span of time tracked in terms of years, months, and days.
Period age = Period.between ( dob , today );
Get years from Period
Ask for the years if that is all you want.
int years = age.getYears ();
Beware that getYears
is not normalized to the full number of years as you may intuit. Depending on how a Period
is constructed, you may get an unexpected result. Another approach is to call toTotalMonths()
and divide by 12 (twelve months to a year). See both approaches in this quick example; compare y
and y2
.
Period p = Period.ofMonths ( 25 );
int y = p.getYears ();
long y2 = ( ( p.toTotalMonths () ) / 12 );
System.out.println ( "p: " + p + " | y: " + y + " | y2: " + y2 );
p: P25M | y: 0 | y2: 2
Even better, force the Period
object to be normalized to a full count of years then months then days. Well, not exactly force the object: Because of immutable objects, you are actually instantiating a new object based on the original object’s values.
So while our age
object happens to already be normalized because of its particular construction, it might be a good habit to always call normalized
.
Period age = Period.between ( dob , today ).normalized();
Dump to console. By default, the Period::toString
method generates a string according to the ISO 8601 standard for Durations such as P61Y2M27D
seen here.
System.out.println ( "zoneid: " + zoneId + " | today: " + today + " | dob: " + dob + " | age: " + age + " | years: " + years );
zoneid: America/Montreal | today: 2016-03-29 | dob: 1955-01-02 | age: P61Y2M27D | years: 61
Convert int
to Integer
Lastly, if you need an object rather than a primitive, convert int
to Integer
.
Integer yearsObj = Integer.valueOf ( years );
来源:https://stackoverflow.com/questions/35898480/to-display-age-in-textfield-after-user-has-selected-date-of-birth-in-jdatechoose