2010-11-08 18 views
0

Je suis en train de calculer le "timeago" et je suis en train d'arriver à une décrépitude dans mon code.Discrepence de calcul de date (JavaScript VS .NET)

En utilisant la date d'aujourd'hui

7 Novembre, 2010

Si je 1 Septembre, 2010 alors à la fois mon code .NET et mon code JS dire "2 mois"

Si j'utilise le 31 août 2010 alors mon code .NET dit "3 mois" et mon code JS dit "2 mois"

Cet écart persiste jusqu'à le 9 août 2010.

Fondamentalement, le DATEDIFF est "off" du 10 Août - 31 Août basé sur la date d'aujourd'hui du 7 Novembre

Voici le JavaScript (extrait de plugin "timeago")

var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || 
    seconds < 90 && substitute($l.minute, 1) || 
    minutes < 45 && substitute($l.minutes, Math.round(minutes)) || 
    minutes < 90 && substitute($l.hour, 1) || 
    hours < 24 && substitute($l.hours, Math.round(hours)) || 
    hours < 48 && substitute($l.day, 1) || 
    days < 30 && substitute($l.days, Math.floor(days)) || 
    days < 60 && substitute($l.month, 1) || 
    days < 365 && substitute($l.months, Math.floor(days/30)) || 
    years < 2 && substitute($l.year, 1) || 
    substitute($l.years, Math.floor(years)); 

Et voici mon code .NET (écrit par moi)

Public Function ToDuration(ByVal dt As Date?, _ 
           Optional ByVal suffixAgo As String = Nothing) As String 

     If Not dt Is Nothing Then 
      Dim theDate As Date = dt 
      Dim SecondsAppart As Integer = DateDiff(DateInterval.Second, theDate, Now) 
      Dim output As String 
      If SecondsAppart < 86400 Then 
       Select Case SecondsAppart 
        Case Is <= 59 : output = "less than a minute " & suffixAgo 
        Case Is <= 119 : output = "about a minute " & suffixAgo 
        Case Is <= 3599 : output = DateDiff(DateInterval.Minute, theDate, Now) & " minutes " & suffixAgo 
        Case Is <= 7199 : output = "about an hour " & suffixAgo 
        Case Else : output = DateDiff(DateInterval.Hour, theDate, Now) & " hours " & suffixAgo 
       End Select 

      Else 
       Dim DaysAppart As Integer = DateDiff(DateInterval.Day, theDate, Now) 
       Select Case DaysAppart 
        Case Is <= 1 : output = "yesterday" 
        Case Is <= 30 : output = DateDiff(DateInterval.Day, theDate, Now) & " days " & suffixAgo 
        Case Is <= 60 : output = "about a month " & suffixAgo 
        Case Is <= 365 : output = DateDiff(DateInterval.Month, theDate, Now) & " months " & suffixAgo 
        Case Is <= 730 : output = "about a year " & suffixAgo 
        Case Else : output = DateDiff(DateInterval.Year, theDate, Now) & " years " & suffixAgo 
       End Select 
      End If 

      Return output 
     Else 
      Return String.Empty 
     End If 
    End Function 

le problème que je vais avoir est fondamentale, ainsi que une logistique.

  1. Quel code est "correct" quand il s'agit de DateDiff? (IE: Est-ce que 2 mois et 14 jours sont considérés comme 2 mois ou 3?)
  2. Quelle est la meilleure façon de les aligner en conséquence?
+0

Une chose que je ferais est de substituer <= avec <. La façon dont vous codez fonctionne maintenant, vous dites que deux mois se sont écoulés depuis environ un mois. Même que 730 jours est d'environ un an. –

+0

Je me demande si c'est une coïncidence que vous ayez choisi la date dans laquelle le fuseau horaire de la plupart des États-Unis passe de la lumière du jour à l'heure normale. – kennebec

+0

haha, n'a pas même chose à propos de DST. Je ne sais pas si cela s'applique ici ou non. –

Répondre

1

Apporté quelques hypothèses et a dû l'écrire en C#, mais cette version du code me donne 2 mois du 31 Août et 3 mois pour le 9 Août

 public static string ToDuration(DateTime dt, string suffixAgo) 
     { 
      string output; 
      DateTime theDate; 
      if (dt == null) 
      { 
       output = "now"; 
      } 
      else 
      { 
       theDate = dt; 
       TimeSpan DateInterval = DateTime.Now - theDate; 
       int SecondsAppart = Convert.ToInt32(Math.Floor(DateInterval.TotalSeconds)); 
       if ((SecondsAppart < 86400)) 
       { 

        if (SecondsAppart < 59) 
         output = ("less than a minute " + suffixAgo); 
        else if (SecondsAppart < 119) 
         output = ("about a minute " + suffixAgo); 
        else if (SecondsAppart < 3599) 
         output = string.Format("{0} minutes {1}", Math.Floor(DateInterval.TotalMinutes), suffixAgo); 
        else if (SecondsAppart < 7199) 
         output = "about an hour " + suffixAgo; 
        else 
         output = string.Format("{0} hours {1}", Math.Floor(DateInterval.TotalHours), suffixAgo); 
       } 
       else 
       { 
        int DaysAppart = Convert.ToInt32(DateInterval.TotalDays); 
        if (DaysAppart <= 1) 
         output = "yesterday"; 
        else if (DaysAppart < 30) 
         output = string.Format("{0} days {1}", Math.Floor(DateInterval.TotalDays), suffixAgo); 
        else if (DaysAppart < 60) 
         output = "about a month " + suffixAgo; 
        else if (DaysAppart < 365) 
         output = string.Format("{0} months {1}", Math.Floor(DateInterval.TotalDays/30), suffixAgo); 
        else if (DaysAppart < 730) 
         output = ("about a year " + suffixAgo); 
        else 
         output = string.Format("{0} year {1}", Math.Floor(DateInterval.TotalDays/365), suffixAgo); 
       } 
      } 
      return output; 
     } 

J'ai mis à jour le code et Je pense que vous avez les résultats que vous attendez maintenant. Espérons que cela aidera.

Cheers, Wagner.

+0

Je pense que c'est plus proche, mais si j'entre le 15 août, j'obtiens 2 mois en JS et 3 mois en .NET. –

+0

PS: Je pense que j'aime la corde. Formate beaucoup mieux ... je ne sais pas pourquoi je n'ai pas pensé à ça. –

+0

Je pense que je l'ai eu ... Dans les instructions if, si vous remplacez Convert.ToInt32 par Math.Floor, vous devriez obtenir les résultats que vous attendez. Ce qui est logique, car c'est exactement ce que fait le code js. Je suis en train de mettre à jour le code pour le refléter. –