Transférée distance valeurs DateTime dans un objet DataSet sont converties à l'heure locale équivalent d'un ordinateur distant qui se trouve dans un fuseau horaire différent

Traductions disponibles Traductions disponibles
Numéro d'article: 842545 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Lorsque vous transmettez un objet de la classe DataSet à un service Web à distance ou à un service Web qui est dans un fuseau horaire qui diffère le fuseau horaire de l'application appelante, les colonnes DateTime dans un tableau contenu sont convertis à l'heure locale équivalent. Les colonnes DateTime sont converties car le code System.Data.DataSet s'ajuste pour le temps local équivalent en fonction du fuseau horaire de l'ordinateur distant. Par exemple, si une valeur de 17 est transmise d'un ordinateur client en heure du Pacifique à un service Web en temps est, la valeur de l'objet DataSet change à 8:00 dans la méthode réception du service Web. Cet article explique comment contourner ce problème en passant les informations de fuseau horaire à partir de l'application cliente au service Web et en ajustant les colonnes DateTime sur l'ordinateur distant. Le System.Data est l'espace de noms qui contient la classe DataSet.

Symptômes

Les valeurs des colonnes DateTime changent lorsque vous transmettez un objet System.Data.DataSet à un service Web ou à un service Web à distance. Ce problème se produit si votre service Web ou un service Web distant se trouve dans un autre fuseau horaire à l'application cliente. Les valeurs des colonnes DateTime sont converties à le l'heure locale équivalent en fonction dans le fuseau horaire de l'ordinateur distant.

Cause

Le fuseau horaire de l'application cliente est stocké au cours de la sérialisation objet DataSet . L'objet DataSet est désérialisée à la fin de réception et le code System.Data.DataSet ajuste les colonnes DateTime à l'heure locale équivalente de l'ordinateur distant qui se trouve dans un fuseau horaire différent.

Contournement

Pour contourner ce problème, vous devez transmettre informations du fuseau horaire lorsque l'objet DataSet est créée dans l'application cliente et puis vous devez ajuster l'objet DataSet après que qu'il a été reçu dans le processus appelé sur l'ordinateur distant. Pour ce faire, procédez comme suit :
  1. Dans le projet de service Web sur l'ordinateur distant, écrire du code qui ajuste les valeurs DateTime selon le fuseau horaire de l'application cliente. Pour ce faire, procédez comme suit :
    1. Ajoutez le code suivant dans le Service1 de classe tel que spécifié dans la section « Création d'un service Web »: chaîne public
      [WebMethod]
      public string AdjustDSTimeZone( DataSet dataSet ) 
      {
      
       // Obtains the time difference on the sender computer that
       //remoted this dataset to the Web service.
       string str;	
       string sourceTicksString = dataSet.ExtendedProperties["UTCDifference"].ToString();
       long sourceTicks = long.Parse( sourceTicksString );
       // Obtain the UTC offset for the remote computer.
       DateTime baseUTC = DateTime.Now;
       long UtcTickslocal = TimeZone.CurrentTimeZone.GetUtcOffset( baseUTC ).Ticks;
       // Obtain the time difference between the sender computer and the remote computer.
       long ticksDifference = sourceTicks - UtcTickslocal;
       TimeSpan timespan = new TimeSpan( ticksDifference );
       
       // The following code iterates through each table, and find all the columns that are 
       // DateTime columns. After identifying the columns that have to be adjusted,
       // it traverses the data in the table and adjusts the DateTime columns back to their 
       // original values. You must leave the RowState of the DataRow in the same state 
       //after making the adjustments.
       foreach( DataTable table in dataSet.Tables ) 
       {
        DataColumnCollection columns = table.Columns;
        int[] ColumnNumbers = new int[columns.Count];
        int   ColumnNumbersIndex = 0;
        for( int i = 0; i < columns.Count; i++ ) 
        {
         DataColumn col = columns[i];
         if ( col.DataType == typeof( DateTime ) ) 
         {	
       	ColumnNumbers[ColumnNumbersIndex] = i;
      	ColumnNumbersIndex++;
         }
       }
       foreach( DataRow row in table.Rows ) 
       {
        switch ( row.RowState ) 
        {
         case DataRowState.Unchanged:
          AdjustDateTimeValues( row, ColumnNumbers,
          ColumnNumbersIndex, timespan );
          row.AcceptChanges();	// This is to make sure that the
          // row appears to be unchanged again.
          Debug.Assert( row.RowState == DataRowState.Unchanged );
          break;
         case DataRowState.Added:
          AdjustDateTimeValues( row, ColumnNumbers, ColumnNumbersIndex, timespan );
          // The row is still in a DataRowState.Added state.
          Debug.Assert( row.RowState == DataRowState.Added );
           break;
         case DataRowState.Modified:
           AdjustDateTimeValues( row, ColumnNumbers, ColumnNumbersIndex, timespan );
          // The row is a still DataRowState.Modified.
          Debug.Assert( row.RowState == DataRowState.Modified );
          break;
         case DataRowState.Deleted:
          //   This is to make sure that you obtain the right results if 
          //the .RejectChanges()method is called.
          row.RejectChanges();	// This is to "undo" the delete.
          AdjustDateTimeValues( row, ColumnNumbers, ColumnNumbersIndex, timespan );	
          // To adjust the datatime values.
          // The row is now in DataRowState.Modified state.
          Debug.Assert( row.RowState == DataRowState.Modified );
          row.AcceptChanges();	// This is to mark the changes as permanent.
          Debug.Assert( row.RowState == DataRowState.Unchanged );
          row.Delete();			
          // Delete the row. Now, it has the same state as it started.
          Debug.Assert( row.RowState == DataRowState.Deleted );
          break;
          default:
          throw new ApplicationException
          ( "You must add a case statement that handles the new version of the dataset." );
         }
        }
       } 
       str=dataSet.Tables["MyTable"].Rows[0][1].ToString() ; 
       return str;
      }
      
      la méthode AdjustDSTimeZone ajuste les valeurs de type DateTime pour refléter l'heure d'origine de l'application cliente. Ici, ExtendedProperties propriété de la classe DataSet est utilisée pour stocker le décalage de temps universel coordonné (UTC) avec l'objet DataSet . Avec la propriété ExtendedProperties , vous pouvez stocker des informations personnalisées à l'objet DataSet . Si vous souhaitez que l'objet DataSet à être transférée distance, vous devez stocker le décalage UTC en tant que chaîne dans ExtendedProperties collection.
    2. Ajoutez le code suivant sous la AdjustDSTimeZone méthode :
      void AdjustDateTimeValues( DataRow row, int[] ColumnNumbers, int columnCount, TimeSpan timespan) 
      {
        for ( int i = 0; i < columnCount; i++ ) 
        {
      	int columnIndex = ColumnNumbers[i];
      	DateTime original = (DateTime)row[columnIndex];
      	DateTime modifiedDateTime = original.Add(timespan);
      	row[columnIndex] = modifiedDateTime;
        }
      }
    3. Dans le menu Fichier , cliquez sur Enregistrer tout pour enregistrer l'application.
    4. Dans le menu Générer , cliquez sur Générer la solution pour générer l'application.
    La méthode AdjustDateTimeValues rend l'ajustement à l'objet DateTime . Il obtient l'heure d'origine de la colonne DateTime d'une ligne spécifique, puis modifie l'heure locale de l'application cliente.
  2. Dans l'application cliente, écrire du code qui vérifie que le service Web a ajusté les informations de fuseau horaire. Pour ce faire, procédez comme suit :
    1. Ajoutez le code suivant dans la principale fonction après le code est spécifié dans la section Créer une application client :
      str=myDatasetService.AdjustDSTimeZone(myDataset );
      Console.WriteLine (str);
      Console.ReadLine ();
    2. Dans l'Explorateur de solutions, développez tous les dossiers.
    3. Cliquez avec le bouton droit sur WebReference1 , puis cliquez sur Mise à jour une référence Web .
    4. Dans le menu Fichier , cliquez sur Enregistrer tout pour enregistrer l'application.
    5. Dans le menu Générer , cliquez sur Générer la solution pour générer l'application.
    6. Dans le menu Déboguer , cliquez sur Démarrer pour exécuter l'application.
L'application cliente se connecte à la table MyTable qui contient une colonne DateTime. Elle crée un objet du service Web et transmet un objet de la classe DataSet à la méthode AdjustDSTimeZone du site Web service. La méthode AdjustDSTimeZone dans le service Web met à jour le DateTime colonne de la MyTable table selon le fuseau horaire de l'application cliente et puis renvoie la valeur DateTime de la première ligne de la table MyTable. La valeur de type DateTime qui est reçue par l'application cliente est identique à celle qui est transmis par l'application cliente sur le Web service.

Statut

Ce comportement est voulu par la conception même du produit.

Plus d'informations

Procédure pour reproduire le problème

Créer une table de base de données

Pour créer une table de base de données dans une instance de Microsoft SQL Server, procédez comme suit :
  1. Démarrez l'Analyseur de requêtes SQL.
  2. Dans le menu Fichier , cliquez sur Nouveau .
  3. Cliquez sur fenêtre de requête vide , puis cliquez sur OK .
  4. Collez le code suivant dans la fenêtre de requête. Ce code crée la table MyTable.
    CREATE  TABLE MyTable (
    
                [ID] [int] NOT NULL ,
    
                [DateTimeCol] [datetime] NOT NULL 
    
    ) ON [PRIMARY]
    
    Go
    Insert into MyTable Values (1, '2004-05-19 15:00:00.000')
    Go
    
    Insert into MyTable Values (2, '2004-05-19 13:00:00.000')
    Go
    
    
  5. Dans le menu requête , cliquez sur Exécuter pour exécuter la requête. Le MaTable table est créée et la table est mise à jour avec les deux valeurs.

Créer un service Web

Créer un projet de service Web sur un ordinateur distant qui reçoit les valeurs DateTime d'une application cliente. Pour ce faire, procédez comme suit :
  1. Démarrez Microsoft Visual Studio .NET.
  2. Dans le menu Fichier , pointez sur Nouveau , puis cliquez sur projet .
  3. Sous types de projets , cliquez sur projets Visual C# , puis cliquez sur Service Web ASP.NET sous modèles .
  4. Dans la zone Nom , tapez MyWebService et puis cliquez sur OK . Par défaut, le fichier Service1.asmx est créé.
  5. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le fichier Service1.asmx , puis cliquez sur Afficher le code .
  6. Ajoutez le code suivant au début du fichier :
    using System.Data.SqlClient;
    using System.Timers;
  7. Recherchez le code suivant dans le Service1 classe :
    public class Service1 : System.Web.Services.WebService
    {
  8. Ajoutez le code suivant après le code que vous avez localisée à l'étape 7:
    [WebMethod]
    public String DataSetReturn( DataSet clientDataSet )
    {
      string str;				
      str=clientDataSet.Tables["MyTable"].Rows[0][1].ToString() ;
      return str;	
    }
    la méthode DataSetReturn reçoit un objet du DataSet qui est transmis par l'application cliente. Cette méthode renvoie la valeur DateTime de la première ligne de la table MyTable à l'application cliente.
  9. Dans le menu Fichier , cliquez sur Enregistrer tout pour enregistrer l'application.
  10. Dans le menu Générer , cliquez sur Créer solution pour créer l'application.

Créer une application client

Pour créer une application client qui transmet un objet DataSet au service Web distant, procédez comme suit :
  1. Démarrez Microsoft Visual Studio .NET.
  2. Dans le menu Fichier , pointez sur Nouveau , puis cliquez sur projet .
  3. Sous types de projets , cliquez sur projets Visual C# , puis cliquez sur application console sous modèles .
  4. Dans la zone Nom , tapez MyDataSet et puis cliquez sur OK . Par défaut, le fichier Class1.cs est créé.
  5. Ajoutez le code suivant au début du fichier :
    using System.Data;
    using System.Data.SqlClient;
    using System.Timers;
    using System.Diagnostics;
  6. Ajoutez le code suivant dans la principale fonction :
    string auth="Server=YourServer;Database=YourDatabase;User ID=YourUserID;password=YourPassword";
    WebReference1.Service1 myDatasetService = new WebReference1.Service1();
    DataSet myDataset = new DataSet();
    SqlDataAdapter da = new SqlDataAdapter("Select * From MyTable",auth);
    da.Fill(myDataset, "MyTable");
    //Modify first row to have the current time.
    myDataset.Tables["MyTable"].Rows[0][1] = DateTime.Now;
    string str=myDataset.Tables["MyTable"].Rows[0][1].ToString() ;
    System.Console.WriteLine(str);
    //Store the ticks from UTC in the ExtendedProperties collection of the DataSet
    DateTime clientDateTime = DateTime.Now;
    myDataset.ExtendedProperties["UTCDifference"] = TimeZone.CurrentTimeZone.GetUtcOffset
    ( clientDateTime ).Ticks.ToString();    
    str= myDatasetService.DataSetReturn(myDataset );
    Console.WriteLine (str);
    Console.ReadLine ();
    
    myDataset.Tables["MyTable"].Rows[0][1] = DateTime.Now chaîne str=myDataset.Tables["MyTable"].Rows[0][1].ToString() System.Console.WriteLine(str) ; //Store les graduations de UTC dans la collection ExtendedProperties de la clientDateTime DataSet DateTime = DateTime.Now ; myDataset.ExtendedProperties["UTCDifference "] = TimeZone.CurrentTimeZone.GetUtcOffset (clientDateTime).ticks.ToString(); str = myDatasetService.DataSetReturn (myDataset) Console.WriteLine (str) Console.ReadLine (); Remarque pour accéder à la MaTable table, vous devez modifier les informations de serveur et les informations de base de données et avec le nom d'utilisateur et le mot de passe pour établir la connexion avec Microsoft SQL Server.
  7. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur Références , puis cliquez sur Ajouter une référence Web .
  8. Dans la zone URL , tapez http:// RemoteServer /MyWebService/Service1.asmx et puis cliquez sur OK . Par défaut, dans Visual Studio .NET 2002, un site Web référence est nommé WebReference1 est créée.

    note RemoteServer est un espace réservé pour le nom du serveur distant où le service Web est créé.
  9. Dans Microsoft Visual Studio .NET 2003, tapez WebReference1 dans le nom de la référence Web zone. Ici, WebReference1 sert à correspond à la syntaxe du code.
  10. Cliquez sur Ajouter la référence .
  11. Dans le menu Fichier , cliquez sur Enregistrer tout pour enregistrer l'application.
  12. Dans le menu Générer , cliquez sur Créer solution pour créer l'application.
  13. Dans le menu Déboguer , cliquez sur Démarrer pour exécuter l'application.
L'application cliente modifie la colonne DateTime de la première ligne. Le code définit la valeur de type DateTime à la date actuelle et l'heure de l'application cliente. Elle transmet un objet DataSet au service Web. Le service Web reçoit l'objet DataSet , extrait la valeur de la colonne DateTime dans la première ligne et puis renvoie la valeur à l'application client. La valeur DateTime renvoyée par le service Web est modifiée en fonction en informations de fuseau horaire du serveur distant comme spécifié dans la « Symptômes » de cet article section.

.NET framework remoting

Si vous implémentez les services d'accès distant .NET Framework dans votre application et que vous n'appelez pas une méthode de service .NET Framework Web, vous pouvez utiliser le code de classe DataSetSurrogate . Pour plus d'informations sur la classe DataSetSurrogate, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
829740 Amélioration des performances de sérialisation et accès distant DataSet
La classe DataSetSurrogate empêche les ajustements de fuseau horaire local sur les colonnes DateTime. Cette classe offre également de meilleures performances au cours de .NET Framework remoting. La classe DataSetSurrogate remplace la sérialisation par défaut de la classe DataSet et sérialise la classe DataSetSurrogate et ses membres contenus sous forme binaire.

Références

Pour plus d'informations, reportez-vous aux sites Microsoft Developer réseau MSDN (Web adresses suivantes :
System.Data.SqlClient espace de noms
http://msdn2.microsoft.com/en-us/library/system.data.sqlclient(vs.71).aspx
DataSet.ExtendedProperties propriété
http://msdn2.microsoft.com/en-us/library/system.data.dataset.extendedproperties(vs.71).aspx

Propriétés

Numéro d'article: 842545 - Dernière mise à jour: vendredi 18 mai 2007 - Version: 1.5
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Mots-clés : 
kbmt kbtshoot kbwebservices kbremoting kbclient kbsystemdata kbsqlclient kbservice kbprb KB842545 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 842545
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com