He creado un punto final de API. La persona que llama puede llamar a la API con el método que pasa los parámetros relevantes. En los parámetros hay un parámetro que es de formato.POST
datetime
El problema es que al llamar a esta API la persona que llama puede pasar en 3 formatos diferentes:datetime
long int
– por ejemplo, 1374755180- Formato de EE.UU. – por ejemplo, «7/25/2013 6:37:31 PM» (como
string
) - Formato de marca de tiempo- por ejemplo, «2013-07-25 14:26:00» (como
string
)
Tengo que analizar el valor y convertirlo a un o en formato de marca de tiempo.datetime
DateTime
string
He intentado usar , , y pero ninguno de ellos está funcionando con certeza para mí.DateTime.TryParse()
DateTime.Parse()
Convert.ToDateTime()
Convert.ToDouble()
La salida requerida tiene que estar en formato.en-GB
Editar:
Había pensado en tener un bloque para usar con 3 veces con una para decir que la cuerda no se podía analizar. ¿Es esta la mejor solución? ¿O hay soluciones mejores que esta?if-else if-else
TryParse
else
¡Por favor, ayuda!
Solución
Debe considerar la posibilidad de requerir una zona horaria. 1 no lo necesita, pero #2 y #3 sí.
public DateTime ParseRequestDate()
{
// https://stackoverflow.com/questions/2883576/how-do-you-convert-epoch-time-in-c
CultureInfo enUS = new CultureInfo("en-US");
var dt = "1374755180";
//var dt = "7/25/2013 6:37:31 PM";
//var dt = "2013-07-25 14:26:00";
DateTime dateValue;
long dtLong;
// Scenario #1
if (long.TryParse(dt, out dtLong))
return dtLong.FromUnixTime();
// Scenario #2
if (DateTime.TryParseExact(dt, "MM/dd/yyyy hh:mm:ss tt", enUS, DateTimeStyles.None, out dateValue))
return dateValue;
// Scenario #3
if (DateTime.TryParseExact(dt, "yyyy-MM-dd hh:mm:ss", enUS, DateTimeStyles.None, out dateValue))
return dateValue;
throw new SomeException("Don't know how to parse...");
}
EDITAR Como señala Matt Johnson, DateTime.TryParseExact acepta una matriz de cadenas de formato. 2 y 3 podrían condensarse.
public DateTime ParseRequestDate()
{
// https://stackoverflow.com/questions/2883576/how-do-you-convert-epoch-time-in-c
CultureInfo enUS = new CultureInfo("en-US");
var dt = "1374755180";
//var dt = "7/25/2013 6:37:31 PM";
//var dt = "2013-07-25 14:26:00";
DateTime dateValue;
long dtLong;
// Scenario #1
if (long.TryParse(dt, out dtLong))
return dtLong.FromUnixTime();
// Scenario #2 & #3
var formatStrings = new string[] { "MM/dd/yyyy hh:mm:ss tt", "yyyy-MM-dd hh:mm:ss" };
if (DateTime.TryParseExact(dt, formatStrings, enUS, DateTimeStyles.None, out dateValue))
return dateValue;
throw new SomeException("Don't know how to parse...");
}
La conversión de época la tomé prestada de otra pregunta. (Un método de extensión)
public static class MyExtensions
{
public static DateTime FromUnixTime(this long unixTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
}
Otras respuestas
Una forma de lidiar con este problema sería configurar un método de fábrica que «entienda» diferentes formatos y los analice en consecuencia.
Puede crear una cadena de –s para lidiar con este problema, pero también puede hacer una implementación «impulsada por tablas»: lo que necesita es una matriz de delegados que tomen una cadena y le digan dos cosas:if
then
else
- Si este delegado puede analizar o no la cadena entrante, y
- En caso afirmativo, ¿cuál es el resultado de ese análisis, expresado como
DateTime
Here is a sample implementation:
private static readonly DateParsers = new Func<string,Tuple<DateTime,bool>>[] {
(s) => {
long res;
if (long.TryParse(s, out res)) {
// The format was correct - make a DateTime,
// and return true to indicate a successful parse
return Tuple.Create(new DateTime(res), true);
} else {
// It does not matter what you put in the Item1
// when Item2 of the tuple is set to false
return Tuple.Create(DateTime.MinValue, false);
}
}
...
// Add similar delegates for other formats here
};
Now your factory method could be implemented as follows:
private static bool TryParseMultiformat(string s, out DateTime res) {
// Check all parsers in turn, looking for one returning success
foreach (var p in DateParsers) {
var tmp = p(s);
if (tmp.Item2) {
res = tmp.Item1;
return true;
}
}
res = DateTime.MinValue;
return false;
}