2012-08-17 24 views

Respuesta

6

Este código debería funcionar:

 string input = "10 days ago"; 

     DateTime result = DateTime.MinValue; 
     int minutesMultiplier = 0; 

     if (input.Contains("minute")) 
      minutesMultiplier = 1; 
     else 
      if (input.Contains("hour")) 
       minutesMultiplier = 60; 
      else 
       if (input.Contains("day")) 
        minutesMultiplier = 1440; 
       else 
        throw new Exception("Couldn't parse time format"); 

     string numberStr = input.Split(' ')[0]; 
     int number; 
     if (int.TryParse(numberStr, out number)) 
      result = DateTime.Now.AddMinutes(-number * minutesMultiplier); 

Se hace el análisis sintáctico de un nombre de intervalo (por ejemplo, minutos, horas, días) y se multiplica ellos para obtener el número de minutos porque más adelante se utiliza DateTime.Now.AddMinutes método, Lo mismo podría hacerse usando TimeSpan y llamando al DateTime.Now.Add.

Aquí es un ejemplo más de que maneja el caso de una cadena que contiene más de un nombre de intervalo, como por ejemplo "hace 10 horas y 15 minutos":

 // If there are mixed interval types in an input string 
     string input = "10 days and 10 hours ago"; 

     // Parse out the intervals and numbers 
     var matches = Regex.Matches(input, 
         @"(?<number>\d+)\s(?<interval>(day)|(minute)|(hour))"); 

     // Convert them to dictionary 
     var dic = matches 
      .Cast<Match>() 
      .ToDictionary(
       key => key.Groups["interval"].Value, 
       o => int.Parse(o.Groups["number"].Value)); 

     // Calculate the total number of minutes for each interval 
     DateTime result = DateTime.MinValue; 
     int totalMinutes = 0; 

     foreach (var keyValue in dic) 
     { 
      if (keyValue.Key.Contains("minute")) 
       totalMinutes += keyValue.Value; 
      else 
       if (keyValue.Key.Contains("hour")) 
        totalMinutes += keyValue.Value * 60; 
       else 
        if (keyValue.Key.Contains("day")) 
         totalMinutes += keyValue.Value * 1440; 
        else 
         throw new Exception("Unparsable time format"); 
     } 

     result = DateTime.Now.AddMinutes(-totalMinutes); 
+1

Tenga en cuenta que este código se basa en cadenas de entrada formateadas correctamente. –

+1

Sí, la presunción es que las entradas son predecibles y posiblemente generadas automáticamente. –

+1

'string input =" hace 10 horas y 30 minutos ";' - ¿qué hace tu código? Entiendo que no puede prever todas las entradas posibles, pero cuando la entrada no está en el formato que espera, debe lanzar una excepción, no silenciosamente hacer lo incorrecto. – hvd

2

La forma correcta sería almacenar su valor relativo como un valor TimeSpan y restarlo de DateTime.Now (o de cualquier DateTime que desee usar como base).

Puede usar métodos como int.Parse para convertir los números (el número de minutos, horas, etc.) en valores enteros y copiarlos en su valor TimeSpan. El algoritmo de análisis exacto depende del formato real de sus cadenas, es decir, qué palabras están permitidas allí y en qué orden pueden aparecer los números.

Si las cadenas ya están aislados como se muestra en su pregunta, se puede tratar de desmontar utilizando una expresión regular (con la Regex class):

^(\d+)\s+([a-z]+)\s+ago$ 
6

Usted tendrá que escribir sus propias rutinas para hacerlo , al igual que las personas que hacen lo opuesto tenían que hacer.

Básicamente, deberá analizar el texto para encontrar el intervalo (es decir, minutos, horas, días, etc. ...), el importe y si está en el pasado o en el futuro (usando ago o from).

En este punto, tendrá suficientes datos para construir una instancia de TimeSpan adecuada y utilizarla con DateTime.Now para obtener ese tiempo.

Para que todo lo anterior funcione, deberá asegurarse de que los valores de cadena para analizar están estandarizados.

Cuestiones relacionadas