Avatar billede wired Nybegynder
27. august 2006 - 00:57 Der er 12 kommentarer og
1 løsning

Forskel mellem to datoer opgivet i år, måned og dage

Jeg søger en metode til at udregne forskellen mellem to datoer og resultatet skal opgives i år,måneder og dage.

Problemet er at få resultatet i måneder og dage.

Jeg er opmærksom på at der er forskellige antal dage for f.eks. feb. afhængig af året etc. Derfor dette spørgsmål.
Avatar billede arne_v Ekspert
27. august 2006 - 01:40 #1
bedste ide jeg kan komme på er:

        public struct YMD
        {
            public int Y;
            public int M;
            public int D;
        }
        public static YMD DateDiff(DateTime t1, DateTime t2)
        {
            YMD res = new YMD();
            DateTime tmp = t1;
            while(tmp.AddYears(-1) >= t2)
            {
                res.Y++;
                tmp = tmp.AddYears(-1);
            }
            while(tmp.AddMonths(-1) >= t2)
            {
                res.M++;
                tmp = tmp.AddMonths(-1);
            }
            while(tmp.AddDays(-1) >= t2)
            {
                res.D++;
                tmp = tmp.AddDays(-1);
            }
            return res;
        }
Avatar billede nielle Nybegynder
27. august 2006 - 08:43 #2
Jeg synes at det er en af den slags spørgsmål der ikke kan gives noget eksakt svare på.

"Hvor mange dage, måneder og år er der imellem 15/2-2006 og 15/3-2006" ?

Nu er 2006 ikke et skudår, så vi har ikke denne komplikation. Men hvor lang er "en måned" lige i ovennævnte sammenhæng? Er den 28 dage fordi at februar er 28, eller er den 31 dage fordi at marts er 31? Begge valg er vel lige gyldige i situationen.

Og hvad sker der med denne definition når det er skudår. Bliver "en måned" så 29 dage eller 31 dage? Mao. "en måned" er ikke nogen veldefineret måleenhed.

Eller er den pr. definition altid 30 dage? (og så er der jo ikke noget problem med skudår).
Avatar billede nielle Nybegynder
27. august 2006 - 09:52 #3
... bare for at køre lidt videre på retorikken:

"Hvor mange dage, måneder og år er der imellem 1/2-2006 og 1/3-2006" ?
"Hvor mange dage, måneder og år er der imellem 28/2-2006 og 28/3-2006" ?

I det første tilfælde ville svaret måske naturligt nok være "1 måned og 1 dag", men hvad med det andet? Vil vi sige "1 måned og ..." blot fordi at den 1. dato ligger i februar? Ville "29 dage" ikke være et mere naturligt svar? Men så er det næste spørgsmål hvornår man skifter mellem at vælge "29 dage" fremfor "1 måned og 1 dag". Hvad ville f.eks. være det naturlige valg midtvejs i februar?

"Hvor mange dage, måneder og år er der imellem 14/2-2006 og 14/3-2006" ?

Men, ikke destomindre er der lige mange dage imellem datoerne i alle tre eksempler.
Avatar billede wired Nybegynder
27. august 2006 - 13:43 #4
Du har fuldstændig ret nielle. Uden at gå dybere ind på dabatten som jeg også læste på http://www.dotnet247.com/247reference/msgs/48/244018.aspx betragter jeg måske nok bare en måned som dagen fra første dato(måned) til samme dag i næste dato(måned). Og ja det betyder at man må gennemløbe alle månederne(år) i mellem de to datoer.

Og selv om arne ikke løser opgaven 100% er jeg igen igen imponeret over hvor korrekt et svar han igen igen er kommet med og så hurtigt. På baggrund af debatten må det nok konkluderes som den bedste (måske eneste) løsning på svaret.

Jeg takker... og må bede Arne om et svar.
Avatar billede wired Nybegynder
27. august 2006 - 13:45 #5
"som jeg også læste mere om på ..." skulle der have stået.
Avatar billede nielle Nybegynder
27. august 2006 - 14:25 #6
Den definition halter lidt (IMHO), for i følge den må der jo være:

1 måned og 0 dage fra:

28/1-2006 til 28/2-2006 (????)
29/1-2006 til 28/2-2006
30/1-2006 til 28/2-2006
31/1-2006 til 28/2-2006

Og hvor langt er der så fra:

31/1-2006 til 31/3-2006 ?

Er der "2 måneder"? Eller er der "2 måneder og 3 dage"?:

31/1-2006 -> 28/2-2006 -> 28/3-2006 -> 31/3-2006
Avatar billede wired Nybegynder
27. august 2006 - 16:57 #7
OIC you'r point. Løsningen er måske at tælle antallet af dage fra første datos måned og til måneden er slut plus antallet af dage i den anden datos måned, og så bare tælle hele måneder i mellem sammen.

dvs.
fra 31/1-2006 til 1/2-2006 giver hhv.0 el. 1 afhængig af valg
fra 1/2-2006 til 1/3-2006 giver 1 måned
fra 1/3-2006 til 31/3-2006 giver hhv. 30 el 31 afhængig af valg

I dit tilfælde vil man så få 1 måneder og 31 (evt. 32) dage.

En mulighed måske?
Avatar billede nielle Nybegynder
27. august 2006 - 17:34 #8
Men, den kan jo sagtens give mere end 31/32 dage:

5/1-2006 til 25/2-2006

- giver 27+25 = 52 dage.

Jeg tror som sagt ikke at der er nogen entydig og fuldstændig logisk definition af hvor mange dage, måneder og år der er i mellem to givne datoer. Selv den jeg ellers ville anbefale, 1 måned = 30 dage, holder ikke fuldstændigt vand.

Men når alt kommer til alt: Er der overhovedet nogen grund til at have en eksakt definition? Det afhænger vel at omstændighederne, og i langt de fleste tilfælde er et ca. resultat ganske udemærket.
Avatar billede arne_v Ekspert
27. august 2006 - 17:42 #9
Der vil ofte være 1 dags (op til 3 hvis februar er involveret) forskel på
om man tæller forlæns eller baglæns.

Kode:

using System;

namespace E
{
    public class MainClass
    {
        public struct YMD
        {
            public int Y;
            public int M;
            public int D;
        }
        public static YMD DateDiffBackward(DateTime t1, DateTime t2)
        {
            YMD res = new YMD();
            DateTime tmp = t1;
            while(tmp.AddYears(-1) >= t2)
            {
                res.Y++;
                tmp = tmp.AddYears(-1);
            }
            while(tmp.AddMonths(-1) >= t2)
            {
                res.M++;
                tmp = tmp.AddMonths(-1);
            }
            while(tmp.AddDays(-1) >= t2)
            {
                res.D++;
                tmp = tmp.AddDays(-1);
            }
            return res;
        }
        public static YMD DateDiffForward(DateTime t1, DateTime t2)
        {
            YMD res = new YMD();
            DateTime tmp = t2;
            while(tmp.AddYears(1) <= t1)
            {
                res.Y++;
                tmp = tmp.AddYears(1);
            }
            while(tmp.AddMonths(1) <= t1)
            {
                res.M++;
                tmp = tmp.AddMonths(1);
            }
            while(tmp.AddDays(1) <= t1)
            {
                res.D++;
                tmp = tmp.AddDays(1);
            }
            return res;
        }
        public static void Test(DateTime t1, DateTime t2)
        {
            Console.WriteLine(t1 + " " + t2);
            YMD d1 = DateDiffBackward(t1, t2);
            Console.WriteLine("Backward: " + d1.Y + " " + d1.M + " " + d1.D);
            YMD d2 = DateDiffForward(t1, t2);
            Console.WriteLine("Forward: " + d2.Y + " " + d2.M + " " + d2.D);
        }
        public static void Main(string[] args)
        {
            Test(new DateTime(2006, 8, 26), new DateTime(2004, 9, 25));
            Test(new DateTime(2006, 8, 25), new DateTime(2004, 9, 26));
            Test(new DateTime(2006, 2, 28), new DateTime(2004, 1, 30));
            Test(new DateTime(2006, 3, 31), new DateTime(2004, 2, 28));
        }
    }
}

men det er vel et kalender/menneskeligt problem og ikke et .NET/C# problem.

Hvis man kan definere hvad det rigtige svar er, så kan man også implementere det.
Avatar billede arne_v Ekspert
27. august 2006 - 17:44 #10
Hvis det var nemt så havde TimeSpan implementeret det !!
Avatar billede nielle Nybegynder
27. august 2006 - 17:55 #11
Enig! :^)
Avatar billede wired Nybegynder
27. august 2006 - 20:07 #12
Afgjort arne og så havde jeg ikke skrevet dette spørgsmål :-)

Yep nielle der man skal nok vælge at sige at hvis afstanden bliver større end 30 dage skal en ekstra måned tilføjes :-) så bliver der maks 3 dage forkert.

Tak for debatten og for løsningen..

Sender du lige et svar arne?
Avatar billede arne_v Ekspert
27. august 2006 - 20:19 #13
og et svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester