Utiliser GregorianCalendar avec SimpleDateFormat

donc j'ai creusé mon cerveau au-dessus de cet (devrait-être) exercice simple pour faire le programme transformer une chaîne de date en un objet GregorianCalendar, le formater, et le rendre à nouveau comme une chaîne quand il est fait.

c'est le dernier petit morceau d'un programme qui prend dans un chuck de texte d'un dossier, le décompose en dossiers individuels, puis brise les dossiers en morceaux individuels de données et les assigne à un objet de personne.

j'ai vérifié le code en plusieurs endroits et le code fait exactement ce qu'il est censé faire jusqu'à ce que j'appelle la fonction format, qui lance une Illégalargumentexception. L'objet GergorianCalendar se voit attribuer les valeurs qu'il est censé recevoir (bien que l'impression soit, encore une fois, une toute autre histoire comme vu ci-dessous...), mais le format n'acceptera pas l'objet pour le formatage.

malheureusement, l'instructeur ne savait pas trop comment utiliser le calendrier grégorien et SimpleDateFormat (encore nous a assigné de travailler avec eux) et dit "Google juste il"... J'ai essayé, et rien que j'ai trouvé n'a aidé.

le code que j'ai jusqu'à présent est:

public class DateUtil {

    public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException{

        // this actually works, got rid of the original code idea
        String[] splitDate = dd_mm_yy.split("-");
        int days = Integer.parseInt(splitDate[0]);
        int month = Integer.parseInt(splitDate[1]);
        int year = Integer.parseInt(splitDate[2]);

        // dates are going in right, checked in print statement,
        // but the object is not getting formatted...
        GregorianCalendar dateConverted = new GregorianCalendar(year, month, days);
        format(dateConverted);
        return dateConverted;
    }

    public static String format(GregorianCalendar date){

        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        String dateFormatted = fmt.format(date);
        return dateFormatted;
    }
}

l'erreur que j'obtiens est:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object >as a Date

    at java.text.DateFormat.format(DateFormat.java:281)
    at java.text.Format.format(Format.java:140)
    at lab2.DateUtil.format(DateUtil.java:26) 
    at lab2.DateUtil.convertFromDMY(DateUtil.java:19)
    at lab2.Lab2.createStudent(Lab2.java:75)
    at lab2.Lab2.main(Lab2.java:34)

et une autre chose, est-ce que j'utilise le calendrier grégorien?? Quand j'imprime la valeur de cet objet (devrait être d'obtenir une date droite?), Je reçois ceci:

les valeurs de l'Année, du mois et du jour du mois sont toutes correctes car ce sont les nombres que j'ai passés dans sa création.

pensées, suggestions, suis-je même proche?

modifier

origine des problèmes éclairci (merci assylias!) mais je ne peux toujours pas imprimer correctement parce que les deux fonctions ne sont pas liées et que les exigences doivent avoir une valeur de date GregorianCalendar imprimé à partir de l'objet "personne" (la date de naissance étant Unendar grégorien).

code mis à jour:

public class DateUtil {

    static SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");

    public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException{

        // this actually works, got rid of the original code idea
        String[] splitDate = dd_mm_yy.split("-");
        int days = Integer.parseInt(splitDate[0]);
        int month = (Integer.parseInt(splitDate[1]) - 1);
        int year = Integer.parseInt(splitDate[2]);

        // dates go in properly
        GregorianCalendar dateConverted = new GregorianCalendar(year, month, days);
        String finalDate = format(dateConverted);
        return ;
    }

    public static String format(GregorianCalendar date) throws ParseException{

       fmt.setCalendar(date);
        String dateFormatted = fmt.format(date.getTime());
        System.out.println(dateFormatted);
        return dateFormatted;
    }

}

dernière édition

Ok donc il semble que je suis un idiot et N'ai pas besoin de relier les deux fonctions DateUtil ensemble, mais les utiliser en tandem. Tout d'abord, convertissez la date de naissance en Unendar Grégorien et stockez-la dans l'objet personne. Puis dans la déclaration d'impression il suffit de dire au programme de formater que la date est imprimée. Le problème a été résolu. Tous les travaux selon les spécifications maintenant, et je me sens beaucoup plus stupide parce que j'étais flailing comme un poisson hors de l'eau pour le dernier jour ou ainsi avec la classe DateUtil, en essayant de les faire travailler en même temps.

Merci pour l'aide tout sur Obtenir la date aller correctement!

21
demandé sur Chris Stillwell 2012-05-31 12:27:18

5 réponses

SimpleDateFormat#format la méthode prend un Date comme paramètre. Vous pouvez obtenir un Date d'un Calendar en appelant son getTime méthode:

public static String format(GregorianCalendar calendar){
    SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
    fmt.setCalendar(calendar);
    String dateFormatted = fmt.format(calendar.getTime());
    return dateFormatted;
}

notez aussi que les mois commencent à 0 donc vous avez probablement voulu dire:

int month = Integer.parseInt(splitDate[1]) - 1;
46
répondu assylias 2012-05-31 08:33:10

pourquoi de telles complications?

public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException 
{
    SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
    Date date = fmt.parse(dd_mm_yy);
    GregorianCalendar cal = GregorianCalendar.getInstance();
    cal.setTime(date);
    return cal;
}
4
répondu m0skit0 2012-05-31 10:49:35

une forme simple, comme son nom l'indique, formate les Dates. Pas De Calendrier. Donc, si vous voulez formater un calendrier Grégorien en utilisant un format Simpledate, vous devez convertir le calendrier à une date en premier:

dateFormat.format(calendar.getTime());

et ce que vous voyez imprimé est la représentation toString() du calendrier. Son usage est de déboguer. Il n'est pas destiné à être utilisé pour afficher une date dans une interface graphique. Pour cela, utiliser un (Simple)DateFormat.

enfin, pour convertir d'une chaîne de caractères à une Date, vous devriez également utiliser une (Simple)DateFormat (sa méthode parse() ), plutôt que de fendre la chaîne de caractères comme vous le faites. Cela vous donnera un objet Date, et vous pouvez créer un calendrier à partir de la Date en l'instanciant ( Calendar.getInstance() ) et en définissant son heure ( calendar.setTime() ).

Mon conseil serait: Googler n'est pas la solution ici. Lire la documentation API est ce que vous devez faire.

2
répondu JB Nizet 2012-05-31 08:38:57
  1. Vous y mettre à deux chiffres de l'année. Le premier siècle. Et le calendrier grégorien a commencé au 16ème siècle. Je pense que vous devriez ajouter 2000 à l'année.

  2. mois dans la fonction nouveau GregorianCalendar(Année, Mois, jours) est basé sur 0. Soustraire 1 du mois.

  3. modifier le corps de la deuxième fonction de sorte:

        String dateFormatted = null;
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        try {
            dateFormatted = fmt.format(date);
        }
        catch ( IllegalArgumentException e){
            System.out.println(e.getMessage());
        }
        return dateFormatted;
    

après debug vous verrez que simplement GregorianCalendar ne peut pas être argument de la fmt.format();

vraiment, personne n'a besoin de GregorianCalendar comme sortie, même si on vous dit de retourner "une chaîne".

changer l'en-tête de la fonction votre format en

public static String format(Date date) 

et apporter les modifications appropriées. fmt.format() prendra volontiers la date objet.

  1. toujours après un une exception inattendue se produit, attrapez-le vous-même, ne laissez pas la machine java le faire. De cette façon, vous allez comprendre le problème.
1
répondu Gangnus 2012-05-31 09:27:17

tl; dr

LocalDate.parse(
    "23-Mar-2017" ,
    DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) 
)

éviter les classes date-heure héritées

la Question et d'autres réponses sont maintenant dépassées, en utilisant de vieilles classes de date-heure gênantes qui sont maintenant héritées, supplantées par le java.les classes de temps.

utilisant java.time

vous semblez avoir affaire à des valeurs date-only. Alors n'utilisez pas de cours de date-heure. Utilisez plutôt LocalDate . Le LocalDate la classe représente une valeur de date seulement sans Heure de la journée et sans fuseau horaire.

spécifiez un Locale pour déterminer (a) le langage humain pour la traduction du nom du jour, du nom du mois, et tel, et (B) les normes culturelles décidant des questions d'abréviation, de Majuscule, de ponctuation, de séparateurs, et tel.

Parse une corde.

String input = "23-Mar-2017" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f );

génère une chaîne de caractères.

String output = ld.format( f );

si vous avez reçu des chiffres plutôt que du texte pour l'année, le mois et le jour du mois, utilisez LocalDate.of .

LocalDate ld = LocalDate.of( 2017 , 3 , 23 );  // ( year , month 1-12 , day-of-month )

voir ce IdeOne.com .

entrée: 23-mars-2017

ld.toString (): 2017-03-23

Production: 23-Mar-2017


à Propos de Java.heure

Le de java.time framework est construit dans Java 8 et plus tard. Ces classes remplacent les anciennes héritées classes de date-heure telles que java.util.Date , Calendar , & SimpleDateFormat .

The Joda-Time project , maintenant en mode maintenance , conseille la migration vers le java.temps des classes.

pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

utilisant un conducteur JDBC conforme à JDBC 4.2 ou plus tard, vous pouvez échanger java.temps objets directement avec votre base de données. Pas besoin de chaînes ni de java.SQL.* classe.

où obtenir le java.les classes de temps?

Le ThreeTen-Extra le projet s'étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouver ici quelques cours utiles tels que: Interval , YearWeek , YearQuarter , et plus .

1
répondu Basil Bourque 2018-02-15 06:59:49