Valores DateTime controlado remotamente num objecto DataSet são convertidas para a hora local equivalente de um computador remoto que esteja no fuso horário diferente

Traduções de Artigos Traduções de Artigos
Artigo: 842545 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Quando passar um objecto da classe DataSet para um serviço Web remoto ou a um serviço Web que está num fuso horário diferente do fuso horário da aplicação chamada, as colunas de DateTime numa tabela contida são convertidas para a hora local equivalente. As colunas de DateTime são convertidas porque o código de System.Data.DataSet ajustada para a hora local equivalente acordo com para o fuso horário do computador remoto. Por exemplo, se um valor de 5: 00 é transmitido de um computador cliente na hora do Pacífico, a um serviço Web na hora do Leste, o valor no objecto DataSet for alterado para 8: 00 no método de recepção do serviço Web. Este artigo descreve como contornar este problema por passar as informações de fuso horário da aplicação cliente para o serviço da Web e ajustando as colunas de DateTime no computador remoto. O System.data é o espaço de nomes que contém class. DataSet

Sintomas

Os valores das colunas DateTime alterados quando passar de um objecto System.Data.DataSet para um serviço Web ou a um serviço Web remoto. Este problema ocorre quando o serviço Web ou serviço da Web remoto está num fuso horário diferente do que a aplicação cliente. Os valores das colunas DateTime são convertidos para a hora local equivalente acordo com para o fuso horário do computador remoto.

Causa

O fuso horário da aplicação cliente é armazenado durante a serialização do objecto DataSet . O objecto de DataSet é anular a serialização na extremidade que recebe e o código de System.Data.DataSet ajusta as colunas de DateTime para a hora local equivalente do computador remoto que esteja no fuso horário diferente.

Como contornar

Para contornar este problema, tem de passar informações sobre o fuso horário quando o objecto de DataSet é criado na aplicação cliente e, em seguida, tem de ajustar o objecto de DataSet depois foi recebida no processo de chamada no computador remoto. Para o fazer, siga estes passos:
  1. Num projecto de serviço Web no computador remoto, escreva o código que ajusta os valores de DateTime de acordo com o fuso horário da aplicação cliente. Para o fazer, siga estes passos:
    1. Adicione o seguinte código Service1 classe tal como especificado na secção "Criar um serviço Web": cadeia pública
      [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;
      }
      
      método AdjustDSTimeZone ajusta os valores DateTime para reflectir a hora original da aplicação cliente. Aqui ExtendedProperties propriedade da classe DataSet é utilizada para armazenar o desvio de tempo universal coordenado (UTC) com o objecto de DataSet . Com a propriedade ExtendedProperties , pode armazenar informações personalizadas com o objecto de DataSet . Se pretender que o objecto DataSet seja controlado remotamente, tem de guardar o deslocamento UTC como uma cadeia em ExtendedProperties colecção.
    2. Adicione o seguinte código abaixo AdjustDSTimeZone método:
      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. No menu ficheiro , clique em Guardar tudo para guardar a aplicação.
    4. No menu criar , clique em Criar soluções para compilar a aplicação.
    O método AdjustDateTimeValues faz com que o ajuste ao objecto de DateTime . -Obtém o tempo original da coluna DateTime de uma determinada linha e, em seguida, modifica acordo com até à hora local da aplicação cliente.
  2. Na aplicação cliente, escreva o código que verifica que o serviço da Web tiver ajustado as informações de fuso horário. Para o fazer, siga estes passos:
    1. Adicione o seguinte código a principal função após o código especificado na secção "Criar uma aplicação cliente":
      str=myDatasetService.AdjustDSTimeZone(myDataset );
      Console.WriteLine (str);
      Console.ReadLine ();
    2. No Solution Explorer, expanda todas as pastas.
    3. Clique com o botão direito do rato WebReference1 e, em seguida, clique em Actualização Web referência .
    4. No menu ficheiro , clique em Guardar tudo para guardar a aplicação.
    5. No menu criar , clique em Criar soluções para compilar a aplicação.
    6. No menu Debug , clique em Iniciar para executar a aplicação.
A aplicação cliente estabelece ligação à tabela AMinhaTabela que contém uma coluna de DateTime. Cria um objecto do serviço Web e passa um objecto da classe DataSet para o método AdjustDSTimeZone da Web service. O método AdjustDSTimeZone no serviço Web actualiza o DateTime tabela coluna da AMinhaTabela acordo com para o fuso horário da aplicação de cliente e, em seguida, devolve o valor DateTime da primeira linha da tabela AMinhaTabela. O valor DateTime é recebido pela aplicação cliente é igual ao valor que é transmitido pela aplicação de cliente para a Web service.

Ponto Da Situação

Este comportamento ocorre por predefinição.

Mais Informação

Passos para reproduzir o problema

Criar uma tabela de base de dados

Para criar uma tabela de base de dados numa instância do Microsoft SQL Server, siga estes passos:
  1. Inicie o SQL Query Analyzer.
  2. No menu ficheiro , clique em Novo .
  3. Clique em Janela de consulta em branco e, em seguida, clique em OK .
  4. Cole o seguinte código na janela de consulta. Este código cria a tabela AMinhaTabela.
    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. No menu de consulta , clique em Executar para executar a consulta. A AMinhaTabela tabela é criada e a tabela é actualizada com dois valores.

Criar um serviço Web

Crie um projecto de serviço Web num computador remoto que recebe os valores DateTime de uma aplicação cliente. Para o fazer, siga estes passos:
  1. Inicie o Microsoft Visual Studio NET..
  2. No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
  3. Em Project Types , clique em Visual C# Projects e, em seguida, clique em Serviço Web do ASP.NET em modelos .
  4. Na caixa nome , escreva MyWebService e, em seguida, clique em OK . Por predefinição, o ficheiro Service1.asmx é criado.
  5. No Solution Explorer, clique com o botão direito do rato no ficheiro Service1.asmx e, em seguida, clique em Código .
  6. Adicione o seguinte código no início do ficheiro:
    using System.Data.SqlClient;
    using System.Timers;
  7. Localize o seguinte código no Service1 classe:
    public class Service1 : System.Web.Services.WebService
    {
  8. Adicione o seguinte código após o código que localizou no passo 7:
    [WebMethod]
    public String DataSetReturn( DataSet clientDataSet )
    {
      string str;				
      str=clientDataSet.Tables["MyTable"].Rows[0][1].ToString() ;
      return str;	
    }
    o método DataSetReturn recebe um objecto do DataSet que é transmitido pela aplicação cliente. Este método devolve o valor DateTime da primeira linha da tabela AMinhaTabela à aplicação cliente.
  9. No menu ficheiro , clique em Guardar tudo para guardar a aplicação.
  10. No menu criar , clique em criar soluções para compilar a aplicação.

Criar uma aplicação cliente

Para criar uma aplicação cliente que passa um objecto de DataSet ao serviço Web remoto, siga estes passos:
  1. Inicie o Microsoft Visual Studio NET..
  2. No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
  3. Em Project Types , clique em Visual C# Projects e clique em Aplicação de consola em modelos .
  4. Na caixa nome , escreva MyDataSet e, em seguida, clique em OK . Por predefinição, o ficheiro Class1.cs é criado.
  5. Adicione o seguinte código no início do ficheiro:
    using System.Data;
    using System.Data.SqlClient;
    using System.Timers;
    using System.Diagnostics;
  6. Adicione o seguinte código principal função:
    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 ();
    
    NOTA: para aceder a AMinhaTabela tabela, tem de modificar as informações de servidor e as informações de base de dados em conjunto com o nome de utilizador e a palavra-passe para estabelecer ligação com o Microsoft SQL Server.
  7. No Solution Explorer, clique com o botão direito do rato em References e, em seguida, clique em Adicionar referência Web .
  8. Na caixa URL , escreva http:// RemoteServer /MyWebService/Service1.asmx e, em seguida, clique em Ir . Por predefinição, no Visual Studio .NET 2002, um Web referência denominado WebReference1 é criada.

    Nota RemoteServer é um marcador para o nome do servidor remoto onde o serviço da Web é criado.
  9. No Microsoft Visual Studio .NET 2003, escreva WebReference1 no nome da referência Web caixa. Aqui WebReference1 é utilizado para corresponder a sintaxe do código.
  10. Clique em Adicionar referência .
  11. No menu ficheiro , clique em Guardar tudo para guardar a aplicação.
  12. No menu criar , clique em criar soluções para compilar a aplicação.
  13. No menu Debug , clique em Iniciar para executar a aplicação.
A aplicação cliente modifica a coluna de DateTime da primeira linha. O código define o valor DateTime para a data e hora actuais da aplicação cliente. Transmitir um objecto de DataSet para o serviço Web. O serviço da Web recebe o objecto de DataSet , obtém o valor da coluna DateTime da primeira linha e, em seguida, devolve o valor anterior à aplicação cliente. O valor DateTime que é devolvido pelo serviço da Web é alterado acordo com as informações de fuso horário do servidor remoto como especificadas em "Sintomas" secção.

Sistema de interacção remota .NET framework

Se estiver a implementar os serviços de sistema de interacção remota do .NET Framework na sua aplicação e não chamar um método de serviço Web do .NET Framework, pode utilizar o código de classe DataSetSurrogate .Para obter informações adicionais sobre a classe DataSetSurrogate, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
829740Melhorar o desempenho de serialização e sistema de interacção remota DataSet
A classe DataSetSurrogate impede que os ajustes de fuso horário local nas colunas DateTime. Esta classe fornece também um melhor desempenho durante o sistema de interacção remota .NET Framework. A classe DataSetSurrogate substitui a serialização predefinido da classe DataSet e serializes classe DataSetSurrogate e respectivos membros contidos no formato binário.

Referências

Para obter mais informações, visite os seguintes Web sites da Microsoft Developer Network (MSDN):
System.data.SqlClient espaço de nomes
http://msdn2.microsoft.com/en-us/library/system.data.sqlclient(vs.71).aspx
DataSet.ExtendedProperties propriedade
http://msdn2.microsoft.com/en-us/library/system.data.dataset.extendedproperties(vs.71).aspx

Propriedades

Artigo: 842545 - Última revisão: 18 de maio de 2007 - Revisão: 1.5
A informação contida neste artigo aplica-se a:
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Palavras-chave: 
kbmt kbtshoot kbwebservices kbremoting kbclient kbsystemdata kbsqlclient kbservice kbprb KB842545 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 842545

Submeter comentários

 

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