J'arrive pas à soustraire le mois en JAVA

Fermé
Walid - Modifié par Walid le 2/08/2012 à 01:09
 Walid - 9 août 2012 à 23:33
Bonjour,

Donc voila je suis en stage et je réaliser une application qui permet la génération d'une trame qui contient des informations donc mon problème c'est que je n'arrive pas à soustraire 6 mois d'une date que l'utilisateur entre avec Scanner bon voici mon code, si vous pouvez m'apporter quelques améliorations ça sera le bienvenue merci d'avance !!
PS: ce n'est qu'une petite partie du code de l'apps

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class NewJFrame {

public static void main(String[] args) {

String mois = null;
String annee= null;
try {
Scanner sc= new Scanner (System.in);
System.out.println("entrez le mois voulu (MM):");

mois = sc.next();

Scanner sc1= new Scanner (System.in);
System.out.println("entrez l'année voulu (yyyy):");
annee = sc1.next();

String annedit = mois+annee;
SimpleDateFormat sdf=new SimpleDateFormat("MMyyyy");
sdf.parse(annedit,new ParsePosition(0));
System.out.println("L'année d'édition est: "+annedit);

annedit.add(annedit.MONTH, -6);
}
catch (Exception e){
}
}
}
A voir également:

4 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
2 août 2012 à 02:17
1) Il n'est pas nécessaire de créer un objet Scanner(System.in) à chaque fois, le clavier étant unique, son flux de données l'est lui aussi, donc faire des doublons c'est moche.

2) Ton utilisation des dates est très maladroite, déjà tu n'utilises jamais d'objet Date, mais à la place tu fais de la manipulation de String avec un rocambolesque annedit, que tu utilises comme un Calendar sorti de nul part... c'est très bizarre !

Exemple :

import java.util.Scanner;

public class Test
{
	public static void main(String...args)
	{
		Scanner clavier = new Scanner(System.in);
	
		System.out.print("Entrez le mois voulu : ");
		int mois = clavier.nextInt();
		
		System.out.print("Entrez l'année voulue: ");
		int annee = clavier.nextInt();
	
		System.out.printf("Date originale: %d/%d\n",mois,annee);
		
		// soustraction de 6 mois
		if (mois>6)
		{
			mois-=6;
		}
		else
		{
			annee--;
			mois+=6;
		}
		
		System.out.printf("Date modifiée : %d/%d\n",mois,annee);
	}
}

Ici tu n'en n'avais pas besoin mais si tu veux utiliser des vraies classes de manipulation de dates, tu peux le faire le correctement comme ceci :

int annee, jour, mois;
Calendar cd = new GregorianCalendar(annee,mois-1,jour); //!\ Janvier=0
Date date = cd.getTime();
3
désolé pour toutes ses fautes ^^ je debute c'est mon premier stage, donc merci pour votre exemple, mais le problème c'est que je dois garder le mois sous format ("MM") et l'année sous format ("yyyyy") car quand je saisie par exemple le mois '09' et l'année 2010 le systeme m'affiche 20109 il ne prend pas le 0 en considération parceque c'est un Int .... je sais plus quoi faire HELP T_T' :

try {
String mois,annee,moiss,année,datedit,datedom ;


Scanner sc= new Scanner (System.in);

System.out.println("entrez le mois voulu");
mois = sc.next();
System.out.println("entrez l'année voulu");
annee = sc.next();
datedit =annee+mois;

moiss = (date_tit).substring(2,4); //permet d'extraire le mois du titre
année = (date_tit).substring(4,8); //permet d'extraire l'année du titre
datedom=moiss+année;
System.out.println("La date de la domiciliation : "+datedom);



le (date_tit) c'est un champ qui appartient à une table, dailleurs j'ai fait une cnx JDBC pour manipuler les tables .... c'est tout ce que je peux vous donner comme explications .. si vous voulez que je met tout le code de l'apps en entier dites le :)
MERCI
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015 > Walid
2 août 2012 à 17:26
Je ne vois pas ce qui pose problème... à part bien sûr que tu utilises encore des String au lieu d'un objet Date qui serait bien plus judicieux !

int annee = 2010, mois = 9, jour = 1;
Calendar cd = new GregorianCalendar(annee, mois-1, jour); //!\ Janvier=0
Date date = cd.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MMyyyy");
System.out.println(sdf.format(date));
0
Walid > Walid
2 août 2012 à 17:46
1- si j'utilise des objets Date je ne pourrais pas faire la methode Substring
2- et les dates je les ai pas c'est l'utilisateur qui va les entrer avec le Scanner ... je pense que il ne va pas me servir le Calendar non ??
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015 > Walid
2 août 2012 à 17:53
1) La méthode substring ne te sers à rien si tu utilises des objets Date !
2) Si l'utilisateur entre des entiers (avec nextInt), c'est plus facile de soustraire 6 mois. L'objet Date tu le construis avec le Calendar, donc les String ne servent à rien, tu n'as pas de problème avec le 0 qui traîne, et en plus tu peux mettre ton objet Date directement dans la base de données.

Il n'y a que des avantages à coder proprement !
0
Pour avoir une idée sur ce que doit faire l'application :

package test;
import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import com.mysql.jdbc.ResultSetMetaData;
import com.mysql.jdbc.Statement;
import java.util.*;


public class Main {

public static void main(String[] args) {

// |||||||||||||||||||||||||||||||||||||||||||------CONNEXION JDBC------|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection cnx = DriverManager.getConnection("jdbc:mysql://localhost:3306/walid","root", "wacwacwac");
Statement state = (Statement) cnx.createStatement();
ResultSet result = state.executeQuery ("SELECT banque.code_bq_oc, guichet.code_guichet_oc, domiciliation.categ_tit, domiciliation.date_tit, CONCAT(banque.code_bq_oc,guichet.code_guichet_oc,domiciliation.num_dom) AS num_titre ,domiciliation.code_pay_prov, client.rais_soc, client.centre_rc, client.num_rc, domiciliation.mont_dom, domiciliation.dev_mont_dom, domiciliation.incoterm, apurement.mont_acompte, apurement.dev_mont_acompte, apurement.date_rglm_acompte, imputation.mont_impu,imputation.date_impu, imputation.mont_rgl, imputation.dev_mont_rgl,reglement.num_formule, reglement.date_rglm_formule,mont_fret+mont_fob AS mont_fact,apurement.situation_apurement FROM domiciliation, banque, guichet, apurement, imputation, client, reglement");
ResultSetMetaData resultMeta = (ResultSetMetaData) result.getMetaData();
while(result.next()){
for(int i = 1; i <= resultMeta.getColumnCount(); i++);



// |||||||||||||||||||||||||||||||||||||||||||--------ELEMENTS DE LA TRAME------||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

String code_bq_oc = result.getString("code_bq_oc");
String code_guichet_oc = result.getString("code_guichet_oc");
String categ_tit = result.getString("categ_tit");
String date_tit = result.getString("date_tit");
String num_titre = result.getString("num_titre");
String code_pay_prov = result.getString("code_pay_prov");
String rais_soc = result.getString("rais_soc");
String centre_rc = result.getString("centre_rc");
String num_rc = result.getString("num_rc");
String mont_dom = result.getString("mont_dom");
String dev_mont_dom = result.getString("dev_mont_dom");
String incoterm = result.getString("incoterm");
String mont_acompte = result.getString("mont_acompte");
String dev_mont_acompte = result.getString("dev_mont_acompte");
String date_rglm_acompte = result.getString("date_rglm_acompte");
String mont_impu = result.getString("mont_impu");
String date_impu = result.getString("date_impu");
String mont_rgl = result.getString("mont_rgl");
String dev_mont_rgl = result.getString("dev_mont_rgl");
String num_formule = result.getString("num_formule");
String date_rglm_formule = result.getString("date_rglm_formule");
String mont_fact = result.getString("mont_fact");
String situation_apurement = result.getString("situation_apurement");


// |||||||||||||||||||||||||||||||||||||||||||||------DATE EDITION & DOMICILIATION ----------|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

try {
String mois,annee,moiss,année,datedit,datedom ;


Scanner sc= new Scanner (System.in);

System.out.println("entrez le mois voulu");
mois = sc.next();
System.out.println("entrez l'année voulu");
annee = sc.next();
datedit =annee+mois;

moiss = (date_tit).substring(2,4); //permet d'extraire le mois du titre
année = (date_tit).substring(4,8); //permet d'extraire l'année du titre
datedom=moiss+année;
System.out.println("La date de la domiciliation : "+datedom);


// ||||||||||||||||||||||||||||||||||||||||||||||||||---TRAAAAMEEEE---||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

String Ligne = new String();
Ligne=code_bq_oc+code_guichet_oc+datedit+categ_tit+date_tit+num_titre+code_pay_prov+rais_soc+centre_rc+num_rc+mont_dom+dev_mont_dom+incoterm+mont_acompte+dev_mont_acompte+date_rglm_acompte+mont_impu+date_impu+mont_rgl+dev_mont_rgl+num_formule+date_rglm_formule+mont_fact+situation_apurement;
System.out.println("Trame: "+Ligne);

// ||||||||||||||||||||||||||||||||||||||||||||||||---ECRITURE DANS FICHIER PLAT----||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

FileWriter fichier = new FileWriter(new File("MonFichier.txt"), true);
fichier.write("\r"+Ligne ); // ecris dans le fichier.
System.out.println();
fichier.close() ; // Ferme le flux du fichier, sauvegardant ainsi les données.

}


catch (Exception e) {


}
result.close();
state.close();
}
}
catch(Exception e){

}
}
}

Désolé de vous déranger ^^, je galère vraiment et je n'ai pas vu trop de Java ... il me reste plus qu'un mois je n'ai même pas encor fini mon service
0
Salut,

En cas de besoins (pour les manipulations de dates avec Calendar/GregorianCalendar) voici une petite appli qui permet de soustraire 6 mois à une date entrée en utilisant Scanner et qui prend en compte les années bissextiles (on peut le constater en entrant la date
29
8
2012).

DateFormat n'est volontairement pas utilisé mais bien entendu c'est possible

Voici donc cette classe:

   import java.util.Scanner; 
   import java.util.GregorianCalendar;  
   import java.util.Calendar; 
    
   public class CalculDates 
   { 
      public static void main(String args[]) 
      { 
         int p1 = 0; // p1 = param année 
         int p2 = 0; // p2 = param mois 
         int p3 = 0; // p3 = param jour 
       
       
         Scanner clavier = new Scanner(System.in); 
          
         System.out.print("Entrez le jour: "); 
         //int jj = clavier.nextInt(); 
         p3 = clavier.nextInt(); 
          
         System.out.print("Entrez le mois: "); 
        // int mm = clavier.nextInt(); 
         p2 = clavier.nextInt(); 
        
         System.out.print("Entrez l'année: "); 
         //int aaaa = clavier.nextInt(); 
         p1 = clavier.nextInt(); 
        
       // Bonus: forcer éventuellement un zéro à gauche du jour et du mois 
         String num_moisS = (p2<10?"0":"") + p2; 
         String jourS = (p3<10?"0":"") + p3; 
          
         String dateEntree = jourS + "/" + num_moisS+ "/" + p1;  
         System.out.println("La date entrée = " + dateEntree); 
          
         p2--; // le mois retourné étant une valeur 0 à 11, (janvier = 0,... décembre 11)) 
               // il faut toujours soustraire 1 au mois désiré sauf si on veut faire un contrôle 
         // strict de la valeur entrée ( cal.setLenient(false); >> "pas d'indugence" ). 
         // Dans ce cas pas de calculs de dates possibles comme par eemple savoir 
         // quelle sera la date dans 20 mois... 
         // Par défaut setLenient(true); 
          
       // VOIR LA JAVA-DOC 
       // https://docs.oracle.com/javase/6/docs/api/ classes Calendar et GregorianCalendar 
          
       //Soustraction de 6 mois à la date entrée: 
         Calendar cal = new GregorianCalendar(p1, p2-6, p3);  
   
         int annee = cal.get(Calendar.YEAR); 
         int num_mois = cal.get(Calendar.MONTH);    // 0 à 11 
         int jour = cal.get(Calendar.DAY_OF_MONTH); // 1 à 28 ou 1 à 29 ou 1 à 30 ou 1 à 31 
          
       //Bonus: forcer éventuellement un zéro à gauche du jour et du mois 
         num_moisS = ((num_mois +1)<10?"0":"") + (num_mois +1); 
         jourS = (jour<10?"0":"") + jour; 
          
         String dateMoins6Mois = jourS + "/" + (num_moisS) + "/" + annee;  
         System.out.println("La date moins six mois = " + dateMoins6Mois); 
      } 
   } 


Cordialement,

Dan
Plus on apprend... plus on se rend compte qu'on ne connaît pas grand-chose.
1
Utilisateur anonyme
4 août 2012 à 06:52
Salut,

Pour tenir compte du fait qu'on ne garde que le mois et l'année, remplacer les 2 dernières lignes de mon code:
        String dateMoins6Mois = jourS + "/" + (num_moisS) + "/" + annee; 
         System.out.println("Date moins six mois = " + dateMoins6Mois); 

par:
        String moisSaisiMoins6EtAnnee = num_moisS + annee;
        System.out.println("Mois saisi moins six et année = " + moisSaisiMoins6EtAnnee);


Et tenir compte du fait que si le mois saisi fait partie des 6 mois soustraits, il faut saisir le nombre de jours de ce mois dans p3, ou dans le cas contraire, saisir 1 dans p3.

Ou bien automatiquement en initialisant p3 à la valeur du nombre de jours du mois, ou à 1 et ne plus saisir p3.

Soit, initialiser p3 à 1, mais si le mois fait partie des 6 mois et uniquement dans ce cas en extrayant le nombre de jours du mois:

Ce qui donnerait ce code nouveau:

   import java.util.Scanner;
   import java.util.GregorianCalendar; 
   import java.util.Calendar;
   
   public class CalculDates
   {
      public static void main(String args[])
      {
         int p1 = 0; // param année
         int p2 = 0; // param mois
         int p3 = 1; // param jour
      
         Calendar cal;
      
         Scanner clavier = new Scanner(System.in);
         
         //System.out.print("Entrez le jour: ");
         //p3 = clavier.nextInt();
         
         System.out.print("Entrez le mois: ");
         p2 = clavier.nextInt();
      	
      	
         System.out.print("Entrez l'année: ");
         p1 = clavier.nextInt();
            
      	// Obtenir le nombre de jours du mois saisi:
         cal = new GregorianCalendar(p1, p2-1, p3);
         p3 = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
         System.out.println("Nombre de jours du mois entré = " + p3);
      	
      	// Bonus: forcer éventuellement un zéro à gauche du jour et du mois
         String num_moisS = (p2<10?"0":"") + p2;
         String jourS = (p3<10?"0":"") + p3;
         
         String dateEntree = jourS + "/" + num_moisS+ "/" + p1; 
         System.out.println("La date de ref. = " + dateEntree);
         
         p2--; // le mois retourné étant une valeur 0 à 11, (janvier = 0,... décembre 11))
               // il faut toujours soustraire 1 au mois désiré sauf si on veut faire un contrôle
      			// strict de la valeur entrée ( cal.setLenient(false); >> "pas d'indugence" ).
      			// Dans ce cas pas de calculs de dates possibles comme par eemple savoir
      			// quelle sera la date dans 20 mois...
      			// Par défaut setLenient(true);
      			
      	// VOIR LA JAVA-DOC
      	// https://docs.oracle.com/javase/6/docs/api/ classes Calendar et GregorianCalendar
         
      	
      	//Soustraction de 6 mois à la date entrée:
         cal = new GregorianCalendar(p1, p2-6, p3);
         																		
         int annee = cal.get(Calendar.YEAR);
         int num_mois = cal.get(Calendar.MONTH);    // 0 à 11
         int jour = cal.get(Calendar.DAY_OF_MONTH); // 1 à 28 ou 1 à 29 ou 1 à 30 ou 1 à 31
         
      	//Bonus: forcer éventuellement un zéro à gauche du jour et du mois
         num_moisS = ((num_mois +1)<10?"0":"") + (num_mois +1);
         jourS = (jour<10?"0":"") + jour;
         
         //String dateMoins6Mois = jourS + "/" + (num_moisS) + "/" + annee; 
         //System.out.println("Date moins six mois = " + dateMoins6Mois);
         
         String moisMoins6MoisEtAnnee = num_moisS + annee;
         System.out.println("Mois moins six mois et année = " + moisMoins6MoisEtAnnee); 
      }
 



Dan
0
Merci énormément Dan :) ça marche ! j'aurai un dernier problème qui sera:
je dois comparer la date qui est sous format MMyyyy avec un champ date_tit qui est sur la base de donnée. Par exemple l'utilisateur à saisi le mois 09 et année 2009 ça donne 092009 avec la soustraction de 6 mois ça va me donner 032009 donc cet "032009" je dois la comparer avec la "date_tit" qui sous la forme ddMMyyyy genre select .........................from domiciliation WHERE date_tit = "092009" mais le problème c'est que "date_tit" est un char(8), j'arrive pas à changer son type en Date(8) ddMMyyyy ... puis les comparer.
En bref je dois générer une trame dont sa date_tit = la date entrée -6 mois ;)
0
Utilisateur anonyme
4 août 2012 à 09:28
Salut!

Je reprends ce que disait KX: pourquoi vous cassez-vous la tête à "réinventer la roue"?

Il existe des classes qui font tout le travail pour vous.

package hacktrack.substractmonthfromdate;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;

public class SubstractMonthDemo {

	public static void main(String[] args) {
		GregorianCalendar calendar = (GregorianCalendar) GregorianCalendar
				.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("MMyyyy");
		int mois = 0;
		int annee = 2012;
		try {
			Scanner sc = new Scanner(System.in);
			System.out.println("Entrez le mois voulu (MM):");
			mois = sc.nextInt()-16;
			//Tu dois soustraire 1 à la valeur du mois entrée par l'utilisateur car en Java, Janvier=0 mais l'utilisateur encode Janvier=1

			System.out.println("Entrez l'année voulue (yyyy):");
			annee = sc.nextInt();

			calendar.set(annee, mois - 6, 1);

			Date date = calendar.getTime();// La date que tu peux utiliser pour
											// le stockage en DB (voir le post
											// de KX)
			
			//Pour l'affichage, tu dois ajouter 1 au mois car en Java, Janvier=0 et pour l'affichage Janvie =1
			calendar.set(annee, mois - 5, 1);
			String dateStr = sdf.format(calendar.getTime());
			System.out.println("L'année d'édition est: " + dateStr);

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


;-)
1
Merciiiiiiiiiiiiiiiiiiiiii :)
0
Utilisateur anonyme
8 août 2012 à 21:33
Salut Walid!

N'oublie pas de marquer le post "Résolu"

;-)
HackTrack
0
j'aurai un dernier problème qui sera:
je dois comparer la date qui est sous format MMyyyy avec un champ date_tit qui est sur la base de donnée. Par exemple l'utilisateur à saisi le mois 09 et année 2009 ça donne 092009 avec la soustraction de 6 mois ça va me donner 032009 donc cet "032009" je dois la comparer avec la "date_tit" qui sous la forme ddMMyyyy genre select .........................from domiciliation WHERE date_tit = "092009" mais le problème c'est que "date_tit" est un char(8), j'arrive pas à changer son type en Date(8) ddMMyyyy ... puis les comparer.
En bref je dois générer une trame dont sa date_tit = la date entrée -6 mois ;)

PLEASE HELP :/
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
9 août 2012 à 14:29
Au risque de me répéter, c'est pour cela que l'on doit utiliser des objets Date, et non pas des String qui n'ont pas la même sémantique et donc aucune méthode de manipulation appropriée...

Date date1, date2;
int n = date1.compareTo(date2); // n<0  si date1.before(date2)
                                // n==0 si date1.equals(date2)
                                // n>0  si date1.after (date2)
0
Mais j'arrive pas à donner à "date_tit" un type date sur sql sous format ddMMyyyy, le type Date donne par défaut le format dd/MM/yyyyy .....
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
9 août 2012 à 16:38
Dans ta base de donnée SQL tu as une valeur de type DATE, que tu récupères avec un objet java.sql.Date (qui hérite de java.util.Date) et que tu manipules avec des méthodes dédiées au traitement de dates, avant de remettre la DATE dans ta base SQL...

Tu n'as donc jamais besoin de faire une conversion en String pour manipuler des dates, sauf éventuellement pour l'affichage, mais ça se fait directement :

System.out.printf("%1$td%1$tm%1$tY\n", date);

Remarque : en plus les objets Date seront moins gourmands en mémoire dans la base de donnée que ta chaîne de caractères (1 long=8 octets vs. 8 char=16 octets).
0
Bonjour,
mais je peux pas avoir une valeur Date qui contient que 8 caractère (ddMMyyyy) si son type est Date ça va donner automatiquement la date avec 10 caractères ==>(dd/MM/yyyy) que ma BDD SQL bien entendu
PS: je suis pas sur mon pc la maintenant, j'essayerai ce que vous venez de me donner une je serai chez moi

bonne soirée
0