Question

Considérez les 2 scénarios suivants: Scénario 1). Aujourd'hui est le 1er mai 2012 et le scénario 2). Aujourd'hui est le 1er Septembre de 2012.

Maintenant, considérons que nous écrivons sur notre page Web qui suit au sujet d'une personne de commentaire a laissé: « Ce commentaire a été écrit il y a 3 mois et 12 jours ». Le nombre de jours dans ces deux scénarios sera toujours différent même si la déclaration est exactement le même. Dans le scénario 1, « 3 mois et 12 jours » équivaudrait à 102 days. Toutefois, dans le scénario 2, "3 mois et 12 jours" seraient 104 days!

Maintenant, au coin de mon point de vue, permet d'utiliser un autre exemple et dire que quelqu'un a laissé un commentaire sur notre site le 30 janvier 2013, et aujourd'hui est le 10 Mars 2013. Notre véritable objet TimeSpan a besoin de connaître cette date relative, et peut comprendre les éléments suivants:

  • Qu'il ya 10 jours en Mars,
  • Qu'il ya 1 jour en janvier (à compter du 30 au 31).
  • Que le mois février est d'un mois, peu importe combien de jours il y a en elle (même si elle est de 28 jours).

Alors, cela signifierait 10 jours + 1 jour + 1 mois au total, à traduire This comment was posted 1 Month and 11 Days ago.

Maintenant, si vous avez utilisé l'objet TimeSpan de style MS (ou tout autre objet TimeSpan dans toutes les langues), il vous donnera le nombre de jours du 30 Jan à 10 Mars (39 jours), et parce que l'objet TimeSpan ne stocker la date relative (la base / date initiale, nous soustrayons pour obtenir le TimeSpan), si vous lui demandez combien de mois et de jours, il a été, il suppose qu'il ya 30 jours en un mois, ou même pire, la moyenne est supérieure de 30 jours, et retourner le reste dans les jours, donc pour se rendre à 39 jours, il vous dira qu'il a été 1 mois et 9 jours et vous obtiendrez le message This comment was posted 1 Month and 9 Days ago. Rappelez-vous, ces deux scénarios ont la même date de début et même date / heure actuelle final, oui l'objet Microsoft TimeSpan, en ne nous permet pas de le dire le mois de février 2013 devrait être considéré, nous a donné un TimeSpan complètement différent, au large par un 2 jours entiers. Il a, en effet, nous a menti.

Le problème est, les gens vont croire, et qui sait ce que la perception qu'ils peuvent avoir, comment leur perception du passé peuvent changer et les décisions et les choix de vie qu'ils peuvent faire en essayant de reconstituer les événements dans le passé à l'intérieur de leur propre esprit , sans jamais apercevoir ou comprendre l'inconvénient et l'échec inhérent à représenter le temps qui est si répandue partout aujourd'hui. Ils ne comprendront pas que les langages de programmation ne se rendent pas compte (ou de soins) que le mois dernier a 31 jours, comme oppposed à 30, 29 ou 28 -. Ou vice versa, et que cela ajoute lorsque vous augmentez la TimeSpan

Ceci est le problème au cœur de ce poste. Je comprends que la plupart des gens ne se soucient pas cette différence (mais assurez-vous que certains d'entre nous, et ne peuvent pas avoir cela sur le dos), et si cela ne vous dérange pas, thats ok. Je voudrais qu'il ne me dérangeait pas, je me serais sauvé un peu de temps, le stress et la déception. Si ce n'est pas la peine, vous pouvez utiliser la fonction pour l'affichage textuel efficace du temps relatif (personnalisable à 1 à 6 nœuds de secondes à plusieurs années), au lieu de l'utiliser pour la précision généralement négligeable qu'elle fournit.

À ma grande déception, j'ai remarqué qu'il n'y a pas de véritable objet timespan, si vous obtenez un timespan, et faire un .years ou .months vous obtiendrez rien, vous aurez seulement .days et inférieure parce qu'un objet timeSpan ne porte pas quoi que ce soit pour lui dire quel mois ou année, le timeSpan a été créé. Par conséquent, il ne saura jamais vraiment combien de mois il a été depuis jours chaque mois varient plus d'un an et encore plus au cours d'une année bissextile.

En réponse à cela, je posterai une fonction que j'ai développé afin d'obtenir des lectures précises et être en mesure de retourner les choses comme ce qui suit sur ma page web ASP.NET ...

  

Posté 4 ans, 3 mois, 14 jours, 15 heures, 18 minutes et 24 secondes il y a

Je me suis dit qu'il y aurait un ...

timeSpan.GetActualNumberOf[Months/Days/Hours/etc] (date de base doit être fournie bien sûr)

... méthode de type sur ce type de données, mais il n'y avait pas.

Tout ce que vous voulez vraiment avez à faire est de créer une autre propriété sur l'objet timeSpan pour lui donner une date de base sur laquelle la différence a été calculée, la chaîne belle-dessus serait calculable assez facilement, et un .year et .month existerait

MISE À JOUR:. Je considérablement élargi et mis à jour mes détails d'utilisation réponse officielle et de code dans ma réponse ci-dessous, 100% de travail réponse et code (en totalité), temps précis et exacts relatifs / dates, pas des approximations - merci

Était-ce utile?

La solution 3

Voici la réponse principale avec le code, s'il vous plaît noter que vous pouvez obtenir un certain nombre de dates / heures précision, secondes et minutes ou secondes, en minutes et les jours, en tout lieu à des années (qui contiendrait 6 parties / segments). Si vous spécifiez deux premiers et il est plus d'un an, il retournera « 1 an et 3 mois » et ne reviendra pas le reste parce que vous avez demandé deux segments. si elle est seulement quelques heures vieux, il ne retournera « 2 heures et il y a 1 minute ». Bien sûr, les mêmes règles sont applicables si vous spécifiez 1, 2, 3, 4, 5 ou 6 segmets (plafonne à 6 en raison secondes, minutes, heures, jours, mois, années ne font que 6 types). Il sera également des problèmes de Grammer corrects comme « minutes » vs « minute » selon si elle est 1 minute ou plus, même pour tous les types et la « chaîne » générés sera toujours grammaticalement correct.

Voici quelques exemples d'utilisation: bAllowSegments identifie le nombre de segments pour montrer ... à savoir: si 3, puis retour chaîne serait (comme exemple) ... "3 years, 2 months and 13 days" (ne comprend pas les heures, les minutes et les secondes que les catégories de temps 3 premiers sont retournés), si cependant, la date était une nouvelle date comme la chose il y a quelques jours, en spécifiant les mêmes segments (3) retourne à la place "4 days, 1 hour and 13 minutes ago", il prend tout en compte!

si bAllowSegments est 2 il reviendriez "3 years and 2 months" et si 6 (valeur maximale) retourneraient "3 years, 2 months, 13 days, 13 hours, 29 minutes and 9 seconds", mais être rappelé qu'il NEVER RETURN quelque chose comme ça "0 years, 0 months, 0 days, 3 hours, 2 minutes and 13 seconds ago" car il comprend qu'il n'y a pas de données de date dans les 3 premiers segments et les ignore , même si vous spécifiez 6 segments, donc ne vous inquiétez pas :). Bien sûr, s'il y a un segment avec 0 en elle, il faudra en tenir compte lors de la formation de la chaîne, et affichera comme "3 days and 4 seconds ago" et en ignorant la partie « 0 heures »! Profitez et s'il vous plaît commentaire si vous le souhaitez.

 Public Function RealTimeUntilNow(ByVal dt As DateTime, Optional ByVal bAllowSegments As Byte = 2) As String
  ' bAllowSegments identifies how many segments to show... ie: if 3, then return string would be (as an example)...
  ' "3 years, 2 months and 13 days" the top 3 time categories are returned, if bAllowSegments is 2 it would return
  ' "3 years and 2 months" and if 6 (maximum value) would return "3 years, 2 months, 13 days, 13 hours, 29 minutes and 9 seconds"
  Dim rYears, rMonths, rDays, rHours, rMinutes, rSeconds As Int16
  Dim dtNow = DateTime.Now
  Dim daysInBaseMonth = Date.DaysInMonth(dt.Year, dt.Month)

  rYears = dtNow.Year - dt.Year
  rMonths = dtNow.Month - dt.Month
  If rMonths < 0 Then rMonths += 12 : rYears -= 1 ' add 1 year to months, and remove 1 year from years.
  rDays = dtNow.Day - dt.Day
  If rDays < 0 Then rDays += daysInBaseMonth : rMonths -= 1
  rHours = dtNow.Hour - dt.Hour
  If rHours < 0 Then rHours += 24 : rDays -= 1
  rMinutes = dtNow.Minute - dt.Minute
  If rMinutes < 0 Then rMinutes += 60 : rHours -= 1
  rSeconds = dtNow.Second - dt.Second
  If rSeconds < 0 Then rSeconds += 60 : rMinutes -= 1

  ' this is the display functionality
  Dim sb As StringBuilder = New StringBuilder()
  Dim iSegmentsAdded As Int16 = 0

  If rYears > 0 Then sb.Append(rYears) : sb.Append(" year" & If(rYears <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rMonths > 0 Then sb.AppendFormat(rMonths) : sb.Append(" month" & If(rMonths <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rDays > 0 Then sb.Append(rDays) : sb.Append(" day" & If(rDays <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rHours > 0 Then sb.Append(rHours) : sb.Append(" hour" & If(rHours <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rMinutes > 0 Then sb.Append(rMinutes) : sb.Append(" minute" & If(rMinutes <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rSeconds > 0 Then sb.Append(rSeconds) : sb.Append(" second" & If(rSeconds <> 1, "s", "") & "") : iSegmentsAdded += 1

parseAndReturn:

  ' if the string is entirely empty, that means it was just posted so its less than a second ago, and an empty string getting passed will cause an error
  ' so we construct our own meaningful string which will still fit into the "Posted * ago " syntax...

  If sb.ToString = "" Then sb.Append("less than 1 second")

  Return ReplaceLast(sb.ToString.TrimEnd(" ", ",").ToString, ",", " and")

 End Function

Bien sûr, vous aurez besoin d'une fonction « ReplaceLast », qui prend une chaîne source, et un argument en précisant ce qui doit être remplacé, et un autre arg précisant ce que vous voulez le remplacer par, et il remplace seulement le dernier occurance de cette chaîne ... J'ai inclus mon un si vous ne l'avez pas ou ne voulez pas mettre en œuvre, si elle est ici, cela fonctionnera « comme est » sans modification nécessaire. Je sais que la fonction ReverseIt est plus nécessaire (existe en .net), mais le ReplaceLast et la func ReverseIt sont reportés des jours pre-.net, donc s'il vous plaît excuser la façon dont il peut sembler daté (fonctionne toujours tho 100%, en utilisant été em depuis plus de dix ans, peut guarante ils sont sans bug) ... :). En outre, si vous utilisez VB6, vous pouvez utiliser StrReverse (l'enroulant autour de la chaîne étendue avec la méthode d'extension .ReverseIt), au lieu d'utiliser la fonction ReverseIt () (fournie en tant que méthode d'extension). Ainsi, au lieu de faire sReplacable.ReverseIt, vous feriez StrReverse (sReplacable) comme StrReverse () est une fonction intégrée VB6 (et fait exactement la même chose, inverse une chaîne donnée, et ne fait rien de plus). Si vous utilisez StrReverse () au lieu de ma fonction ReverseIt générique, vous pouvez supprimer la fonction ReverseIt / l'extension. fonction StrReverse () devrait être disponible dans .NET aussi longtemps que vous importez la bibliothèque héritage ms-VisualBasic-dll. Ça ne fait aucune différence de toute façon, je l'avais écrit ReverseIt () avant que je sais même une fonction StrReverse () avait existé et avait été l'utiliser depuis par habitude (aucune raison de la mienne utiliser, par opposition à la fonction générique construit StrReverse) - en fait, je suis sûr que StrReverse (ou une version similaire, spécifique .NET plus récente d'une chaîne fonction d'inversion) en écrirait être plus efficace :). acclamations.

<Extension()> _ 
Public Function ReplaceLast(ByVal sReplacable As String, ByVal sReplaceWhat As String, ByVal sReplaceWith As String) As String 
    ' let empty string arguments run, incase we dont know if we are sending and empty string or not. 
    sReplacable = sReplacable.ReverseIt 
    sReplacable = Replace(sReplacable, sReplaceWhat.ReverseIt, sReplaceWith.ReverseIt, , 1) ' only does first item on reversed version! 
    Return sReplacable.ReverseIt.ToString 
End Function 

<Extension()> _ 
Public Function ReverseIt(ByVal strS As String, Optional ByVal n As Integer = -1) As String 
    Dim strTempX As String = "", intI As Integer 

    If n > strS.Length Or n = -1 Then n = strS.Length 

    For intI = n To 1 Step -1 
        strTempX = strTempX + Mid(strS, intI, 1) 
    Next intI 

    ReverseIt = strTempX + Right(strS, Len(strS) - n) 

End Function 

Autres conseils

Voici comment ajouter des méthodes d'extension pour cela avec C # en utilisant des valeurs moyennes:

public static class TimeSpanExtensions
{
    public static int GetYears(this TimeSpan timespan)
    {
        return (int)(timespan.Days/365.2425);
    }
    public static int GetMonths(this TimeSpan timespan)
    {
        return (int)(timespan.Days/30.436875);
    }
}

Ce que vous cherchez est en effet pas ce que représente TimeSpan. TimeSpan représente un intervalle en tant que nombre de tiques, sans égard à un DateTime de base ou Calendar.

Un nouveau type de DateDifference serait plus logique ici, avec une méthode constructeur ou une usine prenant une DateTime de base, une DateTime cible, et éventuellement un Calendar (par défaut à CultureInfo.CurrentCulture) avec laquelle pour calculer les différentes composantes de différence (années, mois, etc.)

EDIT: Il me semble que temps Noda peut avoir les outils dont vous avez besoin pour cela - la classe Period « [r] epresents une période de temps exprimée en termes chronologiques de l'homme: les heures, les jours, les semaines, les mois et ainsi de suite », et Period.Between(then, now, PeriodUnits.AllUnits) particulier semble être le calcul précis que vous demandez - mais il est nécessairement un complexe beaucoup plus classe que TimeSpan. Concepts clés sur le wiki temps Noda explique comment « les humains font temps désordre ":

  

En laissant de côté les bits délicates de l'astronomie et de la relativité, l'humanité a   toujours en temps difficile à négocier. Si nous avons tous utilisé les tiques du Unix   époque pour parler du temps, il n'y aurait pas besoin d'une bibliothèque comme   Temps Noda.

     

Mais non, nous aimons parler en années, mois, jours, semaines - et pour certains   raison pour laquelle nous aimons 24:00 (qui vient de prêter à confusion avant 13 heures) pour être à peu près   le moment où le soleil est le plus élevé ... nous avons donc fuseaux horaires .

     

Non seulement cela, mais nous ne sommes pas tous d'accord sur combien de mois il y a.   Différentes civilisations ont trouvé des façons différentes de séparation   l'année et des chiffres différents pour les années à commencer. Celles-ci   sont systèmes de calendrier .

Eh bien, mieux vaut tard rien que je suppose;)

fonction C # donnant tout

Et voici ma version modifiée:

private string GetElapsedTime(DateTime from_date, DateTime to_date) {
int years;
int months;
int days;
int hours;
int minutes;
int seconds;
int milliseconds;

//------------------
// Handle the years.
//------------------
years = to_date.Year - from_date.Year;

//------------------------
// See if we went too far.
//------------------------
DateTime test_date = from_date.AddMonths(12 * years);

if (test_date > to_date)
{
    years--;
    test_date = from_date.AddMonths(12 * years);
}

//--------------------------------
// Add months until we go too far.
//--------------------------------
months = 0;

while (test_date <= to_date)
{
    months++;
    test_date = from_date.AddMonths(12 * years + months);
}

months--;

//------------------------------------------------------------------
// Subtract to see how many more days, hours, minutes, etc. we need.
//------------------------------------------------------------------
from_date = from_date.AddMonths(12 * years + months);
TimeSpan remainder = to_date - from_date;
days = remainder.Days;
hours = remainder.Hours;
minutes = remainder.Minutes;
seconds = remainder.Seconds;
milliseconds = remainder.Milliseconds;

return (years > 0 ? years.ToString() + " years " : "") +
       (months > 0 ? months.ToString() + " months " : "") +
       (days > 0 ? days.ToString() + " days " : "") +
       (hours > 0 ? hours.ToString() + " hours " : "") +
       (minutes > 0 ? minutes.ToString() + " minutes " : "");}

Je dirais que le TimeSpan actuel est un objet réel timespan, à savoir, la quantité de temps entre le 1 janvier 2008 01:31 et le 3 février 2008 à 06h45 est le même que la quantité de temps entre le 5 février 2008 à 13h45 et 9 Mars 2008 à 06:59 h, heure .. Ce que vous cherchez est en réalité la différence entre deux dates.

En ce qui concerne la .MakeMagicHappen.gimmeSomethingPretty.surelyMShasThoughtAboutThisDilema pour répondre aux besoins spécifiques de votre système, c'est pourquoi les gens vous embaucher en tant que programmeur. Si le cadre que vous utilisez ne fait absolument tout, votre entreprise serait tout simplement être en mesure de presss un seul bouton et leur système se sortir complètement formé et vous seriez sur la ligne de chômage ainsi que le reste des programmeurs nous.

En utilisant .Net 4.5 et la classe CultureInfo, on peut ajouter des mois et des années à une date donnée.

DateTime datetime = DateTime.UtcNow;
int years = 15;
int months = 7;

DateTime yearsAgo = CultureInfo.InvariantCulture.Calendar.AddYears(datetime, -years);
DateTime monthsInFuture = CultureInfo.InvariantCulture.Calendar.AddMonths(datetime, months);

Puisque c'est beaucoup de dactylographie, je préfère créer des méthodes d'extension:

public static DateTime AddYears(this DateTime datetime, int years)
{
    return CultureInfo.InvariantCulture.Calendar.AddYears(datetime, years);
}

public static DateTime AddMonths(this DateTime datetime, int months)
{
    return CultureInfo.InvariantCulture.Calendar.AddMonths(datetime, months);
}

DateTime yearsAgo = datetime.AddYears(-years);
DateTime monthsInFuture = datetime.AddMonths(months);

Je crois que la méthode suivante est assez trusteable et simple, car il est basé sur le calcul de la date de cadre et renvoie une chaînes de temps écoulé lisibles comme Ones Facebook. Désolé pour les petits mots portugais et traitement pluriel, dans mon cas, il était nécessaire.

public static string ElapsedTime(DateTime dtEvent)
{
    TimeSpan TS = DateTime.Now - dtEvent;

    int intYears = TS.Days / 365;
    int intMonths = TS.Days / 30;
    int intDays = TS.Days;
    int intHours = TS.Hours;
    int intMinutes = TS.Minutes;
    int intSeconds = TS.Seconds;

    if (intYears > 0) return String.Format("há {0} {1}", intYears, (intYears == 1) ? "ano" : "anos");
    else if (intMonths > 0) return String.Format("há {0} {1}", intMonths, (intMonths == 1) ? "mês" : "meses");
    else if (intDays > 0) return String.Format("há {0} {1}", intDays, (intDays == 1) ? "dia" : "dias");
    else if (intHours > 0) return String.Format("há ± {0} {1}", intHours, (intHours == 1) ? "hora" : "horas");
    else if (intMinutes > 0) return String.Format("há ± {0} {1}", intMinutes, (intMinutes == 1) ? "minuto" : "minutos");
    else if (intSeconds > 0) return String.Format("há ± {0} {1}", intSeconds, (intSeconds == 1) ? "segundo" : "segundos");
    else
    {
        return String.Format("em {0} às {1}", dtEvent.ToShortDateString(), dtEvent.ToShortTimeString());
    }
}

Je pris la réponse acceptée et l'a converti de VB.Net à C # et fait quelques modifications / améliorations aussi bien. Je me suis débarrassé des inversions de cordes, qui ont été utilisés pour remplacer la dernière instance d'une chaîne, et utilisé une méthode d'extension plus directement trouve et remplace la dernière instance d'une chaîne.

Exemple de comment appeler la méthode:

PeriodBetween(#2/28/2011#, DateTime.UtcNow, 6)

principale Méthode:

public static string PeriodBetween(DateTime then, DateTime now, byte numberOfPeriodUnits = 2)
{
    // Translated from VB.Net to C# from: https://stackoverflow.com/a/1956265

    // numberOfPeriodUnits identifies how many time period units to show.
    // If numberOfPeriodUnits = 3, function would return:
    //      "3 years, 2 months and 13 days"
    // If numberOfPeriodUnits = 2, function would return:
    //      "3 years and 2 months"
    // If numberOfPeriodUnits = 6, (maximum value), function would return:
    //      "3 years, 2 months, 13 days, 13 hours, 29 minutes and 9 seconds"

    if (numberOfPeriodUnits > 6 || numberOfPeriodUnits < 1)
    {
        throw new ArgumentOutOfRangeException($"Parameter [{nameof(numberOfPeriodUnits)}] is out of bounds. Valid range is 1 to 6.");
    }

    short Years = 0;
    short Months = 0;
    short Days = 0;
    short Hours = 0;
    short Minutes = 0;
    short Seconds = 0;
    short DaysInBaseMonth = (short)(DateTime.DaysInMonth(then.Year, then.Month));

    Years = (short)(now.Year - then.Year);

    Months = (short)(now.Month - then.Month);
    if (Months < 0)
    {
        Months += 12;
        Years--; // add 1 year to months, and remove 1 year from years.
    }

    Days = (short)(now.Day - then.Day);
    if (Days < 0)
    {
        Days += DaysInBaseMonth;
        Months--;
    }

    Hours = (short)(now.Hour - then.Hour);
    if (Hours < 0)
    {
        Hours += 24;
        Days--;
    }

    Minutes = (short)(now.Minute - then.Minute);
    if (Minutes < 0)
    {
        Minutes += 60;
        Hours--;
    }

    Seconds = (short)(now.Second - then.Second);
    if (Seconds < 0)
    {
        Seconds += 60;
        Minutes--;
    }

    // This is the display functionality.
    StringBuilder TimePeriod = new StringBuilder();
    short NumberOfPeriodUnitsAdded = 0;

    if (Years > 0)
    {
        TimePeriod.Append(Years);
        TimePeriod.Append(" year" + (Years != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Months > 0)
    {
        TimePeriod.AppendFormat(Months.ToString());
        TimePeriod.Append(" month" + (Months != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Days > 0)
    {
        TimePeriod.Append(Days);
        TimePeriod.Append(" day" + (Days != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Hours > 0)
    {
        TimePeriod.Append(Hours);
        TimePeriod.Append(" hour" + (Hours != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Minutes > 0)
    {
        TimePeriod.Append(Minutes);
        TimePeriod.Append(" minute" + (Minutes != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Seconds > 0)
    {
        TimePeriod.Append(Seconds);
        TimePeriod.Append(" second" + (Seconds != 1 ? "s" : "") + "");
        NumberOfPeriodUnitsAdded++;
    }

    ParseAndReturn:
    // If the string is empty, that means the datetime is less than a second in the past.
    // An empty string being passed will cause an error, so we construct our own meaningful
    // string which will still fit into the "Posted * ago " syntax.

    if (TimePeriod.ToString() == "")
    {
        TimePeriod.Append("less than 1 second");
    }

    return TimePeriod.ToString().TrimEnd(' ', ',').ToString().ReplaceLast(",", " and");
}

ReplaceLast Méthode d'extension:

public static string ReplaceLast(this string source, string search, string replace)
{
    int pos = source.LastIndexOf(search);

    if (pos == -1)
    {
        return source;
    }

    return source.Remove(pos, search.Length).Insert(pos, replace);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top