Os valores de DateTime remotos em um objeto de DataSet são convertidos a hora local equivalente de um computador remoto que está em um fuso horário diferente

Traduções deste artigo Traduções deste artigo
ID do artigo: 842545 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

Quando você passar um objeto da classe DataSet para um serviço da Web remoto ou para um serviço da Web que está em um fuso horário que seja diferente do fuso horário do aplicativo de chamada, as colunas DateTime em uma tabela contida são convertidas para a hora local equivalente. As colunas de DateTime são convertidas porque o código System.Data.DataSet ajusta a hora local equivalente de acordo com o fuso horário do computador remoto. Por exemplo, se um valor de 5: 00 for passado em um computador cliente na hora a um serviço da Web em hora, o valor no objeto DataSet é alterado para 8: 00 no método de recebimento do serviço da Web. Este artigo descreve como solucionar esse problema, passando as informações de fuso horário do aplicativo cliente para o serviço da Web e ajustar as colunas DateTime no computador remoto. O System.Data é o namespace que contém o DataSet class.

Sintomas

Os valores das colunas DateTime alterados quando você passar um objeto System.Data.DataSet para um serviço da Web ou para um serviço da Web remoto. Esse problema ocorre quando o serviço da Web ou serviço da Web remoto está em um fuso horário diferente do aplicativo cliente. Os valores em colunas DateTime são convertidos em hora local equivalente de acordo com o fuso horário do computador remoto.

Causa

O fuso horário do aplicativo cliente é armazenado durante a serialização de objeto de DataSet . O objeto DataSet é desserializado na extremidade receptora e o código System.Data.DataSet ajusta as colunas DateTime para a hora local equivalente do computador remoto que está em um fuso horário diferente.

Como Contornar

Para contornar este problema, você deve passar informações sobre o fuso horário quando o objeto DataSet é criado no aplicativo cliente e, em seguida, você deve ajustar o objeto DataSet depois que tiver sido recebida no processo de chamada no computador remoto. Para fazer isso, execute as seguintes etapas:
  1. No projeto de serviço da Web no computador remoto, escreva código que ajusta os valores de DateTime de acordo com o fuso horário do aplicativo cliente. Para fazer isso, execute as seguintes etapas:
    1. Adicione o seguinte código no Service1 classe conforme especificado na seção "Criar um serviço da Web":
      [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;
      }
      
      o método AdjustDSTimeZone ajusta os valores de DateTime para refletir a hora original do aplicativo cliente. Aqui ExtendedProperties propriedade da classe DataSet é usada para armazenar o deslocamento da hora universal coordenada (UTC) com o objeto DataSet . Com a propriedade ExtendedProperties , você pode armazenar informações personalizadas com o objeto DataSet . Se desejar que o objeto de DataSet para o remoto, você deve armazenar o deslocamento UTC como uma seqüência de caracteres em ExtendedProperties coleçã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 arquivo , clique em Salvar tudo para salvar o aplicativo.
    4. No menu Build , clique em Build Solution para criar o aplicativo.
    O método AdjustDateTimeValues torna o ajuste para o objeto DateTime . Ele obtém a hora original da coluna DateTime de uma linha específica e, em seguida, modifica acordo com para a hora local do aplicativo cliente.
  2. No aplicativo cliente, escreva um código que verifica que o serviço da Web ajustou as informações de fuso horário. Para fazer isso, execute as seguintes etapas:
    1. Adicione o seguinte código no principal função após o código que é especificada na seção "Criar um aplicativo 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 mouse WebReference1 e clique em Update Web Reference .
    4. No menu arquivo , clique em Salvar tudo para salvar o aplicativo.
    5. No menu Build , clique em Build Solution para criar o aplicativo.
    6. No menu Debug , clique em Iniciar para executar o aplicativo.
O aplicativo cliente se conecta à tabela de MyTable que contém uma coluna de DateTime. Cria um objeto do serviço da Web e passa um objeto da classe DataSet para o método AdjustDSTimeZone da Web service. O método AdjustDSTimeZone no serviço da Web atualiza o DateTime tabela de coluna do MyTable acordo com a fuso horário do aplicativo cliente e, em seguida, retorna o valor DateTime de primeira linha da tabela MyTable. O valor DateTime que é recebido pelo aplicativo cliente é o mesmo que o valor é passado pelo aplicativo cliente para a Web service.

Situação

Esse comportamento é por design.

Mais Informações

Etapas para reproduzir o problema

Criar uma tabela de banco de dados

Para criar uma tabela de banco de dados em uma instância do Microsoft SQL Server, execute estas etapas:
  1. Inicie o SQL Query Analyzer.
  2. No menu arquivo , clique em novo .
  3. Clique em Janela de consulta em branco e, em seguida, clique em OK .
  4. Cole o código a seguir na janela de consulta. Esse código cria a tabela de 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. No menu consulta , clique em Executar para executar a consulta. O MyTable tabela é criada e a tabela é atualizada com dois valores.

Criar um serviço da Web

Criar um projeto de serviço da Web em um computador remoto que recebe os valores de DateTime de um aplicativo cliente. Para fazer isso, execute as seguintes etapas:
  1. Inicie o Microsoft Visual Studio NET..
  2. No menu arquivo , aponte para novo e, em seguida, clique em Project .
  3. Em Project Types , clique em projetos translation from VPE for Csharp Visual e, em seguida, clique em ASP.NET Web Service em modelos .
  4. Na caixa nome , digite MyWebService e, em seguida, clique em OK . Por padrão, o arquivo Service1.asmx é criado.
  5. No Solution Explorer, clique com o botão direito no arquivo Service1.asmx e, em seguida, clique em View Code .
  6. Adicione o seguinte código no início do arquivo:
    using System.Data.SqlClient;
    using System.Timers;
  7. Localize o código a seguir no Service1 classe:
    public class Service1 : System.Web.Services.WebService
    {
  8. Adicione o seguinte código após o código localizado na etapa 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 objeto de DataSet que é passado pelo aplicativo cliente. Esse método retorna o valor DateTime da primeira linha da tabela MyTable para o aplicativo cliente.
  9. No menu arquivo , clique em Salvar tudo para salvar o aplicativo.
  10. No menu Build , clique em Build Solution para criar o aplicativo.

Criar um aplicativo cliente

Para criar um aplicativo cliente que passa um objeto DataSet para o serviço da Web remoto, siga estas etapas:
  1. Inicie o Microsoft Visual Studio NET..
  2. No menu arquivo , aponte para novo e, em seguida, clique em Project .
  3. Em Project Types , clique em projetos translation from VPE for Csharp Visual e, em seguida, clique em Aplicativo de console em modelos .
  4. Na caixa nome , digite MyDataSet e, em seguida, clique em OK . Por padrão, o arquivo Class1.cs é criado.
  5. Adicione o seguinte código no início do arquivo:
    using System.Data;
    using System.Data.SqlClient;
    using System.Timers;
    using System.Diagnostics;
  6. Adicione o seguinte código no 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 ();
    
    Observação para acessar o MyTable tabela, você deve modificar as informações do servidor e as informações de banco de dados juntamente com o nome de usuário e a senha para estabelecer a conexão com o Microsoft SQL Server.
  7. No Solution Explorer, clique com o botão direito do mouse em References e, em seguida, clique em Add Web Reference .
  8. Na caixa URL , digite http:// RemoteServer /MyWebService/Service1.asmx e, em seguida, clique em Ir . Por padrão, no Visual Studio .NET 2002, uma Web de referência é denominada WebReference1 é criada.

    Observação RemoteServer é um espaço reservado para o nome do servidor remoto onde o serviço da Web é criado.
  9. No Microsoft Visual Studio .NET 2003, digite WebReference1 no Web reference name caixa. WebReference1 é usado para coincidir com a sintaxe do código aqui.
  10. Clique em Adicionar referência .
  11. No menu arquivo , clique em Salvar tudo para salvar o aplicativo.
  12. No menu Build , clique em Build Solution para criar o aplicativo.
  13. No menu Debug , clique em Iniciar para executar o aplicativo.
O aplicativo cliente modifica a coluna de DateTime da primeira linha. O código define o valor DateTime para a data atual e a hora do aplicativo cliente. Ele passa um objeto DataSet para o serviço da Web. O serviço da Web recebe o objeto DataSet , recupera o valor da coluna DateTime da primeira linha e retorna o valor de volta para o aplicativo cliente. O valor DateTime que é retornado pelo serviço da Web é alterado de acordo com as informações de fuso horário do servidor remoto como especificadas em "Sintomas" seção.

.NET framework remoting

Se você estiver implementando os serviços de sistema de interação remota .NET Framework em seu aplicativo e não chame um método de serviço da Web do .NET Framework, você pode usar o código da classe DataSetSurrogate .Para obter informações adicionais sobre a classe DataSetSurrogate, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
829740Melhorar o desempenho remoting e serialização DataSet
A classe DataSetSurrogate impede que os ajustes de fuso horário local nas colunas DateTime. Essa classe também fornece melhor desempenho durante o .NET Framework remoting. A classe DataSetSurrogate substitui a serialização padrão da classe DataSet e serializa a classe DataSetSurrogate e seus membros contidos em formato binário.

Referências

Para obter mais informações, visite os seguintes sites do Microsoft Developer Network (MSDN) da:
System.Data.SqlClient espaço para nome
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

ID do artigo: 842545 - Última revisão: sexta-feira, 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 traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes 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