يوضح هذا الدرس كيفية إنشاء برنامج Java لحساب العمر من تاريخ الميلاد، مع واجهة بسيطة باستخدام Swing. يدخل المستخدم يوم وشهر وسنة الميلاد، ثم يحسب البرنامج العمر بالسنوات والأشهر والأيام اعتمادًا على LocalDate وPeriod. هذا أدق وأسهل صيانة من طرح أرقام السنوات يدويًا، لأن مكتبة الوقت تتعامل مع اختلاف أطوال الشهور والسنوات الكبيسة.
فكرة حساب العمر من تاريخ الميلاد
العمر هو الفرق بين تاريخ الميلاد وتاريخ اليوم. لا يكفي طرح سنة الميلاد من السنة الحالية، لأن النتيجة قد تزيد سنة كاملة قبل حلول عيد الميلاد في السنة الحالية. كما أن حساب الأشهر والأيام يدويًا يسبب أخطاء عند نهاية الشهر أو الانتقال من يناير إلى فبراير. توفر Java الحديثة واجهة java.time لهذه الحسابات.
كود واجهة Swing لحساب العمر
احفظ الملف باسم AgeCalculator.java. المثال التالي يقبل التاريخ بصيغة السنة-الشهر-اليوم، مثل 2000-05-14:
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeParseException;
import javax.swing.*;
import java.awt.*;
public class AgeCalculator extends JFrame {
private final JTextField birthField = new JTextField(12);
private final JLabel result = new JLabel("أدخل تاريخ الميلاد ثم اضغط احسب");
public AgeCalculator() {
super("حساب العمر");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.RIGHT));
add(new JLabel("تاريخ الميلاد (yyyy-MM-dd):"));
add(birthField);
JButton calculate = new JButton("احسب العمر");
add(calculate);
add(result);
calculate.addActionListener(event -> calculateAge());
pack();
setLocationRelativeTo(null);
}
private void calculateAge() {
try {
LocalDate birthDate = LocalDate.parse(birthField.getText().trim());
LocalDate today = LocalDate.now();
if (birthDate.isAfter(today)) {
throw new IllegalArgumentException("تاريخ الميلاد لا يمكن أن يكون في المستقبل.");
}
Period age = Period.between(birthDate, today);
result.setText("العمر: " + age.getYears() + " سنة، "
+ age.getMonths() + " شهر، " + age.getDays() + " يوم");
} catch (DateTimeParseException ex) {
JOptionPane.showMessageDialog(this,
"اكتب التاريخ بصيغة yyyy-MM-dd مثل 2000-05-14",
"صيغة غير صحيحة", JOptionPane.WARNING_MESSAGE);
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(this, ex.getMessage(),
"تاريخ غير صالح", JOptionPane.WARNING_MESSAGE);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new AgeCalculator().setVisible(true));
}
}شرح أجزاء البرنامج
يرث الكلاس AgeCalculator من JFrame ليكون نافذة. يحتوي JTextField على التاريخ، ويعرض JLabel النتيجة. عند الضغط على الزر ينفذ مستمع الحدث الدالة calculateAge. استخدمنا SwingUtilities.invokeLater لتشغيل إنشاء الواجهة على مسار أحداث Swing، وهو النمط المعتاد لتحديث مكونات الواجهة بأمان.
تحول LocalDate.parse النص إلى تاريخ. يجب أن يكون التاريخ مكتوبًا بصيغة ISO الافتراضية yyyy-MM-dd. بعد التحقق من أن تاريخ الميلاد ليس في المستقبل، تحسب Period.between الفارق الكامل. تعرض الدوال getYears وgetMonths وgetDays أجزاء الفترة كلًا على حدة.
التحقق من التاريخ والتعامل مع الأخطاء
إذا كتب المستخدم تاريخًا مثل 2000-15-40 أو ترك الحقل فارغًا، فلن يقبل LocalDate.parse القيمة، لذلك نعالج DateTimeParseException ونشرح الصيغة المطلوبة. أما التاريخ الصحيح الذي يقع بعد اليوم فيتم رفضه برسالة منفصلة. فصل نوعي الخطأ يجعل الواجهة أوضح من إظهار رسالة عامة لا تساعد المستخدم.
تشغيل البرنامج وتخصيصه
من الطرفية، نفذ javac AgeCalculator.java ثم java AgeCalculator. لا يحتاج هذا المثال إلى مكتبة خارجية، لكنه يتطلب Java 8 أو أحدث بسبب java.time. يمكن تطوير النموذج بإضافة قوائم منسدلة لليوم والشهر والسنة، أو بمكون اختيار تاريخ. إذا استخدمت قوائم منفصلة، أنشئ LocalDate داخل try/catch حتى تظهر رسالة عند تاريخ غير ممكن، مثل 31 فبراير.
هل يحسب العمر بدقة قانونية؟
البرنامج يعرض فرق التقويم بين التاريخين، وهو مناسب للتعلم والاستخدام العام. قواعد احتساب العمر القانوني قد تختلف بحسب البلد، خصوصًا في يوم الميلاد أو التقويم المستخدم؛ لذلك لا تعتمد على هذا المثال وحده لاتخاذ قرار قانوني أو إداري. كذلك تستخدم LocalDate.now() تاريخ الجهاز المحلي. في تطبيق موزع، حدد المنطقة الزمنية بوضوح واحصل على تاريخ اليوم من مصدر موثوق.
أفكار للتوسع وروابط داخلية
يمكنك إضافة خيار لحساب المدة حتى تاريخ يختاره المستخدم، أو عرض عدد الأيام الكلي بين التاريخين باستخدام ChronoUnit.DAYS. ويمكن فصل منطق الحساب عن الواجهة في دالة مستقلة لتسهيل إعادة استخدامه. تابع دروس Java، وتعلم قراءة القيم من المستخدم في مثال Scanner للاسم والعمر والدخل، ثم راجع مقارنة الأعداد في Java.





