none
Conversion Decimal en DateTime RRS feed

  • Question

  • Bonsoir, je n'arrive pas à convertir mes variable (décimal) en DateTime sur C#.

    object y5 = (dataTable8.Rows[b]["Horaire"]);
                                            DateTime horaire = Convert.ToDateTime(y5);
                                            decimal sch5 = horaire.Hour + (horaire.Minute / 60);
    
    decimal yy = horaire.year;
    
    decimal mm = horaire.month;
    
    decimal dd = horaire.day;


    puis je vais appeler sch5 pour y ajouter une donnée : sch6 = sch5 + 0.6 (par exemple). 

    Le problème, je veux reconvertir ces données sous la forme d'un DateTime et les stocker dans une seule variable DateTime. Comment faire s'il vous plait ? Merci.


    dimanche 11 novembre 2012 22:21

Réponses

  • Oui et donc cela va être un cauchemar dès que qq va utiliser un PC avec un réglage différent. Selon la façon dont la date est formattée, on peut même dépendre des réglages du serveur en plus de ceux du PC. Il y a aussi le numérique (2,5 en français mais 2.5 dans une instruction SQL et même les chaines "O'Brian" doit être 'O''Brian' dans une instruction SQL). Pour être précis le problème ne dépend pas du format "dans" la base de données (les dates sont toujours stockées de la même façon) mais de la façon dont elles sont représentées sous forme de texte dans l'instruction SQL (et il existe aussi un format universel 'yyyMMdd' qui permettrait de n'être sensible ni au format du PC, ni à la config du serveur).

    Et donc au risque de me répéter, utiliser des requêtes paramétrées permet de supprimer ces problèmes et de faire fonctionner votre application sans aucun problème indépendamment de la langue du PC comme de la configuration du serveur. Sinon c'est à vous d'utiliser les formats qui vous permettent d'obtenir ce résultat (et donc les "mauvais" formats comme ceux que vous avez choisi peuvent sembler fonctionner sans souci mais rendre votre application dépendante des réglages du PC ou du serveur ce qui est à éviter).

    Je suggère donc "fortement" d'utiliser des requêtes paramétrées qui supprimeront ce problème (et en plus protège mieux contre "les attaques par injection SQL" cf article cité précédemment)


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


    mercredi 14 novembre 2012 09:53
    Modérateur
  • Bonjour,

    Je vous conseille fortement d'écouter ce que dit Patrice :) Il a indiqué toutes les raisons qui pousse à utiliser les requêtes paramétrées.

    Voici un exemple avec DateTime :

    SqlCommand sql = new SqlCommand("UPDATE maTable SET maDate=@pDate WHERE ID=@pID", cnx);
    sql.Parameters.Add("@pDate", System.Data.SqlDbType.DateTime).Value = DateTime.Now; //Pour exemple, je prends la date d'aujourd'hui
    sql.Parameters.Add("@pID", System.Data.SqlDbType.Int).Value = 12345;
    int affected = sql.ExecuteNonQuery();
     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    • Marqué comme réponse Aurel Bera vendredi 16 novembre 2012 09:10
    mercredi 14 novembre 2012 10:29
  • pourquoi passer par des décimales ?
     
    System.DateTime dt = new System.DateTime(horaire.year, horaire.month, horaire.day).AddSeconds((horaire.hour *3600) + (horaire.Minute * 60) + secondes);
    Cordialement,
    Bernard
    

    Bernard Grosperrin, Chardonnay, France.
    lundi 12 novembre 2012 08:08

Toutes les réponses

  • pourquoi passer par des décimales ?
     
    System.DateTime dt = new System.DateTime(horaire.year, horaire.month, horaire.day).AddSeconds((horaire.hour *3600) + (horaire.Minute * 60) + secondes);
    Cordialement,
    Bernard
    

    Bernard Grosperrin, Chardonnay, France.
    lundi 12 novembre 2012 08:08
  • Bonjour,

    Et éventuellement voir également le type TimeSpan (durée) ce qui devrait permettre de faire des calculs directement sur des dates et des durées plutôt que de faire des conversions en numérique...

    yy, mm, dd seront utilisées pour récréer une date une fois que l'on aura ajouter 0,6 heures à l'horaire de départ ? Au final on veut juste ajouter une durée à une date ?

    Par exemple :

         DateTime d1 = DateTime.Now;
                TimeSpan durée=TimeSpan.FromHours(0.6);
                Console.WriteLine(d1.ToString());
                Console.WriteLine(d1.Add(durée).ToString());
                Console.ReadKey();


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



    lundi 12 novembre 2012 13:00
    Modérateur
  • Moi je veux, à partir d'un DateTime (exemple: 12/11/12 08:00:00), extraire la date 12/11/12, puis extraire l'heure 08:00, y ajouter par exemple une valeur (0.5), puis restocker la nouvelle heure, avec la date extraite dans son format original => 12/11/12 08:30:00

    Comment on fait ? Merci.

    lundi 12 novembre 2012 14:33
  • Donc comme indiqué ci-dessus avec 0.5 au lieu de 0,6.

    En fait on veut prendre la date 12/11/12 08:00, ajouter 30 minutes ce qui donne la valeur voulue. Il est inutile d'extraire séparemment la date et les heures, de faire le calcul sur les heures puis de réintégrer le résultat dans la date d'origine. On peut prendre juste la date/heure et ajouter 30 minutes ce qui donne bien une autre date/heure :

                DateTime d1 = new DateTime(2012,11,12,8,0,0);
                TimeSpan durée=TimeSpan.FromHours(0.5);
                Console.WriteLine(d1.ToString());
                Console.WriteLine(d1.Add(durée).ToString());
                Console.ReadKey();

    Le principe est qu'ajouter une date et une durée donne une autre date donc inutile de calculer séparemment sur la partie heure. On peut tout à fait ajouter une durée à une date...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".





    lundi 12 novembre 2012 14:56
    Modérateur
  • Il n'y a rien à extraire pour faire cela. Il me semble qu'il y a un peu de confusion entre la visualisation d'une date, et le type de données dateTime. Pour faire ce que vous demandez, ceci suffira (et fonctionne sur le même principe pour toutes les unitées (Années, Mois, Jours, heures, Minutes, Secondes). Testez le vous-même, c'est vraiment bête comme choux (sans vouloir être péjoratif):

    [Test]
            public void TestDateTime()
            {
                DateTime oldDateTime = new System.DateTime();
                oldDateTime = DateTime.Parse("11/11/12 08:00:00");
                Console.WriteLine(oldDateTime.ToString()); // vérifie que la variable a les bonnes valeurs. La chaine sera conforme à la culture locale
                DateTime newDate = oldDateTime.AddHours(0.5);
                Console.WriteLine(newDate.ToString()); // vérifie que la variable a bien 1/2 h de +. La chaine sera conforme à la culture locale
                DateTime newnewdate =newDate.AddMinutes(30);
                Console.WriteLine(newnewdate.ToString()); // vérifie que la variable a bien encore 1/2 h de +. La chaine sera conforme à la culture locale
            }

    Résultat:

    11/11/2012 08:00:00
    11/11/2012 08:30:00
    11/11/2012 09:00:00

    je crée de nouvelles variables à chaque fois pour être plus clair, mais bien sûr on peut trés bien affecter la nouvelle valeur à la même variable.


    Bernard Grosperrin, Chardonnay, France.



    lundi 12 novembre 2012 15:08
  • Oui, c'est une possibilité, mais comme je le montre on n'est même pas obligé de passer par TimeSpan pour incrémenter/modifier une donnée de type DateTime.

    Bernard Grosperrin, Chardonnay, France.

    lundi 12 novembre 2012 15:16
  • Oui, c'est un peu trop ici mais je voulais tout de même montrer qu'il existe un type durée dans .NET et sur le plan du principe que :

    - ajouter une date et une durée donne une date
    - soustraire 2 dates donne une durée etc...

    Je pense que ce qui gêne "JackBauer" est que d'habitude on ajoute des variables de même type ce qui l'a peut-être poussée à extraire les heures séparemment pour y ajouter des heures avant de réintégrer le résultat dans la date. Je voulais donc insister sur le fait que c'est une durée (qu'elle soit exprimé explicitement avec le type TimeStamp ou qu'elle soit ajoutée directement à la date avec Add<UnitéDeDurée>(Valeur) et qu'ajouter une durée à une date est parfaitement légal).

    C'est un comble que "JackBauer" ait un problème avec les durées ;-)


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


    lundi 12 novembre 2012 15:52
    Modérateur
  • Bonsoir,

    j'interviens pour départager Bernard et Patrice : je suis d'accord avec tous les deux ! ;-)

    Les deux  solutions montrent bien comment manipuler les dates / heures.

    Cordialement.

    lundi 12 novembre 2012 16:05
  • L'affichage est correcte, mais lorsque je veux insérer la valeur dans ma BDD, il m'affiche NULL. Cela est peut-être du au format String de d1 ?

    J'ai pas réussi à la convertir en DateTime. N'y a-t-il pas un autre moyen pour ajouter la durée, sans convertir le datetime en string ? 

    lundi 12 novembre 2012 16:06
  • OK, bien compris. C'est vrai que c'est un peu un comble, mais selon d'où l'on vient, certaines habitudes ont la vie dure...

    Bernard Grosperrin, Chardonnay, France.

    lundi 12 novembre 2012 16:06
  • :-) Merci!

    Bernard Grosperrin, Chardonnay, France.

    lundi 12 novembre 2012 16:07
  • Quel est le type de données pour cette colonne dans la BDD.? Et de quelle base de données parle-t-on ? MS SQL, MySQL, autre ?

    Bernard Grosperrin, Chardonnay, France.

    lundi 12 novembre 2012 16:08
  • Le type de données est DateTime , et j'utilise SQLserver
    lundi 12 novembre 2012 16:13
  • Parfait, alors qu'est ce que tu me comprends pas dans mon exemple?

    ceci devrait faire ton bonheur:

     DateTime myDateTime = new System.DateTime();
    myDateTime = d1;
    myDateTime = myDateTime.AddHours(0.5);
    d1 = mydateTime;

    Pourquoi faire simple quand on peut faire compliqué, n'est-ce pas ? Ou le contraire.... :-)


    Bernard Grosperrin, Chardonnay, France.



    lundi 12 novembre 2012 16:20
  • La date n'est sans doute pas bien passée vers SQL Server. On utilise une requête paramétrée ?

    Je pense que le mieux serait de fermer ce sujet et d'ouvrir un nouveau sujet pour éviter de mélanger des problèmes de nature différente dans une même conversation...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    lundi 12 novembre 2012 16:27
    Modérateur
  • Oui j'ai essayé cette méthode, mais lors de l'exécution, il m'affiche (Incorrect syntaxe near '08' )

    Je crois que le format de DateTime dans la base diffère de celui qui m'est affiché dans C#. L'un est de la forme 2012-09-24 08:00:00:000 (sqlserver) et l'autre de la forme 24/09/2012 08:00:00. Peut être que le problème est là ? 

    lundi 12 novembre 2012 16:27
  • Comme le dit Patrice, il y a un doute sur la manière dont les paramètres sont passés à la requète SQL.

    Mais, et SURTOUT (c'est la vraie raison de ma réponse) la FORME de l'affichage n'ONT RIEN A VOIR avec la valeur de la donnée....
    Ce n'est que du String.format.....

    Pour éliminer les doutes concernant le type de données entre SQL et .Net, essaye quelque chose comme:

     DateTime myDateTime = new System.DateTime();
    myDateTime = d1;
    myDateTime = myDateTime.AddHours(0.5);
    SqlDateTime sqldate = new SqlDateTime(mydateTime);
    puis insére sqldate dans ta requête.


    Bernard Grosperrin, Chardonnay, France.


    lundi 12 novembre 2012 16:36
  • SqlDateTime n'existe pas comme commande dans C#
    lundi 12 novembre 2012 18:18
  • D'une part, il ne s'agit pas d'une commande, mais d'un type, qui existe depuis .net 1.1 et se trouve dans System.Data.Sqltypes:

    SQLtypes sur MSDN


    Bernard Grosperrin, Chardonnay, France.


    lundi 12 novembre 2012 19:09
  • Je suggère fortement d'utiliser des requêtes paramétrées : http://webman.developpez.com/articles/aspnet/sqlparameter/csharp/

    Cela permet notamment de s'affranchir de tous les problèmes de conversion de données en chaines de caractères (pour les insérer dans une instruction SQL). Comme signalé par Bernard, même si les valeurs sont stockées et utilisées de la même façon sous leur type de données natif, pratiquement toutes les valeurs sont par contre affichées (et donc convertie en chaine pour insertion dans une instruction SQL) d'une façon qui dépend du pays (et même pour une chaine ' doit être doublée dans une instruction SQL).

    Une requête parametré prendra en charge cela sans que vous ayez à convertir vous-même sous un format indépendant du pays...

    Sinon donnez du détail sur ce que vous utilisez actuellement (c'est une base SQL Server ?, vous mettez à jour avec un SqlCommand ?)


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    lundi 12 novembre 2012 19:13
    Modérateur
  • SqlCommand cmd7 = new SqlCommand("Update TcTaskSchedule set Schedule1EndTime = " + nvelledate + " from tcMachineUsage where tcMachineUsage.MachineUsageId=" + ID_machine + " and TcTaskSchedule.Date=tcMachineUsage.Date and tcTaskSchedule.TaskId=" + TaskId, cn7);
                                                cmd7.ExecuteNonQuery();
    je fais appel à cette requête sur C#, et j'utilise SQL server 2008 R2
    lundi 12 novembre 2012 19:40
  • Patrice t'as indiqué une bonne référence sur la bonne manière de passer des requetes SQL, que l'on appelle requêtes paramétrées. As-tu pris le temps d'aller lire la page en question?

    Dans l'exemple que tu nous fournis, si "nvelledate" par exemple est une date de type DateTime, ça ne peut pas fonctionner, parceque tu mélange des types différents; Tu es dans un String et tu mets au milieu un DateTime. C'est un peu comme si tu cherchais à additionner des pommes et des oranges. 3 pommes + 2 oranges ça fait ni 5 pommes ni 5 oranges, mais 5 fruits....

    Au minimum, mais tu t'exposes à pas mal d'autres problèmes liés à la culture et autres réglages liés au contexte de la machine, ce devrait être :

    SqlCommand cmd7 = new SqlCommand("Update TcTaskSchedule set Schedule1EndTime = " + nvelledate.ToString() + " fro


    Bernard Grosperrin, Chardonnay, France.

    lundi 12 novembre 2012 19:59
  • L'approche habituelle est de sortir l'instruction SQL calculée. On va s'apercevoir qu'elle n'est pas correcte syntaxiquement pour SQL Server sans doute pour les raisons indiquées ci-dessus.

    Une variable est insensible au pays mais va subir les règles propres au pays dès la conversion en texte (dd/MM/yyyy en France, MM/dd/yyyy aux US etc...) et sera donc incorrecte si on l'insère dans une instruction SQL sans aucune précaution.

    D'où ma recommendation sur les requêtes paramètrées qui permet de supprimer le besoin de convertir les données en texte pour les insérer dans des instructions SQL (cf donc le lien cité dans mon précédent message).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    mardi 13 novembre 2012 09:49
    Modérateur
  • C'est ça, le problème, c'est que moi, j'utilise un pc français, et comme je suis au canada, ils utilisent un format différent dans leurs BDD. Quand j'ai essayé d'exécuter le même code sur un pc américain, ça a marché, il a inséré correctement les dates. 
    mercredi 14 novembre 2012 04:24
  • Oui et donc cela va être un cauchemar dès que qq va utiliser un PC avec un réglage différent. Selon la façon dont la date est formattée, on peut même dépendre des réglages du serveur en plus de ceux du PC. Il y a aussi le numérique (2,5 en français mais 2.5 dans une instruction SQL et même les chaines "O'Brian" doit être 'O''Brian' dans une instruction SQL). Pour être précis le problème ne dépend pas du format "dans" la base de données (les dates sont toujours stockées de la même façon) mais de la façon dont elles sont représentées sous forme de texte dans l'instruction SQL (et il existe aussi un format universel 'yyyMMdd' qui permettrait de n'être sensible ni au format du PC, ni à la config du serveur).

    Et donc au risque de me répéter, utiliser des requêtes paramétrées permet de supprimer ces problèmes et de faire fonctionner votre application sans aucun problème indépendamment de la langue du PC comme de la configuration du serveur. Sinon c'est à vous d'utiliser les formats qui vous permettent d'obtenir ce résultat (et donc les "mauvais" formats comme ceux que vous avez choisi peuvent sembler fonctionner sans souci mais rendre votre application dépendante des réglages du PC ou du serveur ce qui est à éviter).

    Je suggère donc "fortement" d'utiliser des requêtes paramétrées qui supprimeront ce problème (et en plus protège mieux contre "les attaques par injection SQL" cf article cité précédemment)


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


    mercredi 14 novembre 2012 09:53
    Modérateur
  • Bonjour,

    Je vous conseille fortement d'écouter ce que dit Patrice :) Il a indiqué toutes les raisons qui pousse à utiliser les requêtes paramétrées.

    Voici un exemple avec DateTime :

    SqlCommand sql = new SqlCommand("UPDATE maTable SET maDate=@pDate WHERE ID=@pID", cnx);
    sql.Parameters.Add("@pDate", System.Data.SqlDbType.DateTime).Value = DateTime.Now; //Pour exemple, je prends la date d'aujourd'hui
    sql.Parameters.Add("@pID", System.Data.SqlDbType.Int).Value = 12345;
    int affected = sql.ExecuteNonQuery();
     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    • Marqué comme réponse Aurel Bera vendredi 16 novembre 2012 09:10
    mercredi 14 novembre 2012 10:29
  • Sinon tu peux stocker ta date sous un long, ce type là il est compatible sur toutes les bases de données :)

    DateTime v_dt1 = DateTime.Now.Ticks
    
    // Et pour le reconvertir en datetime
    
    DateTime v_dt2 = new DateTime(DateTime.Now.Ticks);

    Alors je tiens à préciser que ce n'est pas obligatoire, etc...., mais c'est une solution comme d'autres et ça n'empêche pas de faire un SqlParameters pour inserer ta data bien sur.

    jeudi 15 novembre 2012 08:24
  • Bonjour,

    Est-ce que vous avez testé les solutions proposées ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    jeudi 15 novembre 2012 15:47
  • Bonjour,

    Pouvons-nous considérer que vous avez résolu votre problème avec les scénarios proposés ? Dans l'affirmative, pourriez-vous partager avec nous la solution, afin que d'autres personnes avec le même problème puissent profiter de cette solution ?

    Désormais, nous marquons les solutions proposées. N'hésitez pas à revenir et supprimer la réponse marquée si la solution n’est pas correcte. Merci !

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    vendredi 16 novembre 2012 09:09