4

Tengo una aplicación que realiza llamadas a través de una API, la cual responde un JSON con la información correspondiente.

En mi aplicación creo un objeto Datatable y creo tantas columnas como me devuelve el JSON.

var retorno = await EnviarGET<string>("Sinc...", "Get...", peticion, "GET");
DataTable tUsuarios = new DataTable();
JObject def = (JObject)JSON.ToObject(retorno);
JArray data = (JArray)JSON.ToObject(def["Datos"].ToString());

var oRetornoFichador = new JObject();
foreach (JObject item in data)
{
    DataColumn column;

    column = new DataColumn();
    column.DataType = System.Type.GetType("System.Int32");
    column.ColumnName = "Index";
    tUsuarios.Columns.Add(column);

    column = new DataColumn();
    column.DataType = System.Type.GetType("System.DateTime");
    column.ColumnName = "FechaDesde";
    tUsuarios.Columns.Add(column);

    column = new DataColumn();
    column.DataType = System.Type.GetType("System.DateTime");
    column.ColumnName = "FechaHasta";
    tUsuarios.Columns.Add(column);
    .
    .
    .

Como se ve, hay columnas de varios tipos, entre ellos DateTime. Después de esto, creo una fila con la estructura de columnas de la tabla y la relleno con los datos del JSON:

foreach (JJSon.JObject item2 in data2)
{
    DataRow drow = tUsuarios.NewRow();

    Logger.Write(item2.ToString());

    if (item2["FechaDesde"].ToString() == "")
    {
        drow["FechaDesde"] = DateTime.Now;
    }
    else
    {
        Logger.Write(CultureInfo.CurrentCulture.ToString());
        drow["FechaDesde"] = DateTime.Parse(item2["FechaDesde"].ToString(), provider);
    }
    .
    .
    .

Mi problema está en esta línea (o similares que tengo más abajo):

drow["FechaDesde"] = DateTime.Parse(item2["FechaDesde"].ToString(), provider);

Cuando lo ejecuto en mi pc me funciona sin problema pero si lo ejecuto en otro pc me da un error:

No se puede reconocer la cadena como valor DateTime válido.

Creo que el error no es por el tipo de columna a la hora de hacer la asignación porque si intento imprimir ese mismo valor, sin meterlo a la tabla haciendo lo siguiente me da el mismo error:

CultureInfo provider = CultureInfo.CreateSpecificCulture("es-ES");
Logger.Write(DateTime.Parse(item2["FechaDesde"].ToString()).ToString());

He pensado que cambiando la Cultura me valdría pero en ambos equipos es "es-ES", esto lo veo con el logger.

Otra opción que he probado es a utilizar el método ParseExact de la clase DateTime indicando un formato y la cultura y me da el mismo error.

El json que contiene la fecha que me da problema es el siguiente:

{"Datos":
    [
        {
        .
        .
        .
        "FechaDesde":"27/11/2023 0:00:00",
        "FechaHasta":"01/01/2026 0:00:00",
        .
        .
        .
        }
    ]
}

Creo que el error no está en la Cultura utilizada porque la siguiente línea me la ejecuta sin problema en ambos pcs:

peticionGTPU.Add("diaFB", DateTime.Parse(f_blindaje).Day); //Valor de f_blindaje: "07/12/2023 17:07:45", es un string obtenido de un json
7
  • tienes que validar que lo datos que estas usando cumplen con los formatos... y esto es una practica que te ayudara en el futuro, en mi respuesta trato de abordar esa cultura. si bien tu formato de hora le falta un 0 no cumple con el formato HH que es el que esperas. Commented el 10 ene. a las 19:37
  • hay una solucion mucho mas simple. te importa la hora?
    – gbianchi
    Commented el 10 ene. a las 19:41
  • ¿La API es sensible a localización?
    – Sal
    Commented el 10 ene. a las 20:09
  • @FranciscoNuñezIALover sospecho que es por eso, el resto de cosas ya no me cuadran, voy a mirar por ahí, gracias. Commented el 11 ene. a las 8:29
  • @gbianchi si, necesito la hora también, sospecho que me tendré que asegurar que la hora tenga 2 dígitos. Commented el 11 ene. a las 8:30

3 respuestas 3

3

Puedes implementar CultureInfo como lo indican las otras dos respuesta, otra alternativa seria la siguiente:

using System.Globalization;

string fechaDesdeString = item2["FechaDesde"].ToString();
string formatoFecha = "dd/MM/yyyy HH:mm:ss";

if (string.IsNullOrEmpty(fechaDesdeString))
{
    drow["FechaDesde"] = DateTime.Now;
}
else
{
    DateTime fechaDesde;
    if (DateTime.TryParseExact(fechaDesdeString, formatoFecha, CultureInfo.InvariantCulture, DateTimeStyles.None, out fechaDesde))
    {
        drow["FechaDesde"] = fechaDesde;
    }
    else
    {
        // Manejar el caso en el que la cadena no pueda ser parseada como fecha
        Logger.Write("Error al parsear la fecha: " + fechaDesdeString);
    }
}

Nota: el enfoque debería ser más robusto y evitar problemas de interpretación de fechas al cambiar entre diferentes máquinas. Además, al utilizar DateTime.TryParseExact, puedes manejar posibles errores de parseo de manera más controlada.

No he tenido chance de probar el codigo en mi IDE, sujiero que lo tomes AS-IS.

Update:

Ahora algunos compañero hemos notado que el formato "27/11/2023 0:00:00" no lo podras evitar, para eso podemos extender un poco mas el manejo de formatos de fecha.

string fechaDesdeString = item2["FechaDesde"].ToString();
string[] formatosFechaHora = { "dd/MM/yyyy H:mm:ss", "dd/MM/yyyy HH:mm:ss" };

if (string.IsNullOrEmpty(fechaDesdeString))
{
    drow["FechaDesde"] = DateTime.Now;
}
else
{
    DateTime fechaDesde;
    if (DateTime.TryParseExact(fechaDesdeString, formatosFechaHora, CultureInfo.InvariantCulture, DateTimeStyles.None, out fechaDesde))
    {
        drow["FechaDesde"] = fechaDesde;
    }
    else
    {
        // Manejar el caso en el que la cadena no pueda ser parseada como fecha
        Logger.Write("Error al parsear la fecha: " + fechaDesdeString);
    }
}

Me acorde que algunos metodos de C# que trabajan con tipos char tambien aceptan arreglos de cadenas por eso es posible pasar el arreglo de formatos.

4
  • 2
    le hago upvote a este comentario porque por experiencia personal cuando tienes una fecha que tu no puedes manejar el formato en el que te llega lo mejor es verla con tus propios ojos y usar el formato que visualizas para hacer la conversion de texto a fecha con ese formato, esto te ahorra problemas
    – LPZadkiel
    Commented el 10 ene. a las 20:02
  • @LPZadkiel de acuerdo contigo
    – Japv
    Commented el 10 ene. a las 22:41
  • Gracias por el comentario @Francisco Nuñez IA Lover. He probado tu respuesta y no me funciona, me entra todo el rato al segundo else, no me convierte la fecha... Commented el 11 ene. a las 8:51
  • si entra al else no estas recibiendo ninguna de los formatos que indicas o no estas usando el último código. Commented el 11 ene. a las 12:12
2

El primer problema es que una fecha debería transmitirse siempre en formato ISO ej: 2024-01-10T17:12:17.575Z

Para convertir, según el formato que describes debes hacer:

var ci = new CultureInfo("es-ES");
var fecha = Convert.ToDateTime("27/11/2023 0:00:00", ci);
1

Puedes usar el tipo de cultura invariante, el cual es culture-insensitive, se asocia con el idioma inglés pero no con ningún país/región.

drow["FechaDesde"] = DateTime.ParseExact(item2["FechaDesde"], "dd/MM/yyyy HH:mm:ss", CultureInfo.InvarianCulture).ToString("dd/MM/yyyy HH:mm:ss");

Se usa el método ParseExact el cual debe tener el mismo formato de la fecha que recibe como parámetro, caso contrario dará error.

Para poder usar la clase CultureInfo debes poner en los usings:

using System.Globalization;

Nota: Te recomiendo la respuesta de Francisco que est�� más completa.

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.