Adicionando minutos a uma data

Pessoal,
Fiz esse código mas não sei o que pode estar dando errado, pois o mesmo não imprimi a hora correta como deveria ser.
Alguém sabe me dizer o porque não esta funcionando?



/**
 * 
Where,
date: An date as String in the format ?dd/MM/yyyy HH24:mi?;
op: Can be only ?+? | ?-?;
value: the value that should be incremented/decremented. It will be expressed in minutes.
 
Restrictions:
- you shall not work with non-native classes / libraries;
- you shall not make use of neither Data nor Calendar classes;
- if the op is not valid an exception must be thrown;
- if the value is smaller than zero, you should ignore its signal;
- if the result sum is bigger than max value to the field, you should increment its immediate bigger field;
- ignore the fact that February have 28/29 days and always consider only 28 days;
- ignore the daylight save time rules.
 
Example:
changeDate(?15/01/2007 13:22?, ?+?, 150672) = ?31/05/2007 04:34?

 * @author wagnercarvalho
 *
 */
public class DateTnt {

	private Integer day;
	private Integer month;
	private Integer year;
	private Integer hour;
	private Integer minute;
	private Integer minutesDay;
	
	/**
	 *
	 * @param date An date as String in the format ?dd/MM/yyyy HH24:mi?
	 * @param op Can be only ?+? | ?-?
	 * @param value the value that should be incremented/decremented. It will be expressed in minutes
	 * @return
	 */
	public String changeDate(String date, char op, long value) {
		disassemblesDate(date);
		
		sum(value);
		
		System.out.println(day + "/" + month + "/" + year + " " + convertMinutesDayForHourAndMinute(this.minutesDay));
		return "";
	}
	
	public void sum(long value) {
		while (value != 0) {
			if(minutesDay.equals(1440)) {
				minutesDay = 0;
				addOneDay();
			}
			else {
				minutesDay++;
			}
			
			value--;
		}
	}
	
	private void addOneDay() {
		Month month = Month.getMonth(this.month);
		
		if(this.day == month.getNumDay()) {
			this.day = 1;
			addOneMonth();
		}
		else {
			this.day++;
		}
	}

	private void addOneMonth() {
		if(this.month == 12) {
			this.month = 1;
			this.year++;
		}
		else {
			this.month++;
		}
	}
	
	private void disassemblesDate(String dateHour) {
		String[] dates = dateHour.split(" ");

		if(dates != null) {
			if(dates.length == 2) {
				String[] date = dates[0].split("/");
				this.day = Integer.valueOf(date[0]);
				this.month = Integer.valueOf(date[1]);
				this.year = Integer.valueOf(date[2]);
				
				String[] hour = dates[1].split(":");
				this.hour = Integer.valueOf(hour[0]);
				this.minute = Integer.valueOf(hour[1]);
				this.minutesDay = (this.hour * 60) + this.minute;
			}
		}
	}
	
	public String convertMinutesDayForHourAndMinute(long minutes) {
	    long minute = minutes % 60;  
	    long hour = (minutes - minute) / 60;  
	    
	    String m = String.valueOf(minute);
	    
	    if(minute < 10) {
	    	m = "0" + minute;
	    }
	    
		return hour + ":" + m;
	}
	
	
	public static void main(String[] args) {
		DateTnt date = new DateTnt();
		date.changeDate("15/01/2007 13:22", '+', 150672);
	}
	
}

Esta dando como resultado 30/4/2007 2:49, quando deveria ser 31/05/2007 04:34

O enum é:


public enum Month {

	JANUARY(1, 31),
	FEBRUARY(2, 28), 
	MARCH(3, 31),
	APRIL(4, 30), 
	MAY(5, 31), 
	JUNE(6, 30), 
	JULY(7, 31), 
	AUGUST(8, 31),
	SEPTEMBER(9, 30), 
	OCTOBER(10, 31), 
	NOVEMBER(11, 30), 
	DECEMBER(12, 31);
	
	private int num;
	private int numDay;

	Month(int num, int numDay) {
		this.num = num;
		this.numDay = numDay;
	}

	public int getNum() {
		return num;
	}

	public int getNumDay() {
		return numDay;
	}
	
	public static Month getMonth(int num) {
		Month[] values = Month.values();

		for (Month item : values) {
			if (item.getNum() == num) {
				return item;
			}
		}
		
		return null;
	}
	
}

Cara, Se entendi direito é mais fácil você fazer assim.

/* * @autor: alcir barros * @date: 03/10/2012 * */ public static Date dataComCalendar(Date date, Integer horas) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.HOUR_OF_DAY, horas); return calendar.getTime(); }

Transformar a Data em Calendar…

Esse @Alcir Barros é fera em java qualquer coisa da um toque nele ele responde rapidinho …

[quote=tiago2109]Cara, Se entendi direito é mais fácil você fazer assim.

/* * @autor: alcir barros * @date: 03/10/2012 * */ public static Date dataComCalendar(Date date, Integer horas) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.HOUR_OF_DAY, horas); return calendar.getTime(); }

Transformar a Data em Calendar…[/quote]
— you shall not make use of neither Data nor Calendar classes;

Defendendo uma lib nova que está sendo difundida, cara, usa JodaTime;

tem uma classe Chamada DateTime, vc pode somar, subtrair, multiplicar, calcular diferença e não importa se o que vem é calendar ou Date

http://joda-time.sourceforge.net/

http://www.furutani.com.br/2010/02/simplificando-calculos-com-datas-com-joda-time-java/

Para quem sugere Date e JodaTime, não confundam “como as coisas devem ser feitas” com exercícios de aprendizagem.

[quote][code]
public void sum(long value) {
while (value != 0) {
if(minutesDay.equals(1440)) {
minutesDay = 0;
addOneDay();
}
else {
minutesDay++;
}

        value--;  
    }  
}  

[/code]
[/quote]
O teu problema deve ser aqui, Não podes passara para 0 com o minuto é 1440 mas sim quando é 1339. O minuto 1440 já é o minuto 0 do dia seguinte.

Exatamente como disse o pmlm.
Isto é um exercício. E não posso usar classes como Date ou Calendar ou derivadas.

pmlm
Você está certo. Mas mesmo assim isso não solucionou o problema.

Mudei algumas coisas, a hora esta sendo impressa da forma correta mas a data não.



/**
 * Where, 
 * date: An date as String in the format ?dd/MM/yyyy HH24:mi?; 
 * op: Can be only ?+? | ?-?; 
 * value: the value that should be incremented/decremented. It will be expressed in minutes.
 * 
 * Restrictions: 
 * - you shall not work with non-native classes / libraries; 
 * - you shall not make use of neither Data nor Calendar classes; 
 * - if the op is not valid an exception must be thrown; 
 * - if the value is smaller than zero, you should ignore its signal; 
 * - if the result sum is bigger than max value to the field, you should increment its immediate bigger field; 
 * - ignore the fact that February have 28/29 days and always consider only 28 days; 
 * - ignore the daylight save time rules.
 * 
 * Example: changeDate(?15/01/2007 13:22?, ?+?, 150672) = ?31/05/2007 04:34?
 * 
 * @author wagnercarvalho
 * 
 */
public class DateTnt2 {

	private Integer day;
	private Integer month;
	private Integer year;
	private Integer hour;
	private Integer minute;
	private Integer minutesDay;

	/**
	 * 
	 * @param date
	 *            An date as String in the format ?dd/MM/yyyy HH24:mi?
	 * @param op
	 *            Can be only ?+? | ?-?
	 * @param value
	 *            the value that should be incremented/decremented. It will be
	 *            expressed in minutes
	 * @return
	 */
	public String changeDate(String date, char op, long value) throws Exception {
		disassemblesDate(date);

		if (value < 0) {
			value = value * -1;
			op = '-';
		}

		if (op != '-' && op != '+') {
			throw new Exception("This op is invalid.");
		}

		addDaysInDate(countDays(value, op), op);

		return print();
	}
	
	private Integer countDays(long minutes, char op) {
		Integer days = 0;

		while (minutes != 0) {
			if (op == '+') {
				if (this.minutesDay.equals(1439)) {
					this.minutesDay = 0;
					days++;
				} else {
					this.minutesDay++;
				}
			}

			if (op == '-') {
				if (this.minutesDay.equals(0)) {
					this.minutesDay = 1439;
					days++;
				} else {
					this.minutesDay--;
				}
			}

			minutes--;
		}

		return days;
	}

	private void addDaysInDate(Integer days, char op) {
		Month month;

		while (days != 0) {
			if (op == '+') {
				month = Month.getMonth(this.month);

				if (this.day.intValue() == month.getNumDay()) {
					this.day = 1;

					if (this.month.intValue() == 12) {
						this.year++;
						this.month = 1;
					} else {
						this.month++;
					}
				} else {
					this.day++;
				}
			}
			
			if (op == '-') {
				if (this.day == 1) {
					if (this.month == 1) {
						this.year--;
						this.month = 12;
					} else {
						this.month--;
						month = Month.getMonth(this.month);
						this.day = month.getNumDay();
					}
				} else {
					this.day--;
				}
			}
			
			days--;
		}
	}

	private void disassemblesDate(String dateHour) {
		String[] dates = dateHour.split(" ");

		if (dates != null) {
			if (dates.length == 2) {
				String[] date = dates[0].split("/");
				this.day = Integer.valueOf(date[0]);
				this.month = Integer.valueOf(date[1]);
				this.year = Integer.valueOf(date[2]);

				String[] hour = dates[1].split(":");
				this.hour = Integer.valueOf(hour[0]);
				this.minute = Integer.valueOf(hour[1]);
				this.minutesDay = (this.hour * 60) + this.minute;
			}
		}
	}

	private void convertMinutesDayForHourAndMinute(long minutes) {
		Long minute = minutes % 60;
		Long hour = (minutes - minute) / 60;

		this.hour = Integer.valueOf(hour.toString());
		this.minute = Integer.valueOf(minute.toString());
	}

	private String print() {
		convertMinutesDayForHourAndMinute(this.minutesDay);

		String d = this.day.toString();
		String m = this.month.toString();
		String h = this.hour.toString();
		String mi = this.minute.toString();

		if (this.day < 10) {
			d = "0" + this.day;
		}

		if (this.month < 10) {
			m = "0" + this.month;
		}

		if (this.hour < 10) {
			h = "0" + this.hour;
		}

		if (this.minute < 10) {
			mi = "0" + this.minute;
		}

		return d + "/" + m + "/" + this.year + " " + h + ":" + mi;
	}

	public static void main(String[] args) {
		DateTnt2 date = new DateTnt2();

		try {
			System.out.println(date.changeDate("15/01/2007 13:22", '+', 150672));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

Parece-me que o teu exemplo é que está errado :slight_smile:

150672 / 60 / 24 = 104,6333 :arrow: 104 dias e algumas horas.

104 dias são aproximadamente 3 meses e meio, o que dá metade de janeiro que falta, fevereiro, março e abril. Logo nunca poderia dar 31/05.

[quote=pmlm]Para quem sugere Date e JodaTime, não confundam “como as coisas devem ser feitas” com exercícios de aprendizagem.

[quote][code]
public void sum(long value) {
while (value != 0) {
if(minutesDay.equals(1440)) {
minutesDay = 0;
addOneDay();
}
else {
minutesDay++;
}

        value--;  
    }  
}  

[/code]
[/quote]
O teu problema deve ser aqui, Não podes passara para 0 com o minuto é 1440 mas sim quando é 1339. O minuto 1440 já é o minuto 0 do dia seguinte.[/quote]

Hummm, me empolguei, não tinha olhado direito o enunciado da propostta, mals. ^^