1

I am new in java programming and i am working for android apps development. I know the basics of java and i can understand the code. I need to know how can I calculate the upcoming birthday total days from my current date.

` btCalculate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            String sDate = btBirth.getText().toString();
            String eDate = btToday.getText().toString();

            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
            try {
                Date date1 = simpleDateFormat1.parse(sDate);
                Date date2 = simpleDateFormat1.parse(eDate);

                long startDate = date1.getTime();
                long endDate = date2.getTime();

                if (startDate <= endDate) {

                    Period period = new Period(startDate, endDate, PeriodType.yearMonthDay());
                    int years = period.getYears();
                    int months = period.getMonths();
                    int days = period.getDays();


                   textView2.setText("আপনার বয়স হচ্ছে : ");

                    textViewResult.setText(years + " বছর " + months + " মাস " + days + " দিন।");

                }


                else {

                    Toast.makeText(getApplicationContext(), "জন্মতারিখ আজকের তারিখের চেয়ে বড় হবে না। ", Toast.LENGTH_SHORT).show();
                }

            } catch (ParseException e) {
                e.printStackTrace();
            }


        }
    });`

i make this and this can calculate total age. I need help to calculate upcoming birthdays. hope you guys help me . thanks

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 1
    As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use `java.time`, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Dec 02 '19 at 17:10

3 Answers3

2

tl;dr

Determine a birthday anniversary by parsing a string of the birthdate, extract the month-day, and apply desired year, resulting in a date as a LocalDate object.

MonthDay
.from(
    LocalDate
    .parse(
        "23/02/1969" , 
        DateTimeFormatter.ofPattern( "did/MM/uuuu" )
    )
)
.atYear(
    2040
)
.toString()

2040-02-23

Determine age by passing two LocalDate objects to Period.between: the date of birth, and birthday anniversary.

Avoid legacy date-time classes

Do not mix the terrible legacy date-time classes with their replacements. Use only the classes from the java.time package. Never use Date nor SimpleDateFormat.

LocalDate

For a date-only value, without time-of-day and without time zone, use LocalDate.

Parse incoming string.

String input = "23/01/1971" ; 
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ; 
LocalDate birthDate = LocalDate.parse( input , f ) ;

Get today’s date. That requires a time zone. For any given moment, the date varies around the globe by time zone.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;

Verify input. That date should be before today.

if( birthDate.isBefore( today ) ) { … } else { … handle error }

Period

Determine age. The Period class represents a span-of-time not attached to the timeline.

Period age = Period.between( birthDate , today ) ;

MonthDay

But some parts of your Question seem to determine future dates for birthday celebration. For that you need MonthDay class. This class represents the month and day parts of a date, but without the context of a year.

MonthDay birthMonthDay = MonthDay.from( birthDate ) ;

Determine the birthday anniversary this year.

LocalDate birthdayAnniversaryThisYear = birthMonthDay.atYear( today.getYear() ) ; 

Some other year.

LocalDate birthdayAnniversary = birthMonthDay.atYear( 2035 ) ; 

For a month-day of February 29, three out of four years the anniversary date will be invalid. So java.time adjusts the result to February 28.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

java.time and ThreeTenABP

Sort your dates in a way that ignores the birth year and sorts dates that fall in the remainder of the year before those that have already been passed this year.

For a brief demonstration:

import java.util.Arrays;
import java.util.Comparator;

import org.threeten.bp.LocalDate;
import org.threeten.bp.Month;
import org.threeten.bp.MonthDay;
import org.threeten.bp.ZoneId;

public class GetUpcomingBirthdays {

    public static void main(String[] args) {
        LocalDate[] birthdays = {
                LocalDate.of(2016, Month.JANUARY, 29),
                LocalDate.of(1987, Month.MARCH, 5),
                LocalDate.of(1996, Month.JANUARY, 16),
                LocalDate.of(1922, Month.DECEMBER, 8),
                LocalDate.of(2018, Month.OCTOBER, 21),
                LocalDate.of(1977, Month.JULY, 9),
                LocalDate.of(1967, Month.NOVEMBER, 21),
        };

        LocalDate today = LocalDate.now(ZoneId.systemDefault());
        Arrays.sort(birthdays, getBirthdayComparator(today));

        System.out.println("Upcoming birthdays:");
        for (int i = 0; i < 3; i++) {
            System.out.println(birthdays[i]);
        }
    }

    private static Comparator<LocalDate> getBirthdayComparator(LocalDate today) {
        final MonthDay mdToday = MonthDay.from(today);
        return new Comparator<LocalDate>() {

            @Override
            public int compare(LocalDate ld1, LocalDate ld2) {
                MonthDay md1 = MonthDay.from(ld1);
                MonthDay md2 = MonthDay.from(ld2);
                if (md1.isBefore(mdToday)) {
                    if (md2.isBefore(mdToday)) {
                        return md1.compareTo(md2);
                    } else {
                        return 1;
                    }
                } else {
                    if (md2.isBefore(mdToday)) {
                        return -1;
                    } else {
                        return md1.compareTo(md2);
                    }
                }
            }
        };
    } 

}

When running this program today (December 2), the output was:

Upcoming birthdays
1922-12-08
1996-01-16
2016-01-29

The trick is the Comparator, of course. By converting each date to MonthDay I am getting rid of the birth year. Next I need to compare to today’s date (also as MonthDay) to separate those in the remainder of this year from those that have been passed this year and won’t be met again until next year.

For most purposes you would probably rather sort the persons having the birthdays rather than only the dates. I believe that you should be able to modify the code to do that.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Simply call getUpcomingDateList method to get the dates sorted as per your requirement

private ArrayList<Date> getUpcomingDateList(ArrayList<Date> dateList) {
        //Replace year with current year to sort in jan to dec order
        for(int i = 0; i < dateList.size(); i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateList.get(i));
            calendar.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
            dateList.set(i, calendar.getTime());
        }
        //Sort all dates in ascending order
        Collections.sort(dateList);
        //Get final index of past dates
        int index = 0;
        for (int i = 0; i < dateList.size(); i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateList.get(i));
            calendar.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
            Calendar today = Calendar.getInstance();
            today.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE) - 1);
            if (calendar.getTime().after(today.getTime())) {
                index = i;
                break;
            }
        }
        //New list for storing upcoming dates
        ArrayList<Date> newList = new ArrayList<>();
        
        //Store upcoming dates in new list
        for (int i = index; i < dateList.size(); i++) {
            newList.add(dateList.get(i));
        }
        //Store past dates in new list
        for (int i = 0; i < index; i++) {
            newList.add(dateList.get(i));
        }
        Collections.copy(dateList, newList);
        return dateList;
    }

For example, store some sample dates to array list and call getUpcomingDateList method

SimpleDateFormat formatter = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy"); // Your date format
        
ArrayList<Date> dateList = new ArrayList<>();
dateList.add(formatter.parse("Thu May 25 00:00:00 GMT+05:30 2000"));
dateList.add(formatter.parse("Tue Apr 18 00:00:00 GMT+05:30 2021"));
dateList.add(formatter.parse("Wed Jan 27 00:00:00 GMT+05:30 1997"));
dateList.add(formatter.parse("Sat Feb 22 00:00:00 GMT+05:30 2020"));
dateList.add(formatter.parse("Mon Dec 20 00:00:00 GMT+05:30 2001"));
dateList.add(formatter.parse("Thu Jun 14 00:00:00 GMT+05:30 2009"));
dateList.add(formatter.parse("Sat Mar 01 00:00:00 GMT+05:30 1999"));
dateList.add(formatter.parse("Sat Nov 07 00:00:00 GMT+05:30 2005"));
        
dateList = getUpcomingDateList(dateList);
        
for(Date date: dateList) {
    System.out.println(date.toString());
}

If current date is Feb 01 2021, then the final output will be as shown below

Mon Feb 22 00:00:00 IST 2021
Mon Mar 01 00:00:00 IST 2021
Sun Apr 18 00:00:00 IST 2021
Tue May 25 00:00:00 IST 2021
Mon Jun 14 00:00:00 IST 2021
Sun Nov 07 00:00:00 IST 2021
Mon Dec 20 00:00:00 IST 2021
Wed Jan 27 00:00:00 IST 2021
niranj1997
  • 719
  • 8
  • 16