PROBLEMA COM DATAS

GABRIEL301 22/09/2009 00:20:18
#323378
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[Ô]:
  
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.
MORDOR 22/09/2009 09:13:26
#323390
Resposta escolhida
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[Ô]) + [Ô])[Ô]
MORDOR 22/09/2009 09:41:26
#323393
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.
GABRIEL301 22/09/2009 11:15:53
#323395
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:

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
MORDOR 22/09/2009 11:38:27
#323400
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?
GABRIEL301 22/09/2009 11:45:38
#323403
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:

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
GABRIEL301 22/09/2009 11:58:54
#323407
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);

}
}
MORDOR 22/09/2009 12:17:38
#323409
Ok, deixa assim sem esse trecho:


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
MORDOR 22/09/2009 12:27:28
#323411
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

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.
GABRIEL301 22/09/2009 12:30:28
#323412
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
MORDOR 22/09/2009 12:33:23
#323413
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).
Página 1 de 2 [14 registro(s)]
Tópico encerrado , respostas não são mais permitidas