@Martivic

Как реализовать алгоритм расчета даты, при заданной цикличности?

Здравствуйте!
В android - приложении необходимо реализовать функционал ежедневника: напоминание события через каждые К дней.
Имеется начальная дата с которой начинается событие, предположим, 1.1.2014, текущая дата телефона 26.07.2014, и цикличность К - дней [1- ... ] через которые событие повторяется.
По этим данным необходимо вычислить дату следующего повторения события.
Пробовал использовать класс: 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);

Результат получается необходимый:

t3.year = 2014 t3.month = 6 t3.monthDay = 30 t3.yearDay = 210 t3.weekDay = 3
30 июля 2014, среда

Но проблемы начинаются, при дате, у которой начальный год меньше текущего

UPD: Решение
1. Переводим день, с которого нужно вычислять последующие события, в миллисекунды и запишем в ft. В моем примере (1.1.2014)
2. Переводим день, на который нужно проверить событие, в миллисекунды и запишем nt. В моем примере (26.07.2014)
3. Формируем цикл while do с условием ( ft <= nt ), равенство т.к событие может наступить в проверяемый день. Телом цикла будет увеличение ft на значение повторения события К в миллисекундах: ft += 24 * 3600 * 1000 * K
4. Результатом работы цикла будет ближайшая дата в мс на которую приходится повтор события.
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);

Лог:

t1.year = 2014 t1.month = 0 t1.monthDay = 7 t1.yearDay = 6 t1.weekDay = 2
  • Вопрос задан
  • 4468 просмотров
Решения вопроса 1
@vdem
(Сам для Android никогда не писал.) А нету ли у класса Time метода вроде addMillis(), или addSeconds()? Я более чем уверен, что в стандартной библиотеке классов предусмотрены какие-то операции над датой и временем, кроме чисто хранения в объектах.

UPD: Допустим, событие надо напомнить через K дней после текущего момента. В миллисекундах это 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);
...
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
VYakushev
@VYakushev
Разработчик Android в Nowtaxi
Народ, не надо изобретать велосипедов!!! Есть прекрасный класс Calendar и его методы roll() и add(), которые решают данную задачу одной строкой. К примеру:
Calendar myCal = new GregorianCalendar(2014, 1, 12); // устанавливаем нужную нам дату
myCal.add(Calendar.DAY_OF_YEAR, 4); // добавляем четыре дня 
myCal.add(Calendar.HOUR, 10); // и ещё плюсуем 10 часиков сверху
Date newDate = myCal.getTime(); // ну и получаем новую дату
Ответ написан
mbelskiy
@mbelskiy
Software Developer
Я надеюсь вы используете alarmmanager для создания напоминаний
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы