J'arrive pas à soustraire le mois en JAVA [Fermé]

Signaler
-
 Walid -
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){
}
}
}

4 réponses

Messages postés
16232
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 juin 2020
2 618
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
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 78131 internautes nous ont dit merci ce mois-ci

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
Messages postés
16232
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 juin 2020
2 618 > Walid
Et c'est quoi le problème ? Ton code ne sert à rien si on ne sait pas ce que tu veux faire !

Pour la partie DATE EDITION & DOMICILIATION, tu peux combiner mes deux codes (1, et 2), mais je ne sais pas si "soustraire 6 mois" est toujours d'actualité...

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();

Calendar cd = new GregorianCalendar(annee, mois-1, jour); //!\ Janvier=0
Date date = cd.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MMyyyy");
System.out.println("La date de la domiciliation : "+sdf.format(date));
Merci beaucoup beaucoup donc la je pense que je suis sur la bonne voie

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

public class Tester
{
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();
int jour=0;
Calendar cd = new GregorianCalendar(annee, mois-6, jour); //!\ Janvier=0
Date date = cd.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MMyyyy");
System.out.println("La date des domiciliations à editer : "+sdf.format(date));


}
}


par exemple quand je rentre le mois : 12 et année : 2012 le systeme fait la soustraction et me donne 062012 , jusqu'ici tout va bien. Autre part j'ai le champ date_tit que je lui fait appel par la commande select from ........il est sous forme ddMMyyyy et la je dois générer les trames dont le mois et l'année de leurs date_tit = 062012 et cet date_tit il est en format String .....

en gros voila ce que je dois faire

L'utilisateur aura à saisir le mois et l'année voulu (la génération du répertoire se fait mensuellement), en cliquant sur F4, le système va chercher les domiciliations ouverte il y'a 6mois et va générer pour chaque domiciliation une ligne contenant des informations(Trame).

Les trames (chaque trame représente une ligne et donc une domiciliation) seront stockées dans un fichier plat et envoyé à l'Office des changes qui consommera ce fichier (ainsi que les fichier fourni par les autres banques selon la même structure) via un programme qui lui permettra de l'intégrer dans sa bd afin de pouvoir le visualiser via une application.

je ne sais pas comment vous remercier sérieusement :/ désolé si j'arrive pas à bien m'exprimer
Messages postés
16232
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 juin 2020
2 618 > Walid
mois-6 n'est pas suffisant, parce qu'il faut prendre en compte le cas où le mois est inférieur à 6.
De plus l'année commence par le mois 0, alors que le mois commence par le jour 1, il faut donc encore retirer 1 au mois et ajouter 1 au jour pour être correct, parce que là tu vas être décalé sinon !
Regarde mes codes précédents pour voir les différences avec le tien...
> Walid
daccord merci beaucoup cher KX je vais faire ça tout de suite :) et j'arette je suis fatigué, je reprendrai ça demain :) passez une excellente soirée !
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.
Utilisateur anonyme
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
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 ;)
Messages postés
623
Date d'inscription
vendredi 26 juillet 2002
Statut
Membre
Dernière intervention
11 novembre 2012
967
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();
		}
	}
}


;-)
Merciiiiiiiiiiiiiiiiiiiiii :)
Messages postés
623
Date d'inscription
vendredi 26 juillet 2002
Statut
Membre
Dernière intervention
11 novembre 2012
967
Salut Walid!

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

;-)
HackTrack
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 :/
Messages postés
16232
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 juin 2020
2 618
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)
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 .....
Messages postés
16232
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
3 juin 2020
2 618
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).
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