M
M
Martivic2014-07-26 04:21:04
Java
Martivic, 2014-07-26 04:21:04

How to implement an algorithm for calculating the date, with a given cyclicity?

Hello!
In the android application, it is necessary to implement the functionality of the diary: a reminder of an event every K days.
There is an initial date from which the event starts, let's say, 1.1.2014, the current date of the phone is 26.07.2014, and the cycle is K - days [1- ... ] after which the event repeats.
Based on these data, it is necessary to calculate the date of the next repetition of the event.
Tried using class: android.text.format.Time
month = [0, 11]
yearDay = [0, 364]

int rv = 7;		
Time t1 = new Time();
Time t2 = new Time();

// 1 января 2014, среда
t1.year = 2014;
t1.month = 0;
t1.monthDay = 1;		
t1.set(t1.toMillis(true));

// 26 июля 2014, суббота
t2.year = 2014;
t2.month = 6;
t2.monthDay = 26;		
t2.set(t2.toMillis(true));

Time t3 = new Time();			
t3.set(t2.toMillis(true));

t3.monthDay += rv - (t2.yearDay - t1.yearDay) % rv;
t3.set(t3.toMillis(true));	

Log.d(tag, "t3.year = " + t3.year
    + " t3.month = " + t3.month
    + " t3.monthDay = " + t3.monthDay
    + " t3.yearDay = " + t3.yearDay
    + " t3.weekDay = " + t3.weekDay);

The result is what you want:

t3.year = 2014 t3.month = 6 t3.monthDay = 30 t3.yearDay = 210 t3.weekDay = 3
Wednesday, July 30, 2014

But the problems start when the date has an initial year less than the current
UPD: Solution
1. Convert the day from which you want to calculate subsequent events to milliseconds and write it to ft. In my example (1.1.2014)
2. Convert the day on which you want to check the event to milliseconds and write nt. In my example (07/26/2014)
3. We form a while do loop with the condition ( ft <= nt ), equality, because the event can occur on the day being checked. The body of the loop will increase ft by the event repetition value K in milliseconds: ft += 24 * 3600 * 1000 * K
4. The result of the loop will be the nearest date in ms on which the event is repeated.
int K = 7;
    
Time t1 = new Time();		// День начального события
Time t2 = new Time();		// День проверки события
    
t1.set(31, 11, 2013);	
t2.set(1, 0, 2014);
t1.normalize(true);
t2.normalize(true);		
    
long ft = t1.toMillis(true);
long nt = t2.toMillis(true);
      
while(ft <= nt){
  ft += 24 * 60 * 60 * 1000 * K;
}
    
// Дата ближайшего события на момент t2
t1.set(ft);

Log.d(tag, "t1.year = " + t1.year
    + " t1.month = " + t1.month
    + " t1.monthDay = " + t1.monthDay
    + " t1.yearDay = " + t1.yearDay
    + " t1.weekDay = " + t1.weekDay);

Log:

t1.year = 2014 t1.month = 0 t1.monthDay = 7 t1.yearDay = 6 t1.weekDay = 2

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
vdem, 2014-07-26
@Martivic

(I never wrote for Android myself.) Doesn't the Time class have a method like addMillis(), or addSeconds()? I'm more than sure that the standard class library provides some kind of operation on dates and times, other than purely storing them in objects.
UPD: Let's say an event needs to be reminded K days after the current moment. In milliseconds, this is Km = K * 24 * 60 * 60 * 1000.

...
android.text.format.Time t = new android.text.format.Time();
t.set((new java.util.Date()).getTime() + K * 24 * 60 * 60 * 1000);
...

V
Vladimir Yakushev, 2014-07-26
@VYakushev

Folks, don't reinvent the wheel! There is a wonderful Calendar class and its roll() and add() methods that solve this problem in one line. For example:

Calendar myCal = new GregorianCalendar(2014, 1, 12); // устанавливаем нужную нам дату
myCal.add(Calendar.DAY_OF_YEAR, 4); // добавляем четыре дня 
myCal.add(Calendar.HOUR, 10); // и ещё плюсуем 10 часиков сверху
Date newDate = myCal.getTime(); // ну и получаем новую дату

M
Max, 2014-07-28
@mbelskiy

I hope you use alarmmanager to create reminders

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question