PROBLEMA COM DATAS
Boa Noite!
Estou com um problemas na conversão de datas.
Eu consigo converter a data atual que pego do sistema para o formato [Ô]dd/MM/yyyy[Ô], mas não consigo convertê-la de volta para [Ô]MM/dd/yyyy[Ô].
Nesse código, eu converto a data atual para o formato [Ô]dd/MM/yyyy[Ô]:
Tenho uma Masked Text Box na qual o usuário entra com uma data que também preciso converter para [Ô]MM/dd/yyyy[Ô] para então jogar no Banco de Dados. Eis o código que não funciona:
Tem algum outro jeito de fazer essa conversão?
Obrigado.
Estou com um problemas na conversão de datas.
Eu consigo converter a data atual que pego do sistema para o formato [Ô]dd/MM/yyyy[Ô], mas não consigo convertê-la de volta para [Ô]MM/dd/yyyy[Ô].
Nesse código, eu converto a data atual para o formato [Ô]dd/MM/yyyy[Ô]:
DateTime data = DateTime.Today;
lbldtpedido.Text = data.ToString([Ô]dd/MM/yyyy[Ô]);
Tenho uma Masked Text Box na qual o usuário entra com uma data que também preciso converter para [Ô]MM/dd/yyyy[Ô] para então jogar no Banco de Dados. Eis o código que não funciona:
DateTime dtpedido, dtdesejada;
dtpedido = DateTime.Parse(lbldtpedido.Text);
dtdesejada = DateTime.Parse(txtDtDesejada.Text);
pedido.DataPedido = Convert.ToDateTime(dtpedido.ToString([Ô]MM/dd/yyyy[Ô])); //Ocorre o erro: String was not recognized as a valid DateTime.
pedido.DataDesejada = Convert.ToDateTime(dtdesejada.ToString([Ô]MM/dd/yyyy[Ô]));
Tem algum outro jeito de fazer essa conversão?
Obrigado.
Não adianta tentar fazer isso:
Convert.ToDateTime(dtpedido.ToString([Ô]MM/dd/yyyy[Ô]))
O valor da data não será alterado tentando mudar o formato dela. Isso é indiferente pro tipo DateTime. Se no seu TextBox a data estiver no formato [Ô]MM/dd/yyyy[Ô] e você quiser converter o valor de string para DateTime pode usar:
dtpedido = DateTime.ParseExact(lbldtpedido.Text, [Ô]MM/dd/yyyy[Ô], null);
Utilize [Ô]pedido.DataPedido[Ô] como data independente do formato e faça a conversão para string no formato que desejar na hora que jogar o valor para string SQL que vai executar:
pedido.DataPedido = DateTime.Parse(lbldtpedido.Text); // Aqui não importa o formato.
Na hora de gravar:
[Ô]INSERT INTO table_name (dataPedido)
VALUES ([Ô] + pedido.DataPedido.ToString([Ô]MM/dd/yyyy[Ô]) + [Ô])[Ô]
Convert.ToDateTime(dtpedido.ToString([Ô]MM/dd/yyyy[Ô]))
O valor da data não será alterado tentando mudar o formato dela. Isso é indiferente pro tipo DateTime. Se no seu TextBox a data estiver no formato [Ô]MM/dd/yyyy[Ô] e você quiser converter o valor de string para DateTime pode usar:
dtpedido = DateTime.ParseExact(lbldtpedido.Text, [Ô]MM/dd/yyyy[Ô], null);
Utilize [Ô]pedido.DataPedido[Ô] como data independente do formato e faça a conversão para string no formato que desejar na hora que jogar o valor para string SQL que vai executar:
pedido.DataPedido = DateTime.Parse(lbldtpedido.Text); // Aqui não importa o formato.
Na hora de gravar:
[Ô]INSERT INTO table_name (dataPedido)
VALUES ([Ô] + pedido.DataPedido.ToString([Ô]MM/dd/yyyy[Ô]) + [Ô])[Ô]
Não sei se fui claro na resposta anterior, mas resumindo é o seguinte.
dtpedido = DateTime.Parse([Ô]31/12/2009[Ô]);
dtpedido = DateTime.ParseExact([Ô]12/31/2009[Ô], [Ô]MM/dd/yyyy[Ô], null);
Dessas duas formas dtpedido será sempre [Ô]31 de dezembro de 2009[Ô]. O formato não terá nenhuma influência no valor da data. Por isso que você precisa converter de novo para string no formato correto para gravar no BD.
O ideal é você trabalhar com parâmetros para gravar os dados. Isso porque o provedor de dados OleDB, SqlClient ou MySql tratam os dados de forma correta e você não precisa se preocupar com esse tipo de formato. No mysql por exemplo a data é armazenada no formato [Ô]yyyy-MM-dd hh:mm:ss[Ô]. Ao invés de formatar a data e passar para string sql eu utilizo um parâmetro no command e ele grava no formato correto pra mim.
mySqlCommand.CommandText = [Ô]insert into pedidos (dataPedido) values @dataPedido[Ô];
mySqlCommand.Parameters.AddWithValue([Ô]@dataPedido[Ô], dtpedido)
mySqlCommand.ExecuteNonQuery();
dtpedido sendo do tipo DateTime o provedor de dados vai saber como tratar seu valor e formatar a string sql corretamente.
dtpedido = DateTime.Parse([Ô]31/12/2009[Ô]);
dtpedido = DateTime.ParseExact([Ô]12/31/2009[Ô], [Ô]MM/dd/yyyy[Ô], null);
Dessas duas formas dtpedido será sempre [Ô]31 de dezembro de 2009[Ô]. O formato não terá nenhuma influência no valor da data. Por isso que você precisa converter de novo para string no formato correto para gravar no BD.
O ideal é você trabalhar com parâmetros para gravar os dados. Isso porque o provedor de dados OleDB, SqlClient ou MySql tratam os dados de forma correta e você não precisa se preocupar com esse tipo de formato. No mysql por exemplo a data é armazenada no formato [Ô]yyyy-MM-dd hh:mm:ss[Ô]. Ao invés de formatar a data e passar para string sql eu utilizo um parâmetro no command e ele grava no formato correto pra mim.
mySqlCommand.CommandText = [Ô]insert into pedidos (dataPedido) values @dataPedido[Ô];
mySqlCommand.Parameters.AddWithValue([Ô]@dataPedido[Ô], dtpedido)
mySqlCommand.ExecuteNonQuery();
dtpedido sendo do tipo DateTime o provedor de dados vai saber como tratar seu valor e formatar a string sql corretamente.
Obrigado pela resposta, mas agora me deparei com outro erro.
Vou explicar a situação, talvez no primeiro post não tenha explicado direito.
Quando eu pego a data do sistema, jogo ela em um label, por isso formato para [Ô]dd/MM/yyyy[Ô].
Porém, no banco de dados não aceita desse jeito, por isso tento converter para [Ô]MM/dd/yyyy[Ô].
Estou usando uma Stored Procedure para inserir os dados no Banco de Dados (SQL Express 2005), e consequentimente, uso parâmetros para passar os valores para a SP.
Usando o Datetime.ParseExact, obtive a mensagem de erro:
The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.
Eis o Código:
Já usando somente o Datetime.Parse, o erro acontece na camada de Dados, na hora em que a Stored Procedure vai adicionar as datas.
Erro: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
E o código:
Lembrando que as datas no Label e na TextBox estão no formato [Ô]dd/MM/yyyy[Ô].
Já tentei fazer a conversão na própria SP também, mas não consigo. Exibe uma mensagem de erro falando que a conversão de Datetime para Nvchar gerou uma data(ou algo assim) [Ô]out of range[Ô].
Obrigado
Vou explicar a situação, talvez no primeiro post não tenha explicado direito.
Quando eu pego a data do sistema, jogo ela em um label, por isso formato para [Ô]dd/MM/yyyy[Ô].
Porém, no banco de dados não aceita desse jeito, por isso tento converter para [Ô]MM/dd/yyyy[Ô].
Estou usando uma Stored Procedure para inserir os dados no Banco de Dados (SQL Express 2005), e consequentimente, uso parâmetros para passar os valores para a SP.
Usando o Datetime.ParseExact, obtive a mensagem de erro:
The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.
Eis o Código:
pedido.DataPedido = DateTime.ParseExact(lbldtpedido.Text, [Ô]MM/dd/yyyy[Ô], null);
pedido.DataDesejada = DateTime.ParseExact(txtDtDesejada.Text, [Ô]MM/dd/yyyy[Ô], null);
Já usando somente o Datetime.Parse, o erro acontece na camada de Dados, na hora em que a Stored Procedure vai adicionar as datas.
Erro: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
E o código:
pedido.DataPedido = DateTime.Parse(lbldtpedido.Text);
pedido.DataDesejada = DateTime.Parse(txtDtDesejada.Text);
Lembrando que as datas no Label e na TextBox estão no formato [Ô]dd/MM/yyyy[Ô].
Já tentei fazer a conversão na própria SP também, mas não consigo. Exibe uma mensagem de erro falando que a conversão de Datetime para Nvchar gerou uma data(ou algo assim) [Ô]out of range[Ô].
Obrigado
Mas como você guarda as datas no BD? Como string? O ideal é você trabalhar com os tipos corretos tanto na aplicação como no BD.
Esse erro acontece porque no TextBox a data está no formato [Ô]dd/MM/yyyy[Ô] e você tenta converter como se estivesse em [Ô]MM/dd/yyyy[Ô]. Era pra usar ParseExact se no TextBox estivesse como [Ô]MM/dd/yyyy[Ô].
dtpedido = DateTime.Parse([Ô]31/12/2009[Ô]); // converte de string para DateTime no formato da CultureInfo sob a qual a thread está rodando
dtpedido = DateTime.ParseExact([Ô]12/31/2009[Ô], [Ô]MM/dd/yyyy[Ô], null); // converte de string para DateTime no formato especificado.
Se tentar executar como está no seu TextBox, vai dar erro, porque a data é inválida (dia 12 do mês 31). A data e o formato não batem.
DateTime.ParseExact([Ô]31/12/2009[Ô], [Ô]MM/dd/yyyy[Ô], null)
Faz como te falei. Usa o Parse de TextBox para converter para DateTime e depois quando for jogar pra consulta utilize ToString pro formato que seu BD aceita.
pedido.DataPedido = DateTime.Parse(lbldtpedido.Text);
pedido.DataDesejada = DateTime.Parse(txtDtDesejada.Text);
command.CommandText = [Ô]spPedidos[Ô];
//Se o parâmetro for do tipo varchar passe como string formatando como BD pede
command.Parameters.AddWithValue([Ô]@dataPedido[Ô], pedido.DataPedido.ToString([Ô]MM/dd/yyyy[Ô]))
command.Parameters.AddWithValue([Ô]@dataDesejada[Ô], pedido.DataDesejada.ToString([Ô]MM/dd/yyyy[Ô]))
// Se o parâmetro for do tipo SqlDateTime passe a data sem formatar que o provedor de dados faz isso
command.Parameters.AddWithValue([Ô]@dataPedido[Ô], pedido.DataPedido)
command.Parameters.AddWithValue([Ô]@dataDesejada[Ô], pedido.DataDesejada)
command.ExecuteNonQuery();
Precisa ver qual driver você usa. é o namespace SqlClient? E dentro da procedure como está manipulando isso?
Esse erro acontece porque no TextBox a data está no formato [Ô]dd/MM/yyyy[Ô] e você tenta converter como se estivesse em [Ô]MM/dd/yyyy[Ô]. Era pra usar ParseExact se no TextBox estivesse como [Ô]MM/dd/yyyy[Ô].
dtpedido = DateTime.Parse([Ô]31/12/2009[Ô]); // converte de string para DateTime no formato da CultureInfo sob a qual a thread está rodando
dtpedido = DateTime.ParseExact([Ô]12/31/2009[Ô], [Ô]MM/dd/yyyy[Ô], null); // converte de string para DateTime no formato especificado.
Se tentar executar como está no seu TextBox, vai dar erro, porque a data é inválida (dia 12 do mês 31). A data e o formato não batem.
DateTime.ParseExact([Ô]31/12/2009[Ô], [Ô]MM/dd/yyyy[Ô], null)
Faz como te falei. Usa o Parse de TextBox para converter para DateTime e depois quando for jogar pra consulta utilize ToString pro formato que seu BD aceita.
pedido.DataPedido = DateTime.Parse(lbldtpedido.Text);
pedido.DataDesejada = DateTime.Parse(txtDtDesejada.Text);
command.CommandText = [Ô]spPedidos[Ô];
//Se o parâmetro for do tipo varchar passe como string formatando como BD pede
command.Parameters.AddWithValue([Ô]@dataPedido[Ô], pedido.DataPedido.ToString([Ô]MM/dd/yyyy[Ô]))
command.Parameters.AddWithValue([Ô]@dataDesejada[Ô], pedido.DataDesejada.ToString([Ô]MM/dd/yyyy[Ô]))
// Se o parâmetro for do tipo SqlDateTime passe a data sem formatar que o provedor de dados faz isso
command.Parameters.AddWithValue([Ô]@dataPedido[Ô], pedido.DataPedido)
command.Parameters.AddWithValue([Ô]@dataDesejada[Ô], pedido.DataDesejada)
command.ExecuteNonQuery();
Precisa ver qual driver você usa. é o namespace SqlClient? E dentro da procedure como está manipulando isso?
As datas são no Formato Datetime, tanto na camada de dados quanto no Banco de Dados.
Uso o Namespace System.Data.SqlClient;
Vou colocar a SP aqui, para mostrar como manipulo a data:
Como já disse, eu tentei usar o Convert, mas não deu certo.
Estava usando o convert assim:
Mas como já disse, estava dando um erro relacionado a [Ô]out of range[Ô].
Obrigado
Uso o Namespace System.Data.SqlClient;
Vou colocar a SP aqui, para mostrar como manipulo a data:
CREATE PROCEDURE INSERE_PEDIDO
-- Add the parameters for the stored procedure here
@CDPEDIDO INT,
@CDFUNCIONARIO INT,
@DTPEDIDO DATETIME,
@DESCPEDIDO VARCHAR(500),
@CDITEM INT,
@QTDITEM INT,
@VLTOTAL MONEY,
@DTDESEJADA DATETIME,
@PRIORIDADE INT,
@CDSTATUS INT,
@DTVERBA DATETIME,
@OBSERVACAO VARCHAR(500),
@DTENTREGA DATETIME
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT @CDPEDIDO = MAX(CDPEDIDO) FROM [Banco de Dados].[dbo].[Pedido]
IF @CDPEDIDO IS NULL
BEGIN
SET @CDPEDIDO = 0
END
INSERT INTO [Banco de Dados].[dbo].[Pedido]
([CdPedido]
,[CdFuncionario]
,[DtPedido]
,[DescPedido]
,[CdItem]
,[QtdItem]
,[VlTotal]
,[DtDesejada]
,[Prioridade]
,[CdStatus]
,[DtVerba]
,[Observacao]
,[DtEntrega])
VALUES
(@CDPEDIDO+1,
@CDFUNCIONARIO,
@DTPEDIDO,
@DESCPEDIDO,
@CDITEM ,
@QTDITEM ,
@VLTOTAL ,
@DTDESEJADA ,
@PRIORIDADE ,
@CDSTATUS ,
@DTVERBA ,
@OBSERVACAO,
@DTENTREGA)
END
GO
Como já disse, eu tentei usar o Convert, mas não deu certo.
Estava usando o convert assim:
SET @DTPEDIDO = CONVERT(DATETIME,@DTPEDIDO,102)
SET @DTDESEJADA = CONVERT(DATETIME,@DTDESEJADA,102)
IF @DTVERBA IS NOT NULL
BEGIN
SET @DTVERBA = CONVERT(DATETIME,@DTVERBA,102)
END
IF @DTENTREGA IS NOT NULL
BEGIN
SET @DTENTREGA = CONVERT(DATETIME,@DTENTREGA,102)
END
Mas como já disse, estava dando um erro relacionado a [Ô]out of range[Ô].
Obrigado
Vou postar o código também da minha camada de Dados:
public bool Incluir(PedidoModel pedido)
{
SqlConnection conexao = new SqlConnection(clDados.StringDeConexao);
try
{
SqlCommand comando = new SqlCommand([Ô]INSERE_PEDIDO[Ô], conexao);
comando.CommandType = CommandType.StoredProcedure;
comando.Parameters.AddWithValue([Ô]@CDPEDIDO[Ô],pedido.Codigo);
comando.Parameters.AddWithValue([Ô]@CDFUNCIONARIO[Ô], pedido.CodigoFuncionario);
comando.Parameters.AddWithValue([Ô]@DTPEDIDO[Ô], pedido.DataPedido);
comando.Parameters.AddWithValue([Ô]@DESCPEDIDO[Ô], pedido.DescricaoPedido);
comando.Parameters.AddWithValue([Ô]@CDITEM[Ô], pedido.CodigoItem);
comando.Parameters.AddWithValue([Ô]@QTDITEM[Ô], pedido.Quantidade);
comando.Parameters.AddWithValue([Ô]@VLTOTAL[Ô], pedido.Total);
comando.Parameters.AddWithValue([Ô]@DTDESEJADA[Ô], pedido.DataDesejada);
comando.Parameters.AddWithValue([Ô]@PRIORIDADE[Ô], pedido.Prioridade);
comando.Parameters.AddWithValue([Ô]@CDSTATUS[Ô], pedido.CodigoStatus);
comando.Parameters.AddWithValue([Ô]@DTVERBA[Ô], pedido.DataVerba);
comando.Parameters.AddWithValue([Ô]@OBSERVACAO[Ô], pedido.Observacao);
comando.Parameters.AddWithValue([Ô]@DTENTREGA[Ô], pedido.DataEntrega);
conexao.Open();
comando.ExecuteNonQuery();
return true;
}
catch (SqlException ex)
{
throw new Exception([Ô]Servidor SQL Erro: [Ô] + ex.Number + [Ô] Descrição: [Ô] + ex.Message);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
Ok, deixa assim sem esse trecho:
Estou sem o Sql Server instalado aqui pra poder testar, mas acho que o problema é com algum parâmetro do tipo DateTime que você está passando sem configurar o valor. O sistema vai assumir como DateTime.MinValue e esse valor está fora do range que Sql Server aceita.
Quais os valores das variáveis abaixo você está tentando gravar quando dá o erro?
pedido.DataPedido
pedido.DataDesejada
pedido.DataVerba
pedido.DataEntrega
SET @DTPEDIDO = CONVERT(DATETIME,@DTPEDIDO,102)
SET @DTDESEJADA = CONVERT(DATETIME,@DTDESEJADA,102)
IF @DTVERBA IS NOT NULL
BEGIN
SET @DTVERBA = CONVERT(DATETIME,@DTVERBA,102)
END
IF @DTENTREGA IS NOT NULL
BEGIN
SET @DTENTREGA = CONVERT(DATETIME,@DTENTREGA,102)
END
Estou sem o Sql Server instalado aqui pra poder testar, mas acho que o problema é com algum parâmetro do tipo DateTime que você está passando sem configurar o valor. O sistema vai assumir como DateTime.MinValue e esse valor está fora do range que Sql Server aceita.
Quais os valores das variáveis abaixo você está tentando gravar quando dá o erro?
pedido.DataPedido
pedido.DataDesejada
pedido.DataVerba
pedido.DataEntrega
Se for esse o problema, verifique antes de gravar cada variável tipo Date.
DateTime.MinValue = 01/01/0001 00:00:00
SqlDateTime.MinValue = 01/01/1753 00:00:00
Isso vai acertar o range.
DateTime.MinValue = 01/01/0001 00:00:00
SqlDateTime.MinValue = 01/01/1753 00:00:00
using System.Data.SqlTypes;
if (pedido.DataPedido.Equals(DateTime.MinValue))
pedido.DataPedido = SqlDateTime.MinValue.Value;
comando.Parameters.AddWithValue([Ô]@DTPEDIDO[Ô], pedido.DataPedido)
Isso vai acertar o range.
Todas as datas no formato [Ô]dd/MM/yyyy[Ô]:
pedido.DataPedido - Data Atual
pedido.DataDesejada - usuário digita a data (ela passa por uma validação antes de ir para o banco)
pedido.DataVerba - Nessa parte, passo null
pedido.DataEntrega - Nessa parte passo null.
O valor null não altera nada, pois quando eu executo a SP no banco e digito as datas no formato [Ô]MM/dd/YYYY[Ô], ele cadastra os dados normalmente.
Vou tentar fazer o que você disse.
Obrigado
pedido.DataPedido - Data Atual
pedido.DataDesejada - usuário digita a data (ela passa por uma validação antes de ir para o banco)
pedido.DataVerba - Nessa parte, passo null
pedido.DataEntrega - Nessa parte passo null.
O valor null não altera nada, pois quando eu executo a SP no banco e digito as datas no formato [Ô]MM/dd/YYYY[Ô], ele cadastra os dados normalmente.
Vou tentar fazer o que você disse.
Obrigado
Citação:GABRIEL301 escreveu:
Todas as datas no formato [Ô]dd/MM/yyyy[Ô]:
pedido.DataPedido - Data Atual
pedido.DataDesejada - usuário digita a data (ela passa por uma validação antes de ir para o banco)
pedido.DataVerba - Nessa parte, passo null
pedido.DataEntrega - Nessa parte passo null.
O valor null não altera nada, pois quando eu executo a SP no banco e digito as datas no formato [Ô]MM/dd/YYYY[Ô], ele cadastra os dados normalmente.
Vou tentar fazer o que você disse.
Obrigado
Como null? Se você executa:
comando.Parameters.AddWithValue([Ô]@DTENTREGA[Ô], pedido.DataEntrega);
E não tiver definido em algum momento o valor como algo assim:
pedido.DataEntrega = DateTime.Now;
Essa propriedade vai ter o valor como DateTime.MinValue (01/01/0001 00:00:00) que está fora do range que o bd vai aceitar (01/01/1753 00:00:00).
Tópico encerrado , respostas não são mais permitidas