1

I'm trying to calculate the remaining days to next birthday and setting an alarm to trigger 5 days before.
This is working fine, but it is not accurate.
For example, if I put 23. November 2013 I'm getting 366 days left and if I set some different month from current, I'm getting the right calculation, but not precisely.

For example, if I put 1. December 2013, I'm getting 8 days left and that is 30.
November 2015, not 1. December.

This is what i have done so far:

// Storing selected date
                Date dt = null;
                try { dt = dateFormatter.parse(dateSelected); } // dateSelected - Variable type String for storing the date user chose
                catch (final java.text.ParseException e) { e.printStackTrace(); }

                final Calendar BDay = Calendar.getInstance(); // Setting calendar for the next birthday
                BDay.setTime(dt); // get selected date of birthday
                final Calendar today = Calendar.getInstance(); // Setting calendar for the current date

                // Take your DOB Month and compare it to current month
                final int BMonth = BDay.get(Calendar.MONTH);
                final int CMonth = today.get(Calendar.MONTH);
                BDay.set(Calendar.YEAR, today.get(Calendar.YEAR));
                // Result of next birthday
                if(BMonth <= CMonth)
                {
                    BDay.set(Calendar.YEAR, today.get(Calendar.YEAR) + 1);
                }
                // Result in millis
                final long millis = BDay.getTimeInMillis() - today.getTimeInMillis();
                // Convert to days
                final long days = millis / 86400000; // Precalculated (24 * 60 * 60 * 1000)
                // Test
                final long test = today.getTimeInMillis() + 30*1000;

                SimpleDateFormat dayFormatter = new SimpleDateFormat("EEEE");
                //final String dayOfTheWeek = sdf.format(BDay.getTime());
                final String dayOfTheWeek = dayFormatter.format(dt);
                if (dateSelected != null) {
                    Intent intent = new Intent(AddBirthday.this, AlarmReceiver.class);
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(AddBirthday.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                    // Set the alarm for a particular time.
                    //                alarmManager.set(AlarmManager.RTC_WAKEUP, test, PendingIntent.getBroadcast(AddBirthday.this, 1 , intent, PendingIntent.FLAG_UPDATE_CURRENT));
                    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, test, AlarmManager.INTERVAL_DAY, pendingIntent);
                }
                SuperActivityToast.create(AddBirthday.this, "Days left for birthday: " + days + "\n" + "It will be: " + dayOfTheWeek,
                        SuperToast.Duration.LONG, Style.getStyle(Style.RED, SuperToast.Animations.FLYIN)).show();
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Dusan Dimitrijevic
  • 3,169
  • 6
  • 22
  • 46
  • 1
    What about http://stackoverflow.com/a/31800947/1051804 – michal.luszczuk Nov 22 '15 at 13:18
  • Or using JodaTime http://stackoverflow.com/questions/7103064/java-calculate-the-number-of-days-between-two-dates – Fundhor Nov 22 '15 at 13:22
  • Just at first glance, this looks highly suspect: final long days = millis / 86400000; There's gonna be rounding there... Basically, I'd use a decent time API, which will avoid this kind of possible error. ThreeTen or ThreeTenABP if on Android. JodaTime is a little old now. – themightyjon Nov 22 '15 at 13:25
  • Any suggestion on modifying my code, because i wouldn't want to use something else. – Dusan Dimitrijevic Nov 22 '15 at 13:46
  • I'd really strongly suggest you do - dates are fiddly things, and mistakes almost inevitable - but otherwise you need to be careful to check the remainder of that division at least. You'd also want to break this huge thing up a bit and write tests for each part to verify correctness. – themightyjon Nov 22 '15 at 14:11

1 Answers1

0

you need to clear Hour, Minute and second in today variable

example:

if today is 23 Nov 2015 01:00:00 and BDay is 24 Nov 2015 00:00:00

millis = xxxx (23 hours)

then

days = millis / 86400000 // Precalculated (24 * 60 * 60 * 1000)

and the days will be 0

aiwiguna
  • 2,852
  • 2
  • 15
  • 26
  • Okay, i will try to do that. But it happens if i set BDay for every day in current month. – Dusan Dimitrijevic Nov 22 '15 at 19:22
  • it the same, you need to clear all units below the Day, 30 Nov 2015 10:00:00 and BDay is 1 Dec 2015 00:00:00, millis = xxxx (14 hours) , then days = millis / 86400000 // Precalculated (24 * 60 * 60 * 1000) and the days will be 0 – aiwiguna Nov 23 '15 at 02:58
  • I have tried your suggestion using method clear(), but it didn't worked. – Dusan Dimitrijevic Dec 02 '15 at 20:49