9
votes

Calculer des années, mois, semaines et jours

Dans ma candidature, un utilisateur entre deux dates. Une date de début planifiée et une date de fin planifiée. Nous devons prendre ces dates et peupler 4 champs, en fonction de la différence.

Alors, disons qu'il sélectionne le 1er janvier 2010 en tant que début et 2 mars 2011 comme fin, nous devons vous retrouver avec:

ans: 1 Mois: 2 Semaines: 0 Jours 1

ce qui signifie que la durée totale est de 1 an, 2 mois et 1 jour.

Y a-t-il une façon standard de faire cela? Ou devrais-je écrire une méthode qui a beaucoup de logique assez délicieuse pour l'exercer? J'espérais avoir de la chance et il y aurait une classe de type Date-Diff .NET disponible.


11 Réponses :


2
votes

Je pense Timespan est ce que vous recherchez , mais cela ne fait pas d'années ou de mois, car ceux-ci varient en longueur.

L'exemple ci-dessous est de la liaison ci-dessus; xxx


4 commentaires

Cela semble uniquement gérer les valeurs temporelles ... maximum d'heures.


Pourquoi cela stimule-t-il? Cette solution ne répond pas à la question. Je ne vois pas des années, des mois, des semaines et des jours.


J'aime la réponse Je pense que Timespan est ce que vous recherchez, mais cela ne fait pas ce que vous avez demandé :)


Comme Steve W. a souligné Stackoverflow.com/questions/1083955/... a une réponse acceptée. Cependant, ces réponses ne répondent pas non plus à la question, mais montre que les complexités impliquées dans ce type de calcul. Et il répond à la question "Y a-t-il une façon standard de faire cela? Ou devrais-je écrire une méthode qui a beaucoup de logique assez délicieuse pour le faire sortir?"



0
votes

enquêter sur le C # Timespan Structure. Cela ne fait pas de mois ou d'années, mais cela fait des jours. Cela facilite les choses.


0 commentaires

7
votes

Vous pouvez utiliser la catégorie datrodiff de Ce Bibliothèque gratuite: XXX


0 commentaires

9
votes

Heres une méthode complète, des semaines ne sont pas incluses, mais pourraient être ajoutées relativement simplement. C'est une question quelque peu complexe (demandée d'une multitude de façons d'être sur Stackoverflow et a mal répondu à une multitude de façons), mais aucun ne peut être répondu. L'objet Timespan nous donne une partie de ce dont nous avons besoin, mais ne fonctionne que dans des jours. J'ai écrit un nombre important de tests contre cette méthode, si vous trouvez un trou, veuillez poster un commentaire.

Ce que cela va faire est de comparer 2 dates, d'obtenir les années, des mois, des jours, des heures et des minutes. (par exemple, un événement a eu lieu 1 an, 6 mois, 3 jours, il y a 4 heures et 7 minutes)

Parce que cette question a été posée et tentative d'être répondu tant de fois, je ne suis pas sûr que cela va jamais même être remarqué, mais si cela devrait donc fournir une valeur. xxx


2 commentaires

Celui-ci ne calcule pas correctement les «jours». Pendant 139 jours, cela devrait donner 4 mois et 19 jours, sa dit 30 jours au lieu de ce qui est faux. Il manque également les semaines.


@Jhollman Quelques mois ont 31 jours. La portée entre 2018-03-01 et 2019-03-31 est d'un an, zéro mois, 30 jours. Il serait faux d'appeler cela un an un mois.



1
votes
 public partial class Age1 : System.Web.UI.Page
    {
        private int Years;
        private int Months;
        private int Days;
        DateTime Cday;
        DateTime Bday;


        protected void Page_Load(object sender, EventArgs e)
        {
            txtCurrentDate.Enabled = false;
            txtCurrentDate.Text = DateTime.Now.ToString("g");
            Cday = Convert.ToDateTime(txtCurrentDate.Text);
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            Bday = Convert.ToDateTime(txtBirthdate.Text);
            AgeCaluclation(Bday, Cday);
            txtBirthdate.Text = "";
            txtCurrentDate.Text = "";
            lblAge.Text = this.Years+"  Years "+this.Months+"  Months " +this.Days+ "Days";
        }

        private Age1 AgeCaluclation(DateTime Bday, DateTime Cday)
        {

            if ((Cday.Year - Bday.Year) > 0 || 
               (((Cday.Year - Bday.Year) == 0) && 
               ((Bday.Month < Cday.Month) ||
               ((Bday.Month == Cday.Month) && 
               (Bday.Day <= Cday.Day)))))
            {

                int DaysInBdayMonth = DateTime.DaysInMonth(Bday.Year, Bday.Month);
                int DaysRemain = Cday.Day + (DaysInBdayMonth - Bday.Day);

                    if(Cday.Month > Bday.Month)
                    {
                        this.Years = Cday.Year - Bday.Year;
                        this.Months = Cday.Month - (Bday.Month + 1) + Math.Abs(DaysRemain / DaysInBdayMonth);
                        this.Days = (DaysRemain % DaysInBdayMonth + DaysInBdayMonth) % DaysInBdayMonth;
                    }
                    else if (Cday.Month == Bday.Month)
                    {
                        if (Cday.Day >= Bday.Day)
                        {
                            this.Years = Cday.Year - Bday.Year;
                            this.Months = 0;
                            this.Days = Cday.Day - Bday.Day;
                        }
                        else
                        {
                            this.Years = (Cday.Year - 1) - Bday.Year;
                            this.Months = 11;
                            this.Days = DateTime.DaysInMonth(Bday.Year, Bday.Month) - (Bday.Day - Cday.Day);

                        }
                    }
                    else
                    {
                        this.Years = (Cday.Year - 1) - Bday.Year;
                        this.Months = Cday.Month + (11 - Bday.Month) + Math.Abs(DaysRemain / DaysInBdayMonth);
                        this.Days = (DaysRemain % DaysInBdayMonth + DaysInBdayMonth) % DaysInBdayMonth;
                    }
            }
            else
            {
                throw new ArgumentException("Birthday date must be earlier than current date");
            }
            return this;
        }

    }

0 commentaires

4
votes

J'en avais aussi besoin que, dans mon cas, sans la partie des semaines (alors seulement des années, des mois et des jours). Étant donné que, voici ce que j'ai fait: xxx pré>

Si vous souhaitez l'afficher plus dynamiquement, vous pouvez également utiliser ce code: P>

//build the string
var result = "";
if (years!=0){
    result = years == 1 ? years + " year" : years + " years";
}
if (months != 0) {
    if (result != "") {
        result += ", ";
    }
    result += months == 1 ? months + " month" : months + " months";
}
if (days != 0) {
    if (result != "") {
        result += ", ";
    }
    result += days == 1 ? days + " day" : days + " days";
}
Debug.WriteLine (result);


0 commentaires

1
votes

J'avais créé celui-ci pour la différence de retour en années, mois et jours entre 2 dates. XXX


2 commentaires

Merci pour votre réponse. Ce serait génial si vous ajoutez également une courte explication et quelques commentaires à votre code. Cela aide les gens à mieux comprendre votre réponse.


La pièce DaysinMonIth () échouera, si la valeur de Todate est en janvier, car elle soustrait 1 forme la valeur du mois. Pour corriger: DateTime PrevmonThdate = TODate.AddMonths (-1); JOURS = JOURS + (DATÉTIME.DAYSINION (PREVMONTHDATE.YEAR, PREVMONTHDATE.MONSTATH) - DeDated.day);



0
votes

La logique n'est pas trop compliquée si vous calculez d'abord le total des mois et les jours totaux. Ensuite, il est facile de faire un peu de mathématiques entier avec Divide et Mod.

DateTime start_date = new DateTime(2010, 1, 1);
DateTime end_date = new DateTime(2011, 3, 2);

int diff_years = end_date.Year - start_date.Year;
int diff_months = end_date.Month - start_date.Month;

int total_months = 12 * diff_years + diff_months;
DateTime near_end_date = start_date.AddMonths(total_months);
int total_days = (int)end_date.Subtract(near_end_date).TotalDays;

int years = total_months / 12;
int months = total_months % 12;
int weeks = total_days / 7;
int days = total_days % 7;

Console.WriteLine($"Years: {years} Months: {months} Weeks: {weeks} Days: {days}");


0 commentaires


0
votes

Heres un convertisseur que je viens de construire. Je n'ai pas essayé toutes les solutions ci-dessus, mais toutes celles que j'ai essayées étaient encore légèrement éteintes d'une manière ou d'une autre. Cela prend en compte des années, des années de bonds, des mois, des semaines, des jours, etc., puis attrape les deux valeurs les plus utiles de YM ou MW ou WD ou DH. C'est simple mais j'en avais besoin que mon projet puisse peut-être avoir une aide à une personne sur la route. Et puis bien sûr, si ce n'est pas bon pour une raison ou une autre, je suis sûr que vous le ferez tout le faire savoir.

        DateTime beforeDate = topic.lastActive.ToLocalTime();
        DateTime futureDate = DateTime.Now.ToLocalTime();

        int minutes = 0;
        int hours = 0;
        int days = 0;
        int weeks = 0;
        int months = 0;
        int years = 0;

        Dictionary<int, int> dictMonths = new Dictionary<int, int> { };
        dictMonths.Add(1, 31);
        if (DateTime.IsLeapYear(futureDate.Year))
            dictMonths.Add(2, 29);
        else
            dictMonths.Add(2, 28);
        dictMonths.Add(3, 31);
        dictMonths.Add(4, 30);
        dictMonths.Add(5, 31);
        dictMonths.Add(6, 30);
        dictMonths.Add(7, 31);
        dictMonths.Add(8, 31);
        dictMonths.Add(9, 30);
        dictMonths.Add(10, 31);
        dictMonths.Add(11, 30);
        dictMonths.Add(12, 31);

        //Time difference between dates
        TimeSpan span = futureDate - beforeDate;
        hours = span.Hours;
        minutes = span.Minutes;

        //Days total
        days = span.Days;
        //Find how many years
        DateTime zeroTime = new DateTime(1, 1, 1);

        // Because we start at year 1 for the Gregorian
        // calendar, we must subtract a year here.
        years = (zeroTime + span).Year - 1;
        //find difference of days of years already found
        int startYear = futureDate.Year - years;
        for (int i = 0; i < years; i++)
        {
            if (DateTime.IsLeapYear(startYear))
                days -= 366;
            else
                days -= 365;

            startYear++;
        }
        //Find months by multiplying months in year by difference of datetime years then add difference of current year months
        months = 12 * (futureDate.Year - beforeDate.Year) + (futureDate.Month - beforeDate.Month);
        //month may need to be decremented because the above calculates the ceiling of the months, not the floor.
        //to do so we increase before by the same number of months and compare.
        //(500ms fudge factor because datetimes are not precise enough to compare exactly)
        if (futureDate.CompareTo(beforeDate.AddMonths(months).AddMilliseconds(-500)) <= 0)
        {
            --months;
        }
        //subtract months from how many years we have already accumulated
        months -= (12 * years);
        //find how many days by compared to our month dictionary
        int startMonth = beforeDate.Month;
        for (int i = 0; i < months; i++)
        {
            //check if faulty leap year
            if (startMonth == 2 && (months - 1 > 10))
                days -= 28;
            else
                days -= dictMonths[startMonth];
            startMonth++;
            if (startMonth > 12)
            {
                startMonth = 1;
            }
        }
        //Find if any weeks are within our now total days
        weeks = days / 7;
        if (weeks > 0)
        {
            //remainder is days left
            days = days % 7;
        }

        Console.WriteLine(years + " " + months + " " + weeks + " " + days + " " + span.Hours + " " + span.Minutes);

        if (years > 0)
        {
            if (years > 1 && months > 1)
                return $"Latest Reply: {years} years, {months} months ago.";
            else if (years > 1 && months == 0)
                return $"Latest Reply: {years} years ago.";
            else if (years == 1 && months == 0)
                return $"Latest Reply: {years} year ago.";
            else if (years > 1)
                return $"Latest Reply: {years} years, {months} month ago.";
            else if (months > 1)
                return $"Latest Reply: {years} year, {months} months ago.";
            else
                return $"Latest Reply: {years} year, {months} month ago.";
        }
        else if (months > 0)
        {
            if (months > 1 && weeks > 1)
                return $"Latest Reply: {months} months, {weeks} weeks ago.";
            else if (months > 1 && weeks == 0)
                return $"Latest Reply: {months} months ago.";
            else if (months == 1 && weeks == 0)
                return $"Latest Reply: {months} month ago.";
            else if (months > 1)
                return $"Latest Reply: {months} months, {weeks} week ago.";
            else if (weeks > 1)
                return $"Latest Reply: {months} month, {weeks} weeks ago.";
            else
                return $"Latest Reply: {months} month, {weeks} week ago.";
        }
        else if (weeks > 0)
        {
            if (weeks > 1 && days > 1)
                return $"Latest Reply: {weeks} weeks, {days} days ago.";
            else if (weeks > 1 && days == 0)
                return $"Latest Reply: {weeks} weeks ago.";
            else if (weeks == 1 && days == 0)
                return $"Latest Reply: {weeks} week ago.";
            else if (weeks > 1)
                return $"Latest Reply: {weeks} weeks, {days} day ago.";
            else if (days > 1)
                return $"Latest Reply: {weeks} week, {days} days ago.";
            else
                return $"Latest Reply: {weeks} week, {days} day ago.";
        }
        else if (days > 0)
        {
            if (days > 1 && hours > 1)
                return $"Latest Reply: {days} days, {hours} hours ago.";
            else if (days > 1 && hours == 0)
                return $"Latest Reply: {days} days ago.";
            else if (days == 1 && hours == 0)
                return $"Latest Reply: {days} day ago.";
            else if (days > 1)
                return $"Latest Reply: {days} days, {hours} hour ago.";
            else if (hours > 1)
                return $"Latest Reply: {days} day, {hours} hours ago.";
            else
                return $"Latest Reply: {days} day, {hours} hour ago.";
        }
        else if (hours > 0)
        {
            if (hours > 1 && minutes > 1)
                return $"Latest Reply: {hours} hours, {minutes} minutes ago.";
            else if (hours > 1 && minutes == 0)
                return $"Latest Reply: {hours} hours ago.";
            else if (hours == 1 && minutes == 0)
                return $"Latest Reply: {hours} hour ago.";
            else if (hours > 1)
                return $"Latest Reply: {hours} hours, {minutes} minute ago.";
            else if (minutes > 1)
                return $"Latest Reply: {hours} hour, {minutes} minutes ago.";
            else
                return $"Latest Reply: {hours} hour, {minutes} minute ago.";
        }
        else if (minutes > 0)
        {
            if (minutes > 1)
                return $"Latest Reply: {minutes} minutes ago.";
            else
                return $"Latest Reply: {minutes} minute ago.";
        }
        else
        {
            return $"Latest Reply: Just now.";
        }


0 commentaires

0
votes

C'est une question assez ancienne, mais il est encore temps de partir.

important à considérer que des mois ont un nombre différent de jours. xxx


0 commentaires