3 votes

Je cherche de l'aide pour créer des rendez-vous de 15 minutes, actuellement codés pour une heure.

C'est la première fois que je poste - je suis plus novice en matière de java/JavaFx.

J'essaie de faire en sorte que mon code soit sauvegardé dans un incrémentaliste de 15 minutes. Le projet a une liste d'observables qui contient des heures de rendez-vous sélectionnables.

ApptAddController.java

private final ObservableList<String> times = FXCollections.observableArrayList("8:00 AM", "9:00 AM", "10:00 AM", "11:00 AM", "12:00 PM", "1:00 PM", "2:00 PM", "3:00 PM", "4:00 PM");

ApptDB.Java

Le "times" sélectionné va à la méthode "saveAppt".

public static boolean saveAppt(int id, String type, String contact, String location, String date, String time) {
        //Time stamp for booking times
        String tsStart = createTimeStamp(date, time, location, true);
        String tsEnd = createTimeStamp(date, time, location, false);
        try {
            //get date for Appointment createDate
            DateTimeFormatter dt = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
            String nowString = LocalDateTime.now(Clock.systemUTC()).format(dt);
            Statement statement = DBConnection.getConnection().createStatement();
            //Query
            String queryInsertOne = "INSERT INTO appointment(customerId, type, contact, location, start, end,  createDate, lastUpdateBy, createdBy) values ('" + id + "', '" + type + "', '" + contact + "', '" + location + "','" + tsStart + "','" + tsEnd + "','" + nowString + "','" + UserDB.getCurrentUser() + "','" + UserDB.getCurrentUser() + "')";
            int updateOne = statement.executeUpdate(queryInsertOne);         
            return true;
       } catch (SQLException e) {
            System.out.println("SQLException: " + e.getMessage());
        }
        return false;
    }

La méthode createTimeStamp est codée en dur dans la méthode suivante avec le "00" :

public static String createTimeStamp(String date, String time, String location, boolean startMode) {
        String t = time.split(":")[0];
        int baseH = Integer.parseInt(t);
        if(baseH < 8) {
            baseH += 12;
        }
        if(!startMode) {
            baseH += 1;
        }
        String baseD = String.format("%s %02d:%s", date, baseH, "00");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm");
        LocalDateTime ldt = LocalDateTime.parse(baseD, dtf);
        ZoneId zid;
        zid = TimeZone.getDefault().toZoneId();
           ZonedDateTime zdt = ldt.atZone(zid);
        ZonedDateTime utcDate = zdt.withZoneSameInstant(ZoneId.of("UTC"));
        ldt = utcDate.toLocalDateTime();
        Timestamp ts = Timestamp.valueOf(ldt); 
        return ts.toString();
    }

J'aimerais que les rendez-vous soient échelonnés sur 15 minutes. L'utilisateur choisira les heures au hasard (8:00, 8:15, 8:30, 8:45). Comment puis-je faire en sorte que ce code détecte ce que l'utilisateur sélectionne et le mette dans la base de données en conséquence. Si je change "00" en "15", cela va coder en dur chaque rendez-vous pour 15 après.

Merci pour votre temps.

4voto

Ole V.V. Points 24677

Si je comprends bien, vous pouvez et devez mettre LocalTime dans votre ObservableList . Plutôt que de String des objets. Si c'est le cas, faites-le.

Utilisez également le type de données SQL time pour les temps dans votre base de données (ils le sont peut-être déjà, je n'ai pas noté cette information dans votre question). Passez le LocalTime à votre base de données en utilisant un PrepatedStatement . Par exemple :

    yourPreparedStatement.setObject(5, startLocalTime);
    yourPreparedStatement.setObject(6, endLocalTime);

Faites de même pour les dates, etc., en utilisant uniquement les types appropriés tant du côté Java que du côté SQL.

Pour calculer l'heure de fin 15 minutes après l'heure de début :

    LocalTime endLocalTime = startLocalTime.plusMinutes(15);

Je sais que je ne vous donne pas un code complet, mais j'espère que cela vous permettra d'avancer d'un pas ou deux.

4voto

Basil Bourque Points 8938

Je n'arrive pas à bien suivre votre code. Voici donc quelques conseils généraux. Je dois dire d'emblée que la gestion des rendez-vous et des horaires est un domaine étonnamment compliqué.

Vous semblez vous concentrer sur les chaînes de caractères plutôt que sur les types de données appropriés, un problème courant chez les nouveaux programmeurs. Apprenez à utiliser des objets intelligents, pas des chaînes de caractères idiotes . Notez qu'aucun des codes présentés ci-dessous n'implique de chaînes de caractères, sauf pour la présentation aux utilisateurs. Les valeurs sont échangées avec la base de données sous forme d'objets, sans l'utilisation de chaînes de caractères.

Java offre un assortiment de classes de date et d'heure à la pointe de l'industrie, dans la catégorie java.time paquets. Alors utilisez-les. LocalTime représente une heure du jour. LocalDate représente une date uniquement, sans heure du jour, et sans fuseau horaire.

Pour la saisie de données sur l'heure du rendez-vous, vous devez collecter une heure et une minute. Travailler en interne avec une horloge de 24 heures LocalTime objets.

List< LocalTime > hourTimes = 
    List.of( 
        LocalTime.of( 8 , 0 ) ,
        LocalTime.of( 9 , 0 ) ,
        LocalTime.of( 10 , 0 ) ,
        LocalTime.of( 11 , 0 ) ,
        LocalTime.of( 12 , 0 ) ,
        LocalTime.of( 13 , 0 ) ,
        LocalTime.of( 14 , 0 ) ,
        LocalTime.of( 15 , 0 ) ,
        LocalTime.of( 16 , 0 ) 
    )
;

Si votre public s'attend à un Horloge de 12 heures présentent leur affichage avec un formateur personnalisé. Si votre public s'attend à une horloge de 12 heures, présentez leur écran avec un formateur personnalisé.

Locale locale = Locale.US ;
DateTimeFormatter formatterHourOfDay = DateTimeFormatter.ofPattern ( "h a" ).withLocale ( locale ) ;
String output = hourTimes.get( 7 ).format( formatterHourOfDay ) ;

Voir similaire code exécuté en direct sur IdeOne.com .

3 PM

Notez que java.time utilise objets immuables . Vous pouvez donc utiliser librement le LocalTime directement à partir de la liste principale, sans qu'il soit nécessaire de copier, ni de s'inquiéter que ses valeurs soient modifiées sous vos pieds. Cela signifie également que vous pouvez utiliser java.time à travers les threads, car ils sont conçus pour être Sécurité des fils .

Conservez une liste des procès-verbaux possibles.

List< Integer > minutes = List.of( 0 , 15 , 30 , 45 ) ;

Dans votre interface utilisateur, laissez l'utilisateur choisir l'une de ces quatre valeurs, qui sera associée à son choix parmi les options suivantes hourTimes ci-dessus.

Rassemblez ces valeurs en fonction de l'heure de la journée pour obtenir une nouvelle valeur. LocalTime .

LocalTime localTime = hourTimes.get( 7 ).plusMinutes( minutes.get( 2 ) ) ;  // Adding 0, 15, 30, or 45 minutes to the on-the-hour `LocalTime` object, resulting in another `LocalTime` object. 

Combinez l'heure du jour avec votre date prévue pour obtenir une LocalDateTime objet.

LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
LocalDateTime localDateTime = LocalDateTime.of( localDate , localTime ) ;

Stockez-le dans une colonne de base de données de type standard SQL. TIMESTAMP WITHOUT TIME ZONE . (c'était "SANS", pas "AVEC")

Il est généralement préférable d'utiliser déclarations préparées en SQL plutôt que de combiner des chaînes de caractères.

myPreparedStatement.setObject( … , localDateTime ) ;

En outre, enregistrez le fuseau horaire prévu pour ce rendez-vous. Il existe un type de données en Java pour cela, ZoneId . Mais pas en SQL. Enregistrez donc le nom de la zone en tant que texte dans votre base de données.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
…
myPreparedStatement.setObject( … , z.toString() ) ;  // Record name of zone as text.

D'ailleurs, il n'est pas nécessaire de transmettre la date de création ou de dernière mise à jour de l'enregistrement. Vous devriez configurer votre base de données pour qu'elle définisse ces valeurs automatiquement du côté du serveur.

Séparez votre logique commerciale de votre interface utilisateur. Remarquez qu'aucun de mes codes ci-dessus ne concerne JavaFX .

Définissez une classe uniquement pour le rendez-vous. Cette classe ne doit connaître que les besoins d'un rendez-vous, les règles de gestion de ce qui définit un rendez-vous valide. Cette classe ne doit rien savoir de la base de données, ni de l'interface utilisateur.

Je ne comprends pas ce que vous essayez de faire avec les fuseaux horaires dans votre utilisation de ZonedDateTime . Il semble que vous essayez de former un java.sql.Timestamp objet. C'est la mauvaise façon de procéder pour deux raisons. Premièrement, cette classe est l'une des terribles classes de date-heure héritées du passé supprimé par java.time ; ne l'utilisent jamais. Deuxièmement, ce n'est pas la bonne façon de prendre des rendez-vous. Les rendez-vous futurs doivent être enregistrés en deux parties distinctes, (a) la date avec l'heure du jour et (b) le fuseau horaire.

Les politiciens du monde entier ont montré un penchant à modifier fréquemment le décalage des fuseaux horaires relevant de leur juridiction. Ils le font avec peu, voire pas du tout, d'avertissement. Ainsi, si vous avez réservé 15 h 45 pour le mois de janvier prochain en tant que moment, en tant que point spécifique sur la ligne du temps, l'heure du jour pour l'horloge murale de cette zone pourrait être modifiée d'ici là, 15 h 45 devenant 15 h 15 ou 16 h 45. Imaginez que votre logiciel prenne un rendez-vous pour le moment précis où était 3:45 PM antes de la zone a modifié son décalage par rapport à l'UTC. Les clients qui respectent leurs rendez-vous apparaîtront à 15 heures à l'heure de l'horloge murale actuelle, alors que votre logiciel de prise de rendez-vous les indiquera comme étant en avance (ou en retard). Pour éviter ce problème, ne pas prendre de rendez-vous à l'improviste conservez la date et l'heure du jour ( LocalDateTime ) séparé du fuseau horaire ( ZoneId ).

Ne combinez les deux (date avec heure du jour et fuseau horaire) que lorsque vous élaborez un programme pour lequel vous avez besoin de moments précis.

ZoneId z = ZoneId.of( zoneNameFromDatabase ) ;
ZonedDateTime zdt = localDateTimeFromDatabase.atZone( z ) ;

Si vous avez besoin de voir ce moment en UTC, ajustez en extrayant un Instant objet.

Instant instant = zdt.toInstant() ;

Mais ne stockez pas non plus les ZonedDateTime o Instant pour l'avenir. Ne les stockez qu'après coup, lors de l'enregistrement de l'histoire. Et même dans ce cas, vous enregistrez OffsetDateTime car, curieusement, la spécification JDBC n'exige pas le support de la fonction ZonedDateTime o Instant . Vous stockez ce OffsetDateTime dans une colonne de type SQL-standard TIMESTAMP WITH TIME ZONE ("AVEC", et non "SANS" comme indiqué ci-dessus).

OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;  // Record history as a moment, a specific point on the timeline.

Table of date-time types in Java (both legacy & modern) and in standard SQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X