[PHP] Datums van elkaar aftrekken

Pagina: 1 2 Laatste
Acties:
  • 3.888 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Don't worry, dit is niet de "zoveelste" vraag om een datumdiff script, maar in plaats daarvan mijn implementatie.

Ik zocht een oplossing om 2 datums van elkaar af te trekken, en mij te vertellen (in plat Nederlands) wat er nu precies uitkwam. Ik dacht dat ik een implementatie had, en deze deed 2 datums van elkaar aftrekken, en gaf vervolgens weer hoeveel tijd er tussen de 2 datums zat.

Een voorbeeldje:
"3 jaar, 4 maanden, 3 weken, 2 dagen, 2 uur, 33 minuten en 2 seconden"

Ik kwam er echter vanmiddag achter dat mijn oude code een fout bevatte, want iemand die in 1995 geboren was, bleek ineens 2 jaar oud te zijn |:(.

Nu heb ik mijn oude code zo aangepast, dat er deze code is uitgekomen. Het lijkt omslachtig, en dat is ook de reden dat ik hem hier plaats, in de hoop dat ik er niet alleen mensen een hoop "zoekwerk" mee uit handen neem, maar ook dat er een paar kritische code kloppers naar mijn code kunnen kijken.

Allereerst mijn oude implementatie, misschien kunnen jullie er iets mee.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    /**
     * Geeft $str1 terug indien $val gelijk is aan 1, anders (indien $val groter is dan 1 of gelijk is aan 0) gaat $str2 terug.
     */
    function addSingleMultiple($intVal, $strSingle, $strMultiple, $blnSkip=false) {
        if ($blnSkip && ($intVal == 0)) {
            return '';
        } else {
            return $intVal.' '.(($intVal == 1) ? $strSingle : $strMultiple).', ';
        }
    }

    /**
     * Trekt 2 data van elkaar af en geeft het resultaat terug als een string.
     *
     * @param       string      Datum die afgetrokken zal worden van $date2.
     * @param       string      Datum waarvan $date1 afgetrokken zal worden.
     * @return      string      String met het verschil uitgeschreven als een string, bijv: "1 jaar, 0 maanden, 3 weken, 2 dagen, 1 uur, 2 minuten, 3 seconden".
     */
    function dateDiff($intStart, $intEnd) {
        //
        // Constants
        $intDay = 86400;
        $intHour = 3600;
        $intMinute = 60;

        //
        // Variables
        $intStart = parseDateTime($intStart);
        $intEnd = parseDateTime($intEnd);
        $intDateDiff = $intEnd - $intStart;
        $arrResult = array();

        //
        // Init
        $arrResult['past'] = ($intDateDiff < 0) ? true : false;
        $intDateDiff = $arrResult['past'] ? $intDateDiff * -1 : $intDateDiff;

        //
        // Verschillen berekenen
        $arrResult['diff']['days'] = floor($intDateDiff / $intDay);
        $arrResult['diff']['hours'] = floor($intDateDiff / $intHour);
        $arrResult['diff']['minutes'] = floor($intDateDiff / $intMinute);
        $arrResult['diff']['seconds'] = $intDateDiff;

        //
        // De rest doen
        $intI = $intDateDiff;
        $intN = intval($intI / 60);
        $intI = $intI % 60;
        $intH = intval($intN / 60);
        $intN = $intN % 60;
        $intD = intval($intH / 24);
        $intH = $intH % 24;
        $intW = intval($intD / 7);
        $intD = $intD % 7;

        //
        // Maanden tellen
        $intM = 0;
        $intOffset = 0;
        $intTempStart = $arrResult['past'] ? $intEnd : $intStart;
        $intTempEnd = $arrResult['past'] ? $intStart : $intEnd;
        $intCurrent = $intOld = $intTempStart;
        while ($intCurrent < $intTempEnd) {
            $intOffset++;
            $intCurrent = strtotime("+1 weeks", $intCurrent);
            if (
                (
                    (adodb_date('m', $intCurrent) > adodb_date('m', $intOld)) ||
                    (adodb_date('Y', $intCurrent) != adodb_date('Y', $intOld))
                ) &&
                (adodb_date('d', $intCurrent) > adodb_date('d', $intTempStart))
            ) {
                $intM++;
                $intW-= $intOffset;
                $intOffset = 0;
                $intOld = $intCurrent;
            }
        }

        //
        // Nieuwe dagen berekenen
        if ($intM > 0) {
            $intTemp = $intTempEnd - strtotime('+'.$intM.' months +'.$intW.' weeks ', $intTempStart);
            $intD = intval($intTemp / $intDay);
        }

        //
        // Jaartal berekenen
        $intY = intval($intM / 12);

        //
        // Invullen
        $arrResult['diff']['months'] = $intM;
        $arrResult['diff']['years'] = $intY;
        $arrResult['text']['seconds'] = $intI;
        $arrResult['text']['minutes'] = $intN;
        $arrResult['text']['hours'] = $intH;
        $arrResult['text']['days'] = $intD;
        $arrResult['text']['weeks'] = $intW;
        $arrResult['text']['months'] = $intM;
        $arrResult['text']['years'] = $intY;

        //
        // String samenstellen
        $strTemp = addSingleMultiple($intY, 'jaar', 'jaren', true);
        $strTemp.= addSingleMultiple($intM, 'maand', 'maanden', true);
        $strTemp.= addSingleMultiple($intW, 'week', 'weken', true);
        $strTemp.= addSingleMultiple($intD, 'dag', 'dagen', true);
        $strTemp.= addSingleMultiple($intH, 'uur', 'uren', true);
        $strTemp.= addSingleMultiple($intN, 'minuut', 'minuten', true);
        $strTemp.= addSingleMultiple($intI, 'seconde', 'seconden', true);
        $strTemp = substr($strTemp, 0, strlen($strTemp) - 2);
        $arrResult['text']['string'] = $strTemp;
        if (strpos($strTemp, ',')) {
            $arrResult['text']['string'] = substr($strTemp, 0, strrpos($strTemp, ","));
            if ($arrResult['text']['string'] != '') {
                $arrResult['text']['string'].= ' en ';
            }
            $arrResult['text']['string'].= substr($strTemp, strrpos($strTemp, ",") + 1);
        }

        //
        // Eind tijd samenstellen
        $arrResult['start'] = $intStart;
        $arrResult['end'] = $intEnd;

        //
        // Klaar
        return $arrResult;
    }


Bovenstaande code maakt gebruik van een tweetal functies waarvan ik er maar 1 geef, die ander doet namelijk niets anders dan een (string) datum omzetten naar een UNIX integer. Ga er even vanuit dat deze werkt en een int teruggeeft.

Maar goed, hieronder staat de nieuwe implementatie.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    /**
     * Trekt 2 data van elkaar af en geeft het resultaat terug als een string.
     *
     * @param       string      Datum die afgetrokken zal worden van $date2.
     * @param       string      Datum waarvan $date1 afgetrokken zal worden.
     * @return      string      String met het verschil uitgeschreven als een string, bijv: "1 jaar, 0 maanden, 3 weken, 2 dagen, 1 uur, 2 minuten, 3 seconden".
     */
    function dateDiff($intStart, $intEnd) {
        //
        // Start en einddatum naar UNIX omzetten
        $intStart = parseDateTime($intStart);
        $intEnd = parseDateTime($intEnd);
        if (!$intStart || !$intEnd) {
            return false;
        }

        //
        // Juiste berekening gegens nu pakken, zodat we niet continu met -1 hoeven te rekenen
        if ($intStart > $intEnd) {
            $intCalcStart = $intEnd;
            $intCalcEnd = $intStart;
        } else {
            $intCalcStart = $intStart;
            $intCalcEnd = $intEnd;
        }

        //
        // Initializeren van result array
        $arrResult = array();
        $arrResult['start'] = $intCalcStart;
        $arrResult['end'] = $intCalcEnd;
        $arrResult['past'] = ($intStart > $intEnd) ? true : false;
        //
        // En vervolgens berekenen
        $arrResult['totals']['year'] = adodb_date('Y', $intCalcEnd) - adodb_date('Y', $intCalcStart);
        $arrResult['totals']['month'] = adodb_date('m', $intCalcEnd) - adodb_date('m', $intCalcStart) + ($arrResult['totals']['year'] * 12);
        $arrResult['totals']['week'] = adodb_date('W', $intCalcEnd) - adodb_date('W', $intCalcStart) + ($arrResult['totals']['year'] * 52); // from PHP 4.1
        $arrResult['totals']['day'] = adodb_date('z', $intCalcEnd) - adodb_date('z', $intCalcStart) + (((int)adodb_date('L', $intCalcStart)) ? ($arrResult['totals']['year'] * 366) : ($arrResult['totals']['year'] * 365));
        $arrResult['totals']['hour'] = $arrResult['totals']['day'] * 24;
        $arrResult['totals']['minute'] = $arrResult['totals']['hour'] * 60;
        $arrResult['totals']['second'] = ($intCalcEnd - $intCalcStart);

        //
        // Negatieve waardes omvormen
        foreach ($arrResult['totals'] as $strKey => $intValue) {
            //
            // Indien dit deel ervoor zorgt dat we eerder dan de doeldatum uitkomen, klopt er iets niet!
            // Er moet namelijk iets over te houden zijn ;)
            if (strtotime($intValue.' '.$strKey.'s', $arrResult['start']) > $arrResult['end']) {
                $intValue+= ($intValue < 0) ? 1 : -1;
            }

            //
            // Make sure it is acurate
            if ($intValue < 0) {
                $intValue = $intValue * -1;
            }
            $arrResult['totals'][$strKey] = $intValue;
        }

        //
        // Aantal jaren en maanden berekenen
        $arrResult['diff']['year'] = $arrResult['totals']['year'];
        $arrResult['diff']['month'] = ($arrResult['totals']['month'] > 11) ? ($arrResult['totals']['month'] - ($arrResult['totals']['year'] * 12)) : $arrResult['totals']['month'];

        //
        // Tijd die nog over is (in seconden), tot aan de andere datum berekenen
        $intCalcDate = $intCalcEnd - strtotime('+'.$arrResult['diff']['year'].' years +'.$arrResult['diff']['month'].' months', $intCalcStart);

        //
        // Week berekenen
        $arrResult['diff']['week'] = floor(($intCalcDate / 86400) / 7);
        $intCalcDate-= ($arrResult['diff']['week'] * 7) * 86400;

        //
        // Dagen berekenen
        $arrResult['diff']['day'] = floor($intCalcDate / 86400);
        $intCalcDate-= $arrResult['diff']['day'] * 86400;

        //
        // Uren berekenen
        $arrResult['diff']['hour'] = floor($intCalcDate / 3600);
        $intCalcDate-= $arrResult['diff']['hour'] * 3600;

        //
        // Minuten berekenen
        $arrResult['diff']['minute'] = floor($intCalcDate / 60);
        $intCalcDate-= $arrResult['diff']['minute'] * 60;

        //
        // Seconden berekenen
        $arrResult['diff']['second'] = $intCalcDate;

        //
        // String samenstellen
        $strTemp = addSingleMultiple($arrResult['diff']['year'], 'jaar', 'jaren', true);
        $strTemp.= addSingleMultiple($arrResult['diff']['month'], 'maand', 'maanden', true);
        $strTemp.= addSingleMultiple($arrResult['diff']['week'], 'week', 'weken', true);
        $strTemp.= addSingleMultiple($arrResult['diff']['day'], 'dag', 'dagen', true);
        $strTemp.= addSingleMultiple($arrResult['diff']['hour'], 'uur', 'uren', true);
        $strTemp.= addSingleMultiple($arrResult['diff']['minute'], 'minuut', 'minuten', true);
        $strTemp.= addSingleMultiple($arrResult['diff']['second'], 'seconde', 'seconden', true);
        $strTemp = substr($strTemp, 0, strlen($strTemp) - 2);
        $arrResult['text']['string'] = $strTemp;
        if (strpos(',', $strTemp)) {
            $arrResult['text']['string'] = substr($strTemp, 0, strrpos($strTemp, ","));
            if ($arrResult['text']['string'] != '') {
                $arrResult['text']['string'].= ' en ';
            }
            $arrResult['text']['string'].= substr($strTemp, strrpos($strTemp, ",") + 1);
        }

        //
        // Klaar
        return $arrResult;
    }


Maar goed, wat wil ik hiermee bereiken? Misschien een stukje code review _/-\o_ en natuurlijk dat ik er andere mee help O+. Je zou bovenstaande code kunnen gebruiken door zoiets te doen:
PHP:
1
    print_r(dateDiff(adodb_date('d-m-Y'), strtotime("-3 years")));


Natuurlijk ben ik in staat om vragen te beantwoorden en ik hoop ook dat er mensen zijn die serieuze input hebben!

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 11-07 16:55
Ik heb ooit een keer een app voor visual basic geschreven die leeftijd moest uitreken door geboortedagum van huidige datum af te trekken, de truuk daarin was dat elk jaar 365,25 dagen heeft. Als je de ,25 mee rekent kun je een stuk eenvoudiger gaan rekenen, hmm als ik de code nog heb (zit nu op andere pc) zal ik die ook even posten, ik dacht iig dat deze korter was dan wat jij hebt, het is dan wel geen php maar misschien is dezelfde implementatie in php mogelijk, :)

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Wat opmerkingen; de lijst is zeker niet compleet.
- De functienaam addSingleMultiple zegt zo weinig
- Je functie accepteert integers als datums, maar vervolgens ga je er toch vanuit dat het strings zijn.
- Je gebruikt vervolgens parseDateTime, wat geen standaard PHP-functie is, en ook nergens in je code gedefinieerd is. Strtotime lijkt me logischer, en gebruik je later in je functie wel.
- Zelfde als de vorige, maar nu adodb_date en date
- Juiste berekeninggegevens pakken kan korter met min($intStart, $intEnd) en max($intStart, $intEnd)
- Het stukje Negatieve waardes omvormen lijkt overbodig en kan geschrapt worden. In je commentaar zet je trouwens dat er iets niet klopt als dat stukje code toch nodig is; waarom retourneer je dan niet direct een foutmelding?
- Totalsmonth check je op groter dan 11. Maar dit is het verschil tussen twee maanden, en is dus altijd kleiner dan of gelijk aan 12-1=11
- Je commentaar Week/Dagen/Uren/Minuten/Seconden berekenen is wat over the top
- De code gaat de fout in wanneer een dag 23 of 25 uren duurt (zomer-/wintertijd)
- Volgens mij moet je zo'n functie gewoon niet willen bouwen, omdat een verschil in maanden bijvoorbeeld zo weinig zegt. Dat kan zowel 28 als 31 dagen zijn.

Acties:
  • 0 Henk 'm!

  • KopjeThee
  • Registratie: Maart 2005
  • Niet online
Datums van elkaar aftrekken gaat volgens mij het gemakkelijkst als je de twee datums eerst omrekent naar juliaanse dagnummers. Als je die 2 dagnummers van elkaar aftrekt heb je het verschil in dagen. Verder omzetten naar jaren, maanden etc zou ik niet precies weten.

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Of je convert gewoon naar unix time?

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Hier staat hoe je het in Java zou kunnen doen: http://balusc.blogspot.co...chilTussenDatumsBerekenen
Grijze Vos schreef op zaterdag 24 november 2007 @ 22:40:
Of je convert gewoon naar unix time?
Hoe zou je zelf het aantal jaren, maanden en dagen uit het verschil halen? En ook nog rekening houden met de schrikkeldag/jaar/eeuw?

[ Voor 54% gewijzigd door BalusC op 24-11-2007 22:42 ]


Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 07-07 19:35
Daar houdt Unix time toch rekening mee?

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Thanx voor de reacties:
GlowMouse schreef op zaterdag 24 november 2007 @ 21:24:
Wat opmerkingen; de lijst is zeker niet compleet.
- De functienaam addSingleMultiple zegt zo weinig
- Je functie accepteert integers als datums, maar vervolgens ga je er toch vanuit dat het strings zijn.
- Je gebruikt vervolgens parseDateTime, wat geen standaard PHP-functie is, en ook nergens in je code gedefinieerd is. Strtotime lijkt me logischer, en gebruik je later in je functie wel.
- Zelfde als de vorige, maar nu adodb_date en date
addSingleMultiple staat erbij, daar zie je wat deze doet. De parameters hadden idd "varStart" of zoiets moeten heten, er kan zowel een int als een datum (NL/amerikaans) in, evenals een datetime field. Deze functie werkt met preg_match om te converteren naar de juiste Unix int. Adob_date is een functie voor PHP die het mogelijk maakt om met datums van voor 1970 te gaan rekenen, zelfs 1245 als je wilt. Deze heb ik ergens anders nodig gehad en zit sindsdien in mijn basecode.
GlowMouse schreef op zaterdag 24 november 2007 @ 21:24:
- Juiste berekeninggegevens pakken kan korter met min($intStart, $intEnd) en max($intStart, $intEnd)
Die volg ik niet helemaal...
GlowMouse schreef op zaterdag 24 november 2007 @ 21:24:
- Het stukje Negatieve waardes omvormen lijkt overbodig en kan geschrapt worden. In je commentaar zet je trouwens dat er iets niet klopt als dat stukje code toch nodig is; waarom retourneer je dan niet direct een foutmelding?
Een voorbeeld, als ik het verschil tussen 26-11-2007 en 27-11-2005 aftrek, geeft de functie als "jaren" 2, maar dat klopt niet, want het is 1 jaar en een beetje. Vandaar die extra slag
GlowMouse schreef op zaterdag 24 november 2007 @ 21:24:
- Totalsmonth check je op groter dan 11. Maar dit is het verschil tussen twee maanden, en is dus altijd kleiner dan of gelijk aan 12-1=11
Als het 12 maanden zou zijn, komt er een extra jaar bij. De eerste 2 waardes (jaar en maanden) is het totaal, en met deze manier haal ik van het totaal aantal maanden eerst (jaren*12) af, zodat dat wat er nog overblijft wel klopt.
GlowMouse schreef op zaterdag 24 november 2007 @ 21:24:
- De code gaat de fout in wanneer een dag 23 of 25 uren duurt (zomer-/wintertijd)
Waar zou je dit dan willen inbouwen? Ik weet wat je bedoeld, maar dat is wel heel erg :X :X om in te bouwen.... Tips?
GlowMouse schreef op zaterdag 24 november 2007 @ 21:24:
- Je commentaar Week/Dagen/Uren/Minuten/Seconden berekenen is wat over the top
- Volgens mij moet je zo'n functie gewoon niet willen bouwen, omdat een verschil in maanden bijvoorbeeld zo weinig zegt. Dat kan zowel 28 als 31 dagen zijn.
Eerste puntje ben ik het mee eens, het tweede puntje niet, maar dat is dan ook weer de uitdaging :D

Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
armageddon_2k1 schreef op zaterdag 24 november 2007 @ 23:15:
Daar houdt Unix time toch rekening mee?
Het verschil tussen 2 datums is idd niets anders dan 2 unix times van elkaar aftrekken, maar zet dat maar eens om naar jaren/maanden/weken etc. daar ligt (lag?) de uitdaging voor mij in dit systeem.

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

armageddon_2k1 schreef op zaterdag 24 november 2007 @ 23:15:
Daar houdt Unix time toch rekening mee?
Laat maar eens zien zonder dat je ze opnieuw naar een date converteert.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 23:29
xces schreef op zaterdag 24 november 2007 @ 23:20:
Het verschil tussen 2 datums is idd niets anders dan 2 unix times van elkaar aftrekken, maar zet dat maar eens om naar jaren/maanden/weken etc. daar ligt (lag?) de uitdaging voor mij in dit systeem.
date / mktime :?

* FragFrog mist waarschijnlijk iets, onder andere waarom je bestaande, goed werkende functies lijkt na te willen te maken?

[ Voor 21% gewijzigd door FragFrog op 24-11-2007 23:53 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
FragFrog schreef op zaterdag 24 november 2007 @ 23:49:
[...]

date / mktime :?

* FragFrog mist waarschijnlijk iets, onder andere waarom je bestaande, goed werkende functies lijkt na te willen te maken?
Troost je, daar ben je niet de enige in...

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

FragFrog schreef op zaterdag 24 november 2007 @ 23:49:
date / mktime :?

* FragFrog mist waarschijnlijk iets, onder andere waarom je bestaande, goed werkende functies lijkt na te willen te maken?
Edwardvb schreef op zondag 25 november 2007 @ 01:55:
Troost je, daar ben je niet de enige in...
Jullie missen inderdaad iets: het gaat over tijdsverschillen. Tussen 1 januari 2004 en 1 januari 2005 zit een andere hoeveelheid dagen dan tussen 1 januari 1970 en 1 januari 1971.

Functies met 1 datum (of unixtime) als argument (of berekeningen daarmee) kunnen per definitie geen oplossing voor dit probleem zijn, als het niet alleen om seconden, minuten, uren of dagen gaat, maar ook om weken en maanden (want in een jaar gaan per definitie 52 weken, maar geen 52 weken van 7 dagen!).

[ Voor 10% gewijzigd door Confusion op 26-11-2007 10:03 . Reden: Als het ook om maanden gaat ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Confusion schreef op zondag 25 november 2007 @ 03:29:

Jullie missen inderdaad iets: het gaat over tijdsverschillen. Tussen 1 januari 2004 en 1 januari 2005 zit een andere hoeveelheid dagen dan tussen 1 januari 2005 en 1 januari 2006.

Functies met 1 datum (of unixtime) als argument (of berekeningen daarmee) kunnen per definitie geen oplossing voor dit probleem zijn.
Waarom niet?

PHP:
1
2
3
4
5
6
7
<?php
echo mktime(0, 0, 0, 1, 1, 2006)-mktime(0, 0, 0, 1, 1, 2005);
echo "<BR>";
echo mktime(0, 0, 0, 1, 1, 2005)-mktime(0, 0, 0, 1, 1, 2004);
echo "<BR>";
echo mktime(0, 0, 0, 1, 1, 2004)-mktime(0, 0, 0, 1, 1, 2003);
?>


Geeft:

code:
1
2
3
31536000
31622400
31536000


Zoals je kan zien, is er rekening mee gehouden dat 2004 een schrikkel is, en is daarom langer in secondes, om precies te zijn 86400 secondes, wat een dag is.

offtopic:
Een mooier meervoud van datum is niet datums, maar data, zoals wel in het commentaar staat. Merkwaardig genoeg zegt vandale dat datums wel is toegestaan als alternatief kom ik net achter.

[ Voor 12% gewijzigd door Semyon op 25-11-2007 04:06 ]

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Snapt hier nog niemand dat het hier gaat over het verschil tussen datums in jaren, maanden, dagen, uren, minuten en seconden en niet over het verschil in seconden? :/

Het verschil tussen 1 januari 2008 en 1 maart 2008 is exact 2 maanden of 5184000 seconden. Het verschil tussen 1 maart 2008 en 1 mei 2008 is ook exact 2 maanden, maar wel 5266800 seconden. Je kunt het verschil in seconden niet zomaar omrekenen naar het juiste aantal dagen, maanden en jaren.

[ Voor 52% gewijzigd door BalusC op 25-11-2007 09:09 ]


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
BalusC schreef op zondag 25 november 2007 @ 09:02:
Snapt hier nog niemand dat het hier gaat over het verschil tussen datums in jaren, maanden, dagen, uren, minuten en seconden en niet over het verschil in seconden? :/

Het verschil tussen 1 januari 2008 en 1 maart 2008 is exact 2 maanden of 5184000 seconden. Het verschil tussen 1 maart 2008 en 1 mei 2008 is ook exact 2 maanden, maar wel 5266800 seconden. Je kunt het verschil in seconden niet zomaar omrekenen naar het juiste aantal dagen, maanden en jaren.
Je kan het uitstekend omrekenen. Ik heb zelf een keer zoiets in python gemaakt, met seconds als tussen resultaat. Geeft netjes alles in maanden, weken, dagen seconden, jaren eeuwen zonodig.

Het enige probleem is maanden, omdat die niet goed gedefineerd zijn. Meestal neemt men daarom dan maar gewoon 1/12 jaar.

Een voorbeeld.

30 Aug - 30 Sep precies 1 maand (?)

Wat hebben we dan voor
31 Aug naar 1 Nov
en 1 Sep naar 1 Nov?

Allebei 1 maand? of een van beide een dag?
Ergens loopt het spaak met maanden.

De maand is gewoon niet goed gedefinieerd. Je kan wel proberen slim te zijn, maar ergens krijg je rare dingen.

Zo ook voor een jaar. Voor een jaar zou ik gewoon een omwenden nemen en je bent van het schrikkel gezeur af.

Je kan gewoon niet precies zijn met slordige definities als maanden en jaren met of zonder schrikeldag.

De term "maand" heeft geen vaste tijdsduur. Het als zodanig te gebruiken (zeggen iets duurt 1 maand) lijkt wel slim maar is misbruik als je denkt erg precies te zijn.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15-07 22:01

Creepy

Tactical Espionage Splatterer

Oftewel: je hebt het gedaan met seconden als resultaat maar het aantal maanden en jaren klopt niet altijd. En dat is precies wat BalusC nu aangeeft. En bij zijn Java methode klopt dat dus allemaal wel ;)

En dan vergeet je volgens mij nog de uren/dagen op de dag dat de zomertijd naar wintertijd schakelt en terug. Dan zit er ineens 23 of 25 uur in een dag.

[ Voor 29% gewijzigd door Creepy op 25-11-2007 10:52 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Unixtime gebruiken voor datums voor 1970 is niet handig, zeker niet in PHP. Neem alleen maar het feit dat PHP onder windows dat gewoon weg niet kan.

Acties:
  • 0 Henk 'm!

  • Dutchmega
  • Registratie: September 2001
  • Niet online
Waarom altijd zo moeilijk?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function dateDiff($intStart, $intEnd)
{
    $maanden = 0;
    while( ($new = strtotime("+1 month", $intStart)) <= $intEnd )
    {
        $intStart = $new;
        $maanden++;
    }

    $dagen = 0;
    while( ($new = strtotime("+1 day", $intStart)) <= $intEnd )
    {
        $intStart = $new;
        $dagen++;
    }

    $uren = 0;
    while( ($new = strtotime("+1 hour", $intStart)) <= $intEnd )
    {
        $intStart = $new;
        $uren++;
    }

    $min = 0;
    while( ($new = strtotime("+1 min", $intStart)) <= $intEnd )
    {
        $intStart = $new;
        $min++;
    }

    return $maanden . " maanden, "  . $dagen . " dagen, " . $uren . " uren, " . $min . " minuten, " . ($intEnd - $intStart) . " seconden";
}

var_dump(dateDiff( strtotime("2007-10-26"), strtotime("2007-11-27") ));

Deze geeft netjes 1 dag aan, ook als wintertijd ingaat.

Als je strtotime() niet gebruikt, dan krijg je dingen zoals '23 uur' ipv een dag.

[ Voor 4% gewijzigd door Dutchmega op 25-11-2007 11:28 ]


Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Da's een nette :) Althans wel voor de jaren, maanden en dagen. Het is alleen een beetje dure operatie voor de tijd (uren, minuten en seconden). Deze kun je beter afleiden uit het verschil in (milli)seconden.

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 09-07 15:06
xces schreef op zaterdag 24 november 2007 @ 23:20:
[...]

Het verschil tussen 2 datums is idd niets anders dan 2 unix times van elkaar aftrekken, maar zet dat maar eens om naar jaren/maanden/weken etc. daar ligt (lag?) de uitdaging voor mij in dit systeem.
Ehhmm.. zoiets toch?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$start = "1983-01-18";
$eind = "2007-11-25";

define("SECONDEN_PER_JAAR", 31557600);
define("SECONDEN_PER_WEEK", 604800);
define("SECONDEN_PER_DAG", 86400);
define("SECONDEN_PER_UUR", 3600);
define("SECONDEN_PER_MINUUT", 60);

// Verschil in data in seconden
$verschilSec = strtotime($eind) - strtoime($start);

$verschilJaar = $verschilWeek = $verschilDag = $verschilUur = $verschilMinuut = 0;

while($verschilSec >= SECONDEN_PER_JAAR) {
   $verschilJaar++;
   $verschilSec -= SECONDEN_PER_JAAR;
}
while($verschilSec >= SECONDEN_PER_WEEK) {
   $verschilWeek++;
   $verschilSec -= SECONDEN_PER_WEEK;
}
while($verschilSec >= SECONDEN_PER_DAG) {
   $verschilDag++;
   $verschilSec -= SECONDEN_PER_DAG;
}
while($verschilSec >= SECONDEN_PER_UUR) {
   $verschilUur++;
   $verschilSec -= SECONDEN_PER_UUR;
}
while($verschilSec >= SECONDEN_PER_MINUUT) {
   $verschilMinuut++;
   $verschilSec -= SECONDEN_PER_MINUUT;
}

Acties:
  • 0 Henk 'm!

Anoniem: 60780

delete

[ Voor 99% gewijzigd door Anoniem: 60780 op 25-11-2007 12:17 . Reden: irrelevant voor topic starter (en ik moet beter lezen ;)) ]


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Creepy schreef op zondag 25 november 2007 @ 10:49:
Oftewel: je hebt het gedaan met seconden als resultaat maar het aantal maanden en jaren klopt niet altijd. En dat is precies wat BalusC nu aangeeft. En bij zijn Java methode klopt dat dus allemaal wel ;)

En dan vergeet je volgens mij nog de uren/dagen op de dag dat de zomertijd naar wintertijd schakelt en terug. Dan zit er ineens 23 of 25 uur in een dag.
Mijn argument is dat het zelfs nooit altijd kan kloppen.
Het theoretisch onmogelijk is, omdat de maand niet precies is:

Laten we het eens met optellen proberen.

30 Aug + 1 maand = 30 Sept
1 Sept + 1 maand = 1 Nov

wat is dan 31 Aug + 1 maand?

Als het 1 Nov is zijn er 2 data met het verschil van 1 maand naar de zelfde dag,

Hetzelfde als het naar 30 Sept is. Je hebt dus altijd 2 verschillende data met 1 precies maand verschil.
Beetje merkwaardig en tegen ons idee in van wat verschil is en wat precies is.

ALs je verschillen gaat uitrekenen kom je dus ook in de problemen met het trio 30 Aug, 30 Sept en 1 Nov, omdat 31 Sep niet betaat.

Precies rekenen met maanden is dus theoretisch niet mogelijk.
Met secondes wel, omdat die altijd even lang zijn.
Terug gaan naar seconds is dus zinvol. Wat je met maanden doet maakt allemaal niet zo uit, omdat je hoe dan ook problemen hebt.

Maar goed, als iedereen verder blij is dan mag het van mij ook zonder secondes :)

[ Voor 3% gewijzigd door Semyon op 25-11-2007 12:45 ]

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15-07 22:01

Creepy

Tactical Espionage Splatterer

Semyon schreef op zondag 25 november 2007 @ 12:44:
[...]


Mijn argument is dat het zelfs nooit altijd kan kloppen.
Het theoretisch onmogelijk is, omdat de maand niet precies is:

Laten we het eens met optellen proberen.

30 Aug + 1 maand = 30 Sept
1 Sept + 1 maand = 1 Nov

wat is dan 31 Aug + 1 maand?
1 oct. lijkt me, dat is namelijk de eerst volgende datum na 30 september (en dus precies ;) ).
Als het 1 Nov is zijn er 2 data met het verschil van 1 maand naar de zelfde dag,
Ik neem aan dat je 1 oct. bedoelt: Prima, maar dat is toch niet zo erg lijkt me?
Hetzelfde als het naar 30 Sept is. Je hebt dus altijd 2 verschillende data met 1 precies maand verschil.
Beetje merkwaardig en tegen ons idee in van wat verschil is en wat precies is.

ALs je verschillen gaat uitrekenen kom je dus ook in de problemen met het trio 30 Aug, 30 Sept en 1 Nov, omdat 31 Sep niet betaat.

Precies rekenen met maanden is dus theoretisch niet mogelijk.
Met secondes wel, omdat die altijd even lang zijn.
Terug gaan naar seconds is dus zinvol. Wat je met maanden doet maakt allemaal niet zo uit, omdat je hoe dan ook problemen hebt.

Maar goed, als iedereen verder blij is dan mag het van mij ook zonder secondes :)
Ik vind nog steeds precies. Het feit dat een 30 februari niet bestaat wil niet zeggen dat je niet precies kan rekenen, je moet alleen definieren wat je met een niet bestaande datum doet (wat mij betreft gewoon doorrekenen dus, iets wat Java bijv. automatisch voor je kan doen).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Creepy schreef op zondag 25 november 2007 @ 12:57:
[...]

1 oct. lijkt me, dat is namelijk de eerst volgende datum na 30 september (en dus precies ;) ).

[...]

Ik neem aan dat je 1 oct. bedoelt: Prima, maar dat is toch niet zo erg lijkt me?
Ja foutje.

NOu dan heb je dus

1 Okt - 31 August = 1 maand
1 Okt - 1 Sept = 1 maand.

Is niet erg, maar wel raar als je probeert precies te zijn.
Dat was eigenlijk mijn punt. Als je met maanden gaat rekenen moet je ergens af en toe een dag in smokkelen. Maakt niet zo uit of je dat er hier in smokkelt, of op die plaatsen waar het uitkomt als je terugrekent naar secondes.
Het ene is al voor je gedaan. En met een reden, dat ziet er namelijk logisch uit.

Maar goed, als de mensen het anders willen mag dat van mij. Ik had dat zo niet in de gaten, het lijkt mij persoonlijk erg onlogisch en omslachtig. Veel mensen hebben een ander idee van wat een period is, namelijk dat het altijd evenveel is. Je brengt mensen in verwarring als je probeert precies te zijn maar je smokkelt met dagen.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 23:48
frickY schreef op zondag 25 november 2007 @ 12:04:
[...]

Ehhmm.. zoiets toch?
PHP:
1
2
3
4
5
define("SECONDEN_PER_JAAR", 31557600);
define("SECONDEN_PER_WEEK", 604800);
define("SECONDEN_PER_DAG", 86400);
define("SECONDEN_PER_UUR", 3600);
define("SECONDEN_PER_MINUUT", 60);
Uhmm, hier ga je dus de fout in. Een dag bestaat niet altijd uit 86400 seconden, denk aan zomer/wintertijd, een jaar bestaat niet altijd uit 31557600 seconden, denk aan schrikkeljaren.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Semyon schreef op zondag 25 november 2007 @ 03:58:
Waarom niet?

PHP:
1
2
3
4
5
6
7
<?php
echo mktime(0, 0, 0, 1, 1, 2006)-mktime(0, 0, 0, 1, 1, 2005);
echo "<BR>";
echo mktime(0, 0, 0, 1, 1, 2005)-mktime(0, 0, 0, 1, 1, 2004);
echo "<BR>";
echo mktime(0, 0, 0, 1, 1, 2004)-mktime(0, 0, 0, 1, 1, 2003);
?>
Ja, maar daar gebruik je dus de '-' operator, wat in feite een functie-call is naar een functie die twee datums als argumenten heeft. Ik weet hoe het in Python werkt, maar ik wist niet dat er in PHP iets gelijksoortigs was (edit: hoewel daar blijkbaar nog discussie over is in dit topic :)) . Niettemin blijkt uit de reacties die ik citeerde niet dat ze dat bedoelden en anders hadden ze het wel even mogen toelichten, want het is verre van obvious dat het toepassen van de '-' operator op twee resultaten van de functie mktime (die er in alle opzichten uitzien als 64 bits integers) een tijdsverschil op zou leveren. Dat is bijvoorbeeld in Java en Python niet zo. Alle unix timestamps zijn daar 64 bits ints.

[ Voor 3% gewijzigd door Confusion op 25-11-2007 13:37 ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Confusion schreef op zondag 25 november 2007 @ 13:36:
[...]

Ja, maar daar gebruik je dus de '-' operator, wat in feite een functie-call is naar een functie die twee datums als argumenten heeft. Ik weet hoe het in Python werkt, maar ik wist niet dat er in PHP iets gelijksoortigs was (edit: hoewel daar blijkbaar nog discussie over is in dit topic :)) . Niettemin blijkt uit de reacties die ik citeerde niet dat ze dat bedoelden en anders hadden ze het wel even mogen toelichten, want het is verre van obvious dat het toepassen van de '-' operator op twee resultaten van de functie mktime (die er in alle opzichten uitzien als 64 bits integers) een tijdsverschil op zou leveren. Dat is bijvoorbeeld in Java en Python niet zo. Alle unix timestamps zijn daar 64 bits ints.
Iemand vraagt waarom men geen mktime gebruikt. Je zegt met veel woorden dat dat per definitie niet kan. Daarna beweer je dat het wel kan omdat de '-' operator gebruikt wordt? Het lijkt me dat je gewoon mktime kan gebruiken, hoewel je sterk leek de suggeren dat het per definitie niet kon.

De verdere onduidelijkheid over wat TS precies wil lijkt mij een probleem van specificatie. Wat wil hij precies?
Wil hij maanden soms langer laten duren dan anders? Zo ja, dan krijg je rare rand gevallen bij de dag dat je van 30 dagen naar 31 dagen switch, waar je die rand ook legt. Je hebt 2 verschillende data die allebei een maand verschil blijken te hebben met 1 enkele andere datum. Dat is onlogisch, maar als je dat wil kan dat wel. Ik den dat het onlogische hiervan veel mensen en mij op het verkeerde been hebben gezet als dat echt gewenst functionaliteit is.
Wil hij een maand altijd even lang laten duren? Dan is het coden van een bestaande functie, namelijk mktime levert het al voor je.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Semyon schreef op zondag 25 november 2007 @ 14:11:
Iemand vraagt waarom men geen mktime gebruikt. Je zegt met veel woorden dat dat per definitie niet kan. Daarna beweer je dat het wel kan omdat de '-' operator gebruikt wordt? Het lijkt me dat je gewoon mktime kan gebruiken, hoewel je sterk leek de suggeren dat het per definitie niet kon.
Als mktime 64 bits ints uitspuugt, kan je mktime per definitie niet gebruiken om een tijdsverschil om te rekenen naar de hoeveelheid verstreken dagen (in werkelijke tijd!). Als mktime een soort datetime-objecten uitspuugt dan is het wel mogelijk dat de '-' operator voor die objecten zo ge-overload is dat het de correcte hoeveelheid verstreken dagen oplevert. Zo is het in Python. Daar levert het verschil tussen twee datetime objecten je de werkelijke hoeveelheid verstreken dagen of weken of maanden, rekening houdende met schrikkeljaren, verschillende maandlengtes, etc.
De verdere onduidelijkheid over wat TS precies wil lijkt mij een probleem van specificatie. Wat wil hij precies? Wil hij maanden soms langer laten duren dan anders? Zo ja, dan krijg je rare rand gevallen bij de dag dat je van 30 dagen naar 31 dagen switch, waar je die rand ook legt.
Maanden hebben al verschillende duren: 28, 29, 30 of 31 dagen. Als je daar geen rekening mee houdt, dan gaan er bijvoorbeeld 73 maanden in 6 jaar. Dat is onzinnige informatie aan je gebruiker geven.
Semyon schreef op zondag 25 november 2007 @ 13:10:
[...]
NOu dan heb je dus

1 Okt - 31 August = 1 maand
1 Okt - 1 Sept = 1 maand.
Nee, natuurlijk niet. Tussen 1 oktober en 1 september zit 1 maand. Tussen 1 oktober en 31 augustus zitten 1 maand + 1 dag. Tussen 31 augustus en 1 september zit toch ook 1 dag? Dit soort informatie, rekening houdende met onze belachelijke kalender, is alleen relevant als je iemand vertelt hoeveel tijd er verstreken is ten opzichte van een bepaalde datum. Dat iemand aan de informatie '1 maand' niet kan zien hoeveel dagen er verstreken zijn, doet er helemaal niet toe; dat is een presentatiekeuze. De andere oplossing, iemand vertellen dat er 31 dagen verstreken zijn, vertelt iemand weer niet of het project precies 1 maand duurde of dat het misschien een maand + 1 dag duurde. Je kan niet vooraf een voorkeur aan een van beide geven. Maar dan maar besluiten dat alle maanden 30 dagen duren leidt tot informatie die vanaf beide kanten niet klopt.

[ Voor 34% gewijzigd door Confusion op 26-11-2007 10:04 ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Is de volgende werkwijze wellicht de oplossing:

Wanneer de data 12-02-2007 en 13-08-2005 worden gegeven:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    $jaar_verschil      = $jaar1 - $jaar2   //geeft 2 jaren
    $maand_verschil     = $maand1 - $maand2 //geeft -6 maanden
    
    if($maand_verschil < 0){
        $jaar_verschil  = $jaarverschil - 1;    // 1 jaar
        $maand_verschil = $maand_verschil + 12; // 6 maanden
    }

    if(($dag1 - $dag2) < 0){
        $maand_verschil     = $maand_verschil - 1   // 5 maanden
        $dagen_einde_maand  = $dagen_per_maand[$maand2] - $dag2 + $dag1 // 30 dagen
    }
    else{
        $dag_verschil   = $dag1 - $dag2;
    }
//Geeft uiteindelijk 1 jaar, 5 maanden en 30 dagen aan


Het enige tricky hieraan is dat je het aantal dagen in de maanden goed neer moet zetten. Februari zal hier uiteraard irritant gaan doen, maar het is natuurlijk wel uit te werken. volledige uitleg

Het werkt een beetje met het lenen systeem zoals we vroeger op de basisschool hebben leren aftrekken. Wanneer het aantal maanden te groot is lenen we een jaartje etc.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 23:29
Confusion schreef op zondag 25 november 2007 @ 03:29:
Jullie missen inderdaad iets: het gaat over tijdsverschillen. Tussen 1 januari 2004 en 1 januari 2005 zit een andere hoeveelheid dagen dan tussen 1 januari 2005 en 1 januari 2006.

Functies met 1 datum (of unixtime) als argument (of berekeningen daarmee) kunnen per definitie geen oplossing voor dit probleem zijn.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function compare($lowerDate, $higherDate) {
    $dateDifference = $higherDate - $lowerDate;
    $years = date('o', $dateDifference) - 1970;
    echo     $years . " jaar, " 
             . date('n', $dateDifference) . ' maanden, '
             . date('j', $dateDifference) . ' dagen, '
             . date('G', $dateDifference) . ' uur, '
             . date('i', $dateDifference) . ' minuten '
             . date('s', $dateDifference) . ' seconden.';
}

compare(strtotime('24-11-2007, 12:14'), strtotime('15-5-2009, 16:11'));

// Resultaat: 1 jaar, 6 maanden, 23 dagen, 3 uur, 57 minuten 00 seconden.


En nee, het is niet 100% correct aangezien de maandlengtes vanaf het unix epoch gebruikt worden. Maar het gaat hier om een textuele representatie bedoeld voor een gebruiker, het is in mijn opinie dan onzin om voor die extra nauwkeurigheid 116 regels code te gebruiken als het ook in 10 kan - zoals hierboven al vermeld, het is toch nooit helemaal correct tenzij je echt met alle mogelijke situaties rekening gaat houden.

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

FragFrog schreef op zondag 25 november 2007 @ 15:11:
En nee, het is niet 100% correct aangezien de maandlengtes vanaf het unix epoch gebruikt worden. Maar het gaat hier om een textuele representatie bedoeld voor een gebruiker, het is in mijn opinie dan onzin om voor die extra nauwkeurigheid 116 regels code te gebruiken als het ook in 10 kan - zoals hierboven al vermeld, het is toch nooit helemaal correct tenzij je echt met alle mogelijke situaties rekening gaat houden.
Juist, dus jij, PHP professional for hire, gaat je opdrachtgever een UI presenteren waarin een tijdverschil staat en er staat: '6 jaar'. Hij selecteert 'maanden' en het worden '73 maanden'. Daarna ben je je opdracht kwijt, omdat je blijkbaar niet kan uitrekenen hoeveel tijd er sinds het starten van een bepaalde activiteit verstreken is en de opbrengst per maand daarom ook afwijkt van de opbrengst die de accountant rapporteert. ;)

[ Voor 8% gewijzigd door Confusion op 26-11-2007 10:01 . Reden: Dagen kloppen natuurlijk wel op grond van een tijdsverschil ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • imp4ct
  • Registratie: November 2003
  • Laatst online: 07-07 17:24
Erkens schreef op zondag 25 november 2007 @ 11:13:
Unixtime gebruiken voor datums voor 1970 is niet handig, zeker niet in PHP. Neem alleen maar het feit dat PHP onder windows dat gewoon weg niet kan.
Unixtime voor 1970 kan perfect...

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//dd-mm-yyyy
//script that get's a timestamp from a forwarded date
//this script can be used also for dates before 1970
function print_unixtimestamp_ddmmyyyy($date)
{
  if(!empty($date))
  {
    $day = substr($date,0,2);
    $month = substr($date,3,2);
    $year = substr($date,6,4);
    $hour = 21;
    $minute = 59;
    $second = 59;
      
    if ( $year > 1969 )
    {
      return(gmmktime($hour,$minute,$second,$month,$day,$year));
    }
  
    $t = 0;
    $ds = 86400;
    $hs = 3600;
    $dy = 365;
    $ms = 60;
  
    $months = array ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
    $leap_year = $year % 4 == 0 && ( $year % 100 > 0 || $year % 400 == 0 ) ? true : false;
  
    if ( $year < 1969 )
    {
      $y = 1969 - $year;
      $t -= ( $y * $dy ) * $ds;
      $x = ceil ( $y / 4 );
  
      if ( $leap_year && $month > 2 )
      {
        $x -= 1;
      }
  
      $t -= $x * $ds;
    }
  
    if ( $month != 12 )
    {
      $tm = $months;
      $tm = array_slice ($tm,$month);
      $t -= array_sum ($tm) * $ds;
      unset($tm);
    }
  
    $nh = (($month == 2 && $leap_year ? 29 : $months[$month-1] ) - $day);
    $t -= $nh != 0 ? $nh * $ds : 0;
    $nh = 23 - $hour;
    $t -= $nh != 0 ? $nh * $hs : 0;
    $nh = 59 - $minute;
    $t -= $nh != 0 ? $nh * $ms : 0;
    $nh = 59 - $second;
    $t -= $nh != 0 ? $nh + 1 : 0;
      
    return($t);
  }
}

Bedrijf : Webtrix

Foto materiaal:
Nikon D7100 | Nikor AF-S DX 18-105mm | Nikor AF-S 50mm | Nikon SB600


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

imp4ct schreef op zondag 25 november 2007 @ 16:27:
Unixtime voor 1970 kan perfect...
Natuurlijk kan het wel, alleen niet met standaard PHP zoals jouw script al laat zien ;)
Daarnaast is weergave van een datum en ermee rekenen toch wel iets anders.

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

code:
1
? true : false
Dat gedeelte kan wel weg, is onnodig bij een expressie die zelf al een boolean retourneert.

[ Voor 3% gewijzigd door BalusC op 25-11-2007 18:05 ]


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Confusion schreef op zondag 25 november 2007 @ 14:36:
[...]
Nee, natuurlijk niet. Tussen 1 oktober en 1 september zit 1 maand. Tussen 1 oktober en 31 augustus zitten 1 maand + 1 dag. Tussen 31 augustus en 1 september zit toch ook 1 dag? Dit soort informatie, rekening houdende met onze belachelijke kalender, is alleen relevant als je iemand vertelt hoeveel tijd er verstreken is ten opzichte van een bepaalde datum. Dat iemand aan de informatie '1 maand' niet kan zien hoeveel dagen er verstreken zijn, doet er helemaal niet toe; dat is een presentatiekeuze. De andere oplossing, iemand vertellen dat er 31 dagen verstreken zijn, vertelt iemand weer niet of het project precies 1 maand duurde of dat het misschien een maand + 1 dag duurde. Je kan niet vooraf een voorkeur aan een van beide geven. Maar dan maar besluiten dat alle maanden 30 dagen duren leidt tot informatie die vanaf beide kanten niet klopt.
Als er 1 maand en 1 dag tussen zit is dat goed, maar dat krijg je het probleem ergens anders

Laten we het extreme voorbeeld van Februari nemen.

code:
1
2
28 Jan tot 28 Feb is 1 Maand
28 Jan tot 1 Maart is dus 1 Maand en 1 Dag


Wat nu met

code:
1
2
3
29 Jan tot 1 Maart
30 Jan tot 1 Maart
31 Jan tot 1 Maart


Allemaal maar 1 Maand en 1 dag? 4 Periodes van verschillende lengte allemaal maar aangeven met dezelfde tijdsduur?
Het moet allemaal langer dan een maand zijn (intuitief) maar de periode moet ook steeds korter worden... Je loopt spaak.

Het is allemaal een ellende...

Omdat je maandlengte niet gedefineerd is voor periodes die niet op de 1e beginnen, ga je hoe dan ook problemen krijgen. 31 Periodes mappen naar 30 Periodes in een andere maand allemaal met de term 1 Maand, is ergens een dubbele incasseren.
Nog erger, als je uren meerekent, kan je periodes krijgen als "1 Maand 1 Dag en 1 uur", die langer lijkt maar in feite naar een kortere tijdsduur gaat dan "1 Maand 1 Dag" op een andere dag

Dikke ellende allemaal, je komt er niet uit.

BTW Creepy @ 12:57 stelde voor om 1 Okt - 31 Aug precies 1 maand te noemen, het was niet mijn idee.
Wat is anders precies 1 maand vanaf 31 Aug? Of kan dat niet?

En dan hebben we de meta discussie:
Want het lijkt dat we nu al 3 verschillende ideeen hebben, Confusion, Creepy en ik. En dat weet ik nog niet eens wat TS wil. Intuitief is het allemaal niet, niemand weet meer wat je bedoelt. Je kan niet precies zijn met periodes waarvan je niet kan bepalen hoe lang die zijn.

Dat 1/12 Jaar=1 Maand leidt tot verkeerde informatie is waar, maar het leidt wel tot consistentie. Wat confusion wil (?) of TS wil (?) is me nog niet helemaal duidelijk maar is informatie die ook niet klopt en niet consistent is.

[ Voor 53% gewijzigd door Semyon op 26-11-2007 04:46 . Reden: 1) Voorbeeld fix 2) Spelling 3) Voorbeeld fix ]

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Semyon schreef op zondag 25 november 2007 @ 22:49:
4 Periodes van verschillende lengte allemaal maar aangeven met dezelfde tijdsduur?
Ja. Dat is namelijk normaal, aangezien iedereen het woord 'maand' gebruikt voor perioden met een verschillende tijdsduur. Mensen die met het woord 'maand' altijd een periode van dertig dagen bedoelen, die zijn raar. Dat gaan de werknemers van je opdrachtgever die met het systeem werken nooit snappen.

Als het anders is, dan moet je je opdrachtgever vertellen dat het niet zinvol is bepaalde data in maanden te presenteren. Dat zal ook vaak het geval zijn. Dan wil iemand bijvoorbeeld het aantal verstreken dagen weten. En dan zal je toch echt rekening moeten houden met het daadwerkelijk aantal verstreken dagen en niet doen alsof dezelfde periode sinds 1 jan. 1970 verstreken is, waardoor je een verkeerd aantal dagen rapporteert (wat niet gebeurt als je het tijdsverschil in milliseconden als basis neemt, maar welk risico wel bestaat als je tegerlijktijd in je code ook 'tijdsverschillen in maanden van 30 dagen' rond hebt hangen).

[ Voor 39% gewijzigd door Confusion op 26-11-2007 09:56 ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
@semyon

van 28 januari t/m 1 maart kan ook worden gezien als 1 maand en 3 dagen. Immers het kost 3 dagen om tot 1 februari te komen en dan nog eens 1 maand om tot 1 maart te komen.

Deze wijze van rekenen is wel behoorlijk consistent. Hierbij maak je ten alle tijde gebruik van het feit dat een maand niet perse 30,5 dag is. Je gaat eerst naar het einde van de maand, dan naar de goede maand, dan naar het goede jaar om vervolgens nog eens te tellen hoeveel dagen je nodig hebt om naar de goede dag toe te komen.

Naar mijn mening zit tussen 28 januari en 1 maart namelijk de maand februari die voor die ene maand zorgt en de drie dagen die naar februari toe gaan. En niet de maand die in één keer naar 28 februari toe gaat. maar dit is natuurlijk behoorlijk subjectief, echter denk ik wel de methode om goede consistente informatie te geven

Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Rainmaker1987 schreef op maandag 26 november 2007 @ 09:00:
@semyon

van 28 januari t/m 1 maart kan ook worden gezien als 1 maand en 3 dagen. Immers het kost 3 dagen om tot 1 februari te komen en dan nog eens 1 maand om tot 1 maart te komen.

Deze wijze van rekenen is wel behoorlijk consistent. Hierbij maak je ten alle tijde gebruik van het feit dat een maand niet perse 30,5 dag is. Je gaat eerst naar het einde van de maand, dan naar de goede maand, dan naar het goede jaar om vervolgens nog eens te tellen hoeveel dagen je nodig hebt om naar de goede dag toe te komen.
Ook dit schema is in mijn ogen een drama:

Dan krijg je dat "1 Maand 2 dagen" korter duurt dan "1 Maand"

code:
1
2
3
4
28 Jan -> 28 Feb (1 Maand) 
28 Jan -> 1 Maart (1 Maand 4 dagen)
29 Jan -> 1 Maart (1 Maand 3 dagen)
30 Jan -> 1 Maart (1 Maand 2 dagen)


regel 4 "1 maand 2 dagen" is korter dan "1 maand" van regel 1.

en hier wat ongedefinieerd:

code:
1
2
3
4
5
6
7
28 Feb -> 28 maart (1 Maand)

28 Feb -> 29 maart 
28 Feb -> 30 maart 
28 Feb -> 31 maart 

28 Feb -> 1 April (1 Maand 1 dag)


volgen we jouw oplossing dan gaan we:
met regel 3 bijv eerst einde maand (1 dag) en we zitten op 1 maart en nog wat? 29 dagen? Dus dit noemen we 30 dagen?

Dan krijgen we voor elke keer oplopende tijdsduur van 1 dag: "1 Maand 0 dagen", "30 dagen", "31 dagen", "32 dagen" (allemaal maand vrij... 32 dagen toch maand vrij??) , "1 Maand 1 dag"?

en waarom gaan we met regel 1 eigenlijk niet eerst naar einde maand (1 dag) en dan nog 28 dagen = 29 dagen?
Dus regel 1 mag eigenlijk ook geen "1 Maand" genoemd worden.

ook deze oplossing loopt raar. Elke oplossing volgens mij, omdat je het gewoon niet kan mappen, lijkt me.

Verder kunnen we hier nog een 4e oplossing zien, wat op mijn meta-theorie bouwt dat het allemaal tegen intuitief is en iedereen het anders interpreteert. Ik vermoed dat het tegen enorme problem gaat lopen in de praktijk omdat iedereen z'n eigen idee heeft van hoe een tijdsduur te intepreteren... Nu hebben we dus al een Creepy, Confusion, Rainmaker en mijn idee en allemaal anders hoe de tijd werkt... Om van TS nog maar niet te spreken?

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Semyon schreef op maandag 26 november 2007 @ 09:47:
Dan krijg je dat "1 Maand 2 dagen" korter duurt dan "1 Maand"
En dat is heel normaal. Als ik een willekeurig persoon op straat vraag "Kan het zijn dat '1 maand + 2 dagen' korter duurt dan '1maand', dan zullen ze zeggen: "Ja, als de eerste maand februari is en de tweede maand een maand van 31 dagen'.

Hoe in vredesnaam kan je het raar vinden dat '1 maand' soms korter duurt dan '1 maand'? Als iemand zegt '1maand', zonder context, dan is de vraag 'welke maand'?

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Confusion schreef op maandag 26 november 2007 @ 10:00:
[...]

En dat is heel normaal. Als ik een willekeurig persoon op straat vraag "Kan het zijn dat '1 maand + 2 dagen' korter duurt dan '1maand', dan zullen ze zeggen: "Ja, als de eerste maand februari is en de tweede maand een maand van 31 dagen'.

Hoe in vredesnaam kan je het raar vinden dat '1 maand' soms korter duurt dan '1 maand'? Als iemand zegt '1maand', zonder context, dan is de vraag 'welke maand'?
Nou 1 een lopende reeks (context) vind ik dat nog steed raar...

plus 4 dagen zijn niet gedefineerd, want of

1) 28 Feb - 28 Maart is geen 1 Maand

de regel is:
Einde maand (1 dag)
dan nog wat dagen, misschien weekend.
Eind resultaat is geen maand.

of

2) 28 Feb - 28 Maart is wel een maand, maar dan gaat de genoemde regel niet op en is 28 Feb - 29 Maart ongedefineerd. (als we weer eerst de maand gaan doen en dan dagen lopen we in de problemen met mijn eerdere post)

Deze regel werkt volgens mij ook niet.

maar goed. Als iemand een webdemo heeft met een implementatie wil ik er wel eens graag naar kijken. Ik ben erg benieuwd of iemand een definitie heeft die en alles definieerd en nooit 2 zelfde periodes met verschillende tijds naar de zelfde eindtijd mapt.

Ik houd nu op met tegen voorbeelden te bedenken...

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Zodra ik het heb over volgende of volgende maand dan boeit de exacte datum opzich niet. Dus als ik op 28 februari 2007 zeg dat ik volgende maand "iets" ga doen dan kan dat dus zijn ergens tussen 1 en 31 maart.

Dat is natuurlijk niet handig om te berekenen, maar hieruit kan je wel concluderen dat als de exacte datum niet boeiend is, dan mag je dus ook zeggen dat 28 feb 2007 + 1 maand = 28 t/m 31 maart.

Bij dit soort weergaves van tijd boeit het niet hoe nauwkeurig het is, als je nauwkeurigheid wilt moet je een andere notatie gebruiken.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Wat een gezever, een maand is een wat groter/ruimer begrip, dus qua significantie is het blijkbaar niet boeiend of het 30 of 31 dagen was als gebruiker om een aantal maanden vraagt. :z En als het wel exact moet, vraagt gebruiker wel om een notatie met exacte eenheden (resp. wijs je de klant erop dat een andere eenheid beter is).

{signature}


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Erkens schreef op maandag 26 november 2007 @ 10:33:
Zodra ik het heb over volgende of volgende maand dan boeit de exacte datum opzich niet. Dus als ik op 28 februari 2007 zeg dat ik volgende maand "iets" ga doen dan kan dat dus zijn ergens tussen 1 en 31 maart.

Dat is natuurlijk niet handig om te berekenen, maar hieruit kan je wel concluderen dat als de exacte datum niet boeiend is, dan mag je dus ook zeggen dat 28 feb 2007 + 1 maand = 28 t/m 31 maart.

Bij dit soort weergaves van tijd boeit het niet hoe nauwkeurig het is, als je nauwkeurigheid wilt moet je een andere notatie gebruiken.
Van de topic start:
"3 jaar, 4 maanden, 3 weken, 2 dagen, 2 uur, 33 minuten en 2 seconden"
ik zie hier 2 seconden nauwkeurig voor een periode van over een jaar... Mijn hele punt is dat het met deze aanduiding niet kan... Nogmaals: "man die zegt dat het niet kan, moet man die probeert niet tegenhouden" :) als iemand een online oplossing heeft, zou ik dat heel graag willen zien en hier wat resultaten van posten.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Nu online
Perl heeft de DateTime module. Daar staat een implementatie welke volgens mij niet al te lastig naar PHP te porten is. Of eventueel een klein shell scriptje te maken die je vanuit PHP aanroept.

Deze geeft een date diff in maanden, dagen, uren, minuten en seconden welke IMHO voldoet aan de TS.

Acties:
  • 0 Henk 'm!

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Ik ben maar even bezig geweest (eigenlijk tentamens leren, maar hij was zo leuk om te doen) Met mijn implementatie krijg je de volgende uitwerking: http://tweakers.wikichess.net/tweakers.php

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
include('datum_check.php');
    function mysql_datum($mysql_datum){
        list($dag, $maand, $jaar) = split('[/-]', $mysql_datum);
        $mysql_datum = array($jaar, $maand, $dag);
        return $mysql_datum;
    }

    function dagen_per_maand($datum){
        if($datum['1'] != 2){
            $dagen  = array('','01' => '31','','02' => '31','03' => '30','04' => '31','05' => '30','06' => '31','07' => '31','08' => '30','09' => '31','30','31');
            $dagen  = $dagen[$datum['1']];
        }
        else{
            $dagen  = 28;
            if(($datum['0'] % 4) == 0){
                $dagen = 29;    
            }
            if(($datum['0'] % 100) == 0){
                $dagen = 28;    
            }
            if(($datum['0'] % 400) == 0){
                $dagen = 29;    
            }
        }
        return $dagen;
    }
    
    $datum1 = mysql_datum($_POST['datum1']);
    $datum2 = mysql_datum($_POST['datum2']);

    $jaar_verschil        = $datum1['0'] - $datum2['0'];    
    $maand_verschil        = $datum1['1'] - $datum2['1'];    
     
    if($maand_verschil < 0){ 
        $jaar_verschil    = $jaar_verschil - 1;    
        $maand_verschil    = $maand_verschil + 12;    
    } 

    if(($datum1['2'] - $datum2['2']) < 0){ 
        $maand_verschil        = $maand_verschil - 1 ;   
        $aantal_dagen_per_maand = dagen_per_maand($datum2);
        $dag_verschil    = $aantal_dagen_per_maand - $datum2['2'] + $datum1['2'];     
    } 
    else{ 
        $dag_verschil    = $datum1['2'] - $datum2['2']; 
    } 
    
    echo "Het verschil tussen ".$_POST['datum1']." en ".$_POST['datum2']." is: ".$jaar_verschil." jaar, ".$maand_verschil." maand(en) en ".$dag_verschil." dag(en)";


waarbij datum_check.php alleen maar zorgt voor de juiste invoer methode in de velden. Foutmeldingen staan nu nog aan maar heeft geen invloed op de uitslag.

Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Volgens mij kan het ook mbv deze code:


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function DateDifference($newDate, $oldDate) {

    $newDay = date('d',$newDate);
    $newMonth = date('m',$newDate);
    $newYear = date('Y',$newDate);
    $oldDay = date('d',$oldDate);
    $oldMonth = date('m',$oldDate);
    $oldYear = date('Y',$oldDate);
    $daysInMonth = date('d', mktime(0, 0, 0, $oldMonth+1, 0, $oldYear));

    $substractExtraMonth = 0;
    $substractExtraYear = 0;

    
    if ($newDay < $oldDay) {
        $dayDiff = $newDay - $oldDay + $daysInMonth;
        $substractExtraMonth = 1;
    } else {
        $dayDiff = $newDay - $oldDay;
    }
    
    if ($newMonth < $oldMonth + $substractExtraMonth) {
        $monthDiff = $newMonth - $oldMonth - $substractExtraMonth + 12 ;
        $substractExtraYear = 1;
    } else {
        $monthDiff = $newMonth - $oldMonth - $substractExtraMonth;
    }
    
    $yearDiff = $newYear - $oldYear - $substractExtraYear;
    
    echo "Tussen ".date("d F Y", $oldDate)." en ".date("d F Y", $newDate)." zit ".$dayDiff." dag(en) en ".$monthDiff." maand(en) en ".$yearDiff. "jaar.";
    
}


Ik bereken eerst het verschil in dagen. Is dat negatief dan tel je het aantal dagen van de "oude" maand erbij op.

Vervolgens bereken je het verschil in maanden. Trek daar evt 1 extra maand vanaf als de uitkomst van de dagen negatief was. Is deze uitkomst negatief; tel er 12 maanden bij op.

UIteindelijk bereken je het verschil in jaren. En als de uitkomst van de maanden negaief was, trek er een extra jaar vanaf.


Deze functie lijkt mij vrij eenvoudig en houdt rekening met schrikkeljaren e.d.
Het enige waarbij ik bij het schrijven van de functie geen rekening heb gehouden, is wat er gebeurt als de "oude" datum later is dan de "nieuwe" datum.

de functie geeft als output iets als:

code:
1
Tussen 27 February 1992 en 03 January 1997 zit 5 dag(en) en 10 maand(en) en 4jaar.



Edit:

even als reactie op Rainmaker1987: Jouw functie Dagen_Per_Maand kan je vrij eenvoudig vervangen door:

PHP:
1
$daysInMonth = date('d', mktime(0, 0, 0, $oldMonth+1, 0, $oldYear));


Bijvoorbeeld de datum 0 mrt 2004 wordt geinterpreteerd als 29-Feb-2004. Dan is het natuurlijk nog een eitje om dan het aantal dagen per maand te krijgen :P

[ Voor 9% gewijzigd door Zip McOccup op 26-11-2007 11:22 ]


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Rainmaker1987 schreef op maandag 26 november 2007 @ 11:02:
Ik ben maar even bezig geweest (eigenlijk tentamens leren, maar hij was zo leuk om te doen) Met mijn implementatie krijg je de volgende uitwerking: http://tweakers.wikichess.net/tweakers.php
Misschien ligt het aan mij (of aan firefox/linux), maar ik krijg geen 4 jarige jaar ingevoerd (het haalt de laatst telkens weg) als ik 07 gebruik, krijg ik bij veld 2 geen 2 cijferige jaar (ja de laagste is de laagste datum)

Ik ben erg benieuwd, kan je de check op correctheid weghalen zodat ik gewoon wat kan typen? Of kan ik het op de url meegeven aan datum1 ofzo?

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Semyon schreef op maandag 26 november 2007 @ 11:34:
[...]


Misschien ligt het aan mij (of aan firefox/linux), maar ik krijg geen 4 jarige jaar ingevoerd (het haalt de laatst telkens weg) als ik 07 gebruik, krijg ik bij veld 2 geen 2 cijferige jaar (ja de laagste is de laagste datum)

Ik ben erg benieuwd, kan je de check op correctheid weghalen zodat ik gewoon wat kan typen? Of kan ik het op de url meegeven aan datum1 ofzo?
Probleem ligt inderdaad bij firefox. In IE geeft het geen problemen. Voor de omgeving waarin ik het nogmaal gesproken gebruik is het geen enkel probleem, maar zal er toch maar eens naar kijken. (overigens heb ik dat script niet zelf geschreven)

Er zijn nu twee velden toegevoegd, wanneer die gebruikt worden worden de velden daarboven overschreven

@McOccup
je hebt natuurlijk helemaal gelijk. Ik ben braaf van de mathematische regels van het schrikkeljaar uitgegaan, maar die van jou is een stuk makkelijker.

[ Voor 7% gewijzigd door Rainmaker1987 op 26-11-2007 11:43 ]


Acties:
  • 0 Henk 'm!

  • sopsop
  • Registratie: Januari 2002
  • Laatst online: 08:37

sopsop

[v] [;,,;] [v]

Ik zou dat toch met de beschikbare functies doen, in pseude-code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
sRetStr = ""

iDiffYears = DateDiff(Year,EndDate,StartDate)
sRetStr += iDiffYears + " jaar, "
StartDate = DateAdd(Year,StartDate,iDiffYears)

iDiffMonths = DateDiff(Month,EndDate,StartDate)
sRetStr += iDiffMonths + " maanden, "
StartDate = DateAdd(Month,StartDate,iDiffMonths)

iDiffWeeks = DateDiff(Week,EndDate,StartDate)
sRetStr += iDiffWeeks + " weken, "
StartDate = DateAdd(Week,StartDate,iDiffWeeks)

iDiffDays = DateDiff(Days,EndDate,StartDate)
sRetStr += iDiffDays + " dagen, "
StartDate = DateAdd(Day,StartDate,iDiffDays)

iDiffHours = DateDiff(Hour,EndDate,StartDate)
sRetStr += iDiffHours + " uur, "
StartDate = DateAdd(Hour,StartDate,iDiffHours)

iDiffMinutes = DateDiff(Minute,EndDate,StartDate)
sRetStr += iDiffMinutes + " minuten, "
StartDate = DateAdd(Minute,StartDate,iDiffMinutes)

iDiffSeconds = DateDiff(Second,EndDate,StartDate)
sRetStr += iDiffSeconds + " seconden, "

Print sRetStr

Hierbij ga ik er vanuit uit de returnvalue van datediff altijd een geheel (naar beneden afgerond) getal is.

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Confusion schreef op zondag 25 november 2007 @ 16:00:
[...]

Juist, dus jij, PHP professional for hire, gaat je opdrachtgever een UI presenteren waarin een tijdverschil staat en er staat: '6 jaar'. Hij selecteert 'maanden' en het worden '73 maanden'. Daarna ben je je opdracht kwijt, omdat je blijkbaar niet kan uitrekenen hoeveel tijd er sinds het starten van een bepaalde activiteit verstreken is en de opbrengst per maand daarom ook afwijkt van de opbrengst die de accountant rapporteert. ;)
Nofi, maar dat is gewoon onzin. Waar dit soort data daadwerkelijk van belang is (accountancy e.d.) daar zijn dit soort begrippen gewoon goed gedefinieerd. Uit mijn blote hoofd (economie 2 is toch weer 8 jaar geleden), is een jaar gewoon 360 dagen, en een maand gewoon 30 dagen, punt uit. (Ik geloof dat banken tegenwoordig rente wel over 365 dagen berekenen, maar goed.)

Feit blijft dat het hier dus gewoon goed gedefinieerd is, en als je op een agende o.i.d. (dat is hier de toepassing, neem ik aan) wilt zetten dat de volgende afspraak gepland is "over 1 maand, 2 weken, 3 dagen en, 8 uur, 30 minuten en 6 seconden"; dan wil je misschien eens nadenken over waarom je die data zo wilt neer zetten, want je gebruiker heeft dan minstens even veel aan "over anderhalve maand."

M.a.w. gebruik gewoon de simpele variant 1 maand = 1/12 jaar, dan krijg je prima approximaties die je in de tijdsverschil-representatie van je applicatie kunt gebruiken.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 10-07 15:04
Boekhoudkundig wordt ook wel gerekend met perioden van 4 weken (13 in een jaar). Ook salarisbetalingen worden daar vaak op gebaseerd (ze worden wel per maand uitbetaald; maar de 13e maand is dus eigenlijk het bedrag van die laatste keer 4 weken dat je nog moet krijgen).

Blijf je trouwens nog wel met het probleem van de schrikkeljaren zitten...

Feit blijft dat '1 maand' niet is gedefinieerd, en dat je een bepaalde tijdspanne nooit kan uitdrukken in maanden. (wat dacht je van 0,6 maanden, hoe lang is dat dan).

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
mocean schreef op maandag 26 november 2007 @ 13:00:
(wat dacht je van 0,6 maanden, hoe lang is dat dan).
Op mijn "kalender", twee-drie weken, of gewoon een halve maand.

[ Voor 6% gewijzigd door Grijze Vos op 26-11-2007 13:26 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Rainmaker1987 schreef op maandag 26 november 2007 @ 11:38:
[...]

Probleem ligt inderdaad bij firefox. In IE geeft het geen problemen. Voor de omgeving waarin ik het nogmaal gesproken gebruik is het geen enkel probleem, maar zal er toch maar eens naar kijken. (overigens heb ik dat script niet zelf geschreven)

Er zijn nu twee velden toegevoegd, wanneer die gebruikt worden worden de velden daarboven overschreven
Het werkt nu...

Maar er is weer een fout:

31/08/2007 naar 01/10/2007 is precies 1 maand
zo ook
01/09/2007 naar 01/10/2007 is ook precies 1 maand.

vanaf 01/10/2007 zijn er blijkbaar 2 periodes van precies 1 maand die niet even lang duren.

offtopic:
Ik woon in een andere tijdzone en moet zo gaan slapen :) Als er weer een oplossing is, test ik die graag. Ik twijfel nog steeds zeer aan de haalbaarheid van precieze

[ Voor 19% gewijzigd door Semyon op 26-11-2007 13:28 ]

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Erm, dude... Mijn oplossing geeft:

code:
1
2
Tussen 31 August 2007 en 01 October 2007 zit 1 dag(en) en 1 maand(en) en 0 jaar.
Tussen 01 September 2007 en 01 October 2007 zit 0 dag(en) en 1 maand(en) en 0 jaar.

Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Zip McOccup schreef op maandag 26 november 2007 @ 13:43:
Erm, dude... Mijn oplossing geeft:

code:
1
2
Tussen 31 August 2007 en 01 October 2007 zit 1 dag(en) en 1 maand(en) en 0 jaar.
Tussen 01 September 2007 en 01 October 2007 zit 0 dag(en) en 1 maand(en) en 0 jaar.
Als je daar een webdemo van maakt (of heb ik de url gemist?) dan wil ook wel even naar jouw oplossing kijken.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Grijze Vos schreef op maandag 26 november 2007 @ 12:46:
Nofi, maar dat is gewoon onzin. Waar dit soort data daadwerkelijk van belang is (accountancy e.d.) daar zijn dit soort begrippen gewoon goed gedefinieerd. Uit mijn blote hoofd (economie 2 is toch weer 8 jaar geleden), is een jaar gewoon 360 dagen, en een maand gewoon 30 dagen, punt uit. (Ik geloof dat banken tegenwoordig rente wel over 365 dagen berekenen, maar goed.)
Jouw economie II kennis is niet maatgevend voor hoe bedrijven daadwerkelijk hun financiele administratie bijhouden.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Confusion schreef op maandag 26 november 2007 @ 13:49:
[...]

Jouw economie II kennis is niet maatgevend voor hoe bedrijven daadwerkelijk hun financiele administratie bijhouden.
Mijn punt is dat er in de economie gewoon afspraken over gemaakt zijn, en economen dus niet rekenen met irritant gedefinieerde termen als maanden.

Je mag van mij best een tegenvoorbeeld geven hoor, maar tot nu toe heb ik van jou ook alleen maar jouw mening gelezen.

Om het constructief te houden, TS, waar wil je het precies voor gebruiken? Is het puur een vingeroefening, of zit er toch een daadwerkelijke implementatie aan vast?

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
edit: niet relevant

[ Voor 113% gewijzigd door Zip McOccup op 26-11-2007 14:26 ]


Acties:
  • 0 Henk 'm!

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Semyon schreef op maandag 26 november 2007 @ 13:26:
[...]


Het werkt nu...

Maar er is weer een fout:

31/08/2007 naar 01/10/2007 is precies 1 maand
zo ook
01/09/2007 naar 01/10/2007 is ook precies 1 maand.

vanaf 01/10/2007 zijn er blijkbaar 2 periodes van precies 1 maand die niet even lang duren.

offtopic:
Ik woon in een andere tijdzone en moet zo gaan slapen :) Als er weer een oplossing is, test ik die graag. Ik twijfel nog steeds zeer aan de haalbaarheid van precieze
Een grote fout van mij in mijn aantal dagen in een maand array. Ik sloeg wel netjes $dagen['02'] over met invullen maar definieerde die vervolgens alsnog waardoor maand 10 opeens maar 30 dagen kreeg. Is nu gefixt en komt inderdaad 1 maand en 1 dag uit

Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 15-07 19:07

Dido

heforshe

offtopic:
Ik zit met verbazing dit topic te lezen, en met name de stelligheid waarmee "de maand" als eenheid onwerkbaar wordt verklaard. Het is mij een steeds groter raadsel aan het worden hoe hele volksstammen zonder noemenswaardige problemen of spraakverwarring al sinds het jaar kruik met de maand als periode werken - kennelijk zouden we elkaar allang de hersens hebben moeten inslaan omdat een maandtrajectkaart van de NS, een maandabonnement voor de bus en de sportschool zo verwarrend zijn. Er is niemand in Nederland die snapt wanneer hij een abonnement op moet zeggen als dat drie maanden voor het einde moet, en zelfs de wetgever heeft ons vern**kt toen hij in het arbeidsrecht termijnen in maanden (kalendermaanden, ja!) opnam.
Ik voel de Nederlandse samenleving tot stilstand komen naarmate dit topic vordert en de bruikbaarheid van de maand afneemt tot historische diepten :+

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Zip McOccup schreef op maandag 26 november 2007 @ 13:43:
Erm, dude... Mijn oplossing geeft:

code:
1
2
Tussen 31 August 2007 en 01 October 2007 zit 1 dag(en) en 1 maand(en) en 0 jaar.
Tussen 01 September 2007 en 01 October 2007 zit 0 dag(en) en 1 maand(en) en 0 jaar.
Tussen 27 February 2000 en 01 April 2000 zit 3 dag(en) en 1 maand(en) en 0jaar.
Tussen 27 February 2000 en 30 March 2000 zit 3 dag(en) en 1 maand(en) en 0jaar.

Jouw oplossing is ook raar

Ga niet iedereens script instaleren hoor!

Nu bedtijd... Het is hier al ver na 12'en Naar de rest kijk ik morgen.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Rainmaker1987 schreef op maandag 26 november 2007 @ 14:17:
[...]


Een grote fout van mij in mijn aantal dagen in een maand array. Ik sloeg wel netjes $dagen['02'] over met invullen maar definieerde die vervolgens alsnog waardoor maand 10 opeens maar 30 dagen kreeg. Is nu gefixt en komt inderdaad 1 maand en 1 dag uit
Ok... Laatste:

27-02-2007 naar 29-03-2007 -> 1 maand 2 dagen
27-02-2007 naar 01-04-2007 -> 1 maand 2 dagen

raar..

Nu echt slapen... Sorry, ik denk nog steeds dat het niet kan, in zo'n 10 uur kijk ik er weer naar... De maand is echt slecht gedefinieerd hoor!

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Snap je nu waarom ik er een topic over ben gestart? Dat er 72 maanden tussen 2 datums ligt is leuk, maar ik wil inderdaad eens kijken of er nu eens een goede start gemaakt kan worden met datgene wat ik in de TS heb geplaatst. Om eerlijk te zijn is uren, minuten en seconden weinig interessant, maar als het natuurlijk in 1 functie kan, zou dat mooi zijn.

Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Nu online
PHP om een simpel Perl scriptje heen:
http://www.rutgerwessels.nl/date.php

Het Perl scriptje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use DateTime;
use Data::Dumper;

$date1 = shift(@ARGV);
$date2 = shift(@ARGV);

@date1 = split(/-/, $date1);
@date2 = split(/-/, $date2);


$dt1 = DateTime->new( year => $date1[0], month => $date1[1], day=>$date1[2]);
$dt2 = DateTime->new( year => $date2[0], month => $date2[1], day=>$date2[2]);

$dur = $dt2->subtract_datetime($dt1);

print Dumper(\$dur);

[ Voor 73% gewijzigd door Kalentum op 26-11-2007 15:42 . Reden: De code toegevoegd ]


Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 15-07 19:07

Dido

heforshe

Ik zie voorbeelden van inconsistentie voorbijkomen die alleen maar inconsistent zijn omdat wij geneigd zijn van de kleinste naar de grootste datum toe te rekenen, zo begrijpen we een maandabonement ook.

Het lijkt erop dat de scripts de andere kant op rekenen, dus van de grootste datum naar beneden rekenen. Dat levert verwarrende uitkomsten op.

Als ik kijk naar de NS-logica (die ken ik als maandkaartkoper wel, namelijk), dan geldt het volgende:

Tussen 27 February 2000 en 01 April 2000 zit 3 dag(en) en 1 maand(en) en 0jaar.
, ie 1 maand, plus 28, 29 en 30 maart
Tussen 27 February 2000 en 30 March 2000 zit 2 dag(en) en 1 maand(en) en 0jaar.
, ie 1 maand, plus 28 en 29 maart

27-02-2007 naar 29-03-2007 -> 1 maand 1 dagen
, ie 1 maand, plus 28 maart
27-02-2007 naar 01-04-2007 -> 1 maand 3 dagen
, ie 1 maand, plus 28, 29 en 30 maart

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Een tweede versie gemaakt die ook op die wijze denkt, waar Dido helemaal gelijk in heeft overigens:

Volgens mij houdt hij netjes rekening met schrikkeljaren etc. en de voorbeelden zijn hetzelfde als wat de NS aangeeft. Hij rekent nu dus echt de dagen ertussen in plaats het verschil. Kwestie van 1 erbij optellen uiteraard. Wel apart blijft dat hij bij regel 13 -2 nodig heeft ipv -1, dit heeft waarschijnlijk te maken met de maandoverschrijding. http://tweakers.wikichess.net/tweakers2.php

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$verschil_jaar  = $datum1['0'] - $datum2['0'];
$verschil_maand = $datum1['1'] - $datum2['1'];

if($verschil_maand < 0){
    $verschil_jaar = $verschil_jaar - 1;
    $verschil_maand = $verschil_maand + 12; 
}   
if($datum1['2'] - $datum2['2'] < 0){
    $verschil_maand = $verschil_maand - 1;  
}   

if($datum1['2'] - $datum2['2'] < 0){
$verschil_dagen = date('d', mktime(0, 0, 0, $datum1['1'], 0, $datum1['0'])) - $datum2['2'] + $datum1['2'] - 2; 
}   
else{
$verschil_dagen = $datum1['2'] - $datum2['2'] - 1;  
}


Ps. uiteraard heeft deze weer 2 arrays nodig array('jaar', 'maand','dag')

Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Semyon schreef op maandag 26 november 2007 @ 14:38:
[...]


Ok... Laatste:

27-02-2007 naar 29-03-2007 -> 1 maand 2 dagen
27-02-2007 naar 01-04-2007 -> 1 maand 2 dagen

raar..

Nu echt slapen... Sorry, ik denk nog steeds dat het niet kan, in zo'n 10 uur kijk ik er weer naar... De maand is echt slecht gedefinieerd hoor!
Roger. Snap de fout. Ik moet ook controleren of de nieuwe dag (de 30e in dit geval) groter is dan het aantal dagen in de oude maand.

Dit is trouwens wel een vrij lastige :)
je zou zeggen; nog 2 dagen in februari en dan nog 29 in maart. Dus: Nog 31 dagen.

voor de vergelijking 27-02-2000 en 31-3-2000 is het helemaal extreem; je krijgt: 33 dagen en 0 maanden.
Abstract gezien is dat wel correct; er zit geen hele maand tussen. Maar voor het gevoel klopt er natuurlijk helemaal niets van; 33 dagen is meer dan de langste maanden duren :)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function DateDifference($newDate, $oldDate) {

    $newDay = date('d',$newDate);
    $newMonth = date('m',$newDate);
    $newYear = date('Y',$newDate);
    $oldDay = date('d',$oldDate);
    $oldMonth = date('m',$oldDate);
    $oldYear = date('Y',$oldDate);
    $daysInMonth = date('d', mktime(0, 0, 0, $oldMonth+1, 0, $oldYear));

    $substractExtraMonth = 0;
    $substractExtraYear = 0;

    
    if ($newDay < $oldDay) {
        $dayDiff = $newDay - $oldDay + $daysInMonth;
        $substractExtraMonth = 1;
    } elseif( $daysInMonth < $newDay) {
        $dayDiff = $newDay + $daysInMonth - $oldDay;
        $substractExtraMonth = 1;
    } else {
        $dayDiff = $newDay - $oldDay;
    }
    
    if ($newMonth < $oldMonth + $substractExtraMonth) {
        $monthDiff = $newMonth - $oldMonth - $substractExtraMonth + 12 ;
        $substractExtraYear = 1;
    } else {
        $monthDiff = $newMonth - $oldMonth - $substractExtraMonth;
    }
    
    $yearDiff = $newYear - $oldYear - $substractExtraYear;
    
    echo "Tussen ".date("d F Y", $oldDate)." en ".date("d F Y", $newDate)." zit ".$dayDiff." dag(en) en ".$monthDiff." maand(en) en ".$yearDiff. " jaar.";
    
}

$date0 = mktime(0,0,0,2,27,2000);
$date1 = mktime(0,0,0,3,31,2000);
$date2 = mktime(0,0,0,4,1,2000);

DateDifference($date1, $date0);
echo "\n<br />";
DateDifference($date2, $date0);


ik heb nu voor de dage de volgende code toegevoegd:

PHP:
1
2
3
4
elseif( $daysInMonth < $newDay) {
        $dayDiff = $newDay + $daysInMonth - $oldDay;
        $substractExtraMonth = 1;
    }


Nu krijg je dus wel bizarre zaken: tussen 27 feb 2000 en 31 mrt 2000 zit volgens mijn script 33 dagen.
Toch denk ik dat dit de meest correcte oplossing is, aangezien er geen hele maand tussen valt...

[ Voor 75% gewijzigd door Zip McOccup op 26-11-2007 16:14 ]


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Grijze Vos schreef op maandag 26 november 2007 @ 14:00:
Je mag van mij best een tegenvoorbeeld geven hoor, maar tot nu toe heb ik van jou ook alleen maar jouw mening gelezen.
Je hebt mijn praktijkervaring gelezen. Klant wil inkomsten per dag weten en is niet blij als ik de maandinkomsten voor februari 2004 dan deel door 28 of door 30, omdat er dan opeens een rare afwijking in februari zit. Afwijkingen van 3% in dat soort getallen kunnen relevant zijn.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • sopsop
  • Registratie: Januari 2002
  • Laatst online: 08:37

sopsop

[v] [;,,;] [v]

Maar waarom al die 'moeilijke' berekeningen, als je gewoon de standaard rekenfunctionaliteit van de betreffende taal gebruikt, zoals ik hier doe: sopsop in "[PHP] Datums van elkaar aftrekken"

Ik reken van grootste entiteit naar de kleinste toe (jaar. maand, week, dag, uur, minuut, seconde) en werk met het restant van de het verschil tussen de twee data. Daarbij hou ik dus automatisch rekening met schrikkeldagen, zomer/wintertijd e.d. aangezien ik met datums blijf werken.

Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 09-07 10:34
sopsop schreef op maandag 26 november 2007 @ 16:20:
Maar waarom al die 'moeilijke' berekeningen, als je gewoon de standaard rekenfunctionaliteit van de betreffende taal gebruikt, zoals ik hier doe: sopsop in "[PHP] Datums van elkaar aftrekken"

Ik reken van grootste entiteit naar de kleinste toe (jaar. maand, week, dag, uur, minuut, seconde) en werk met het restant van de het verschil tussen de twee data. Daarbij hou ik dus automatisch rekening met schrikkeldagen, zomer/wintertijd e.d. aangezien ik met datums blijf werken.
Het probleem is dat maanden niet een vaste duur hebben.
Van 28 februari naar 1 april is meestal 1 maand en 4 dagen, maar als je op 1 april kijkt welke datum 1 maand en 4 dagen geleden was, dan kom je uit op 25 februari.

Al deze mensen proberen met andere definities voor datums te werken.

[ Voor 4% gewijzigd door _js_ op 26-11-2007 16:41 ]


Acties:
  • 0 Henk 'm!

  • sopsop
  • Registratie: Januari 2002
  • Laatst online: 08:37

sopsop

[v] [;,,;] [v]

_js_ schreef op maandag 26 november 2007 @ 16:40:
[...]
Het probleem is dat maanden niet een vaste duur hebben.
Van 28 februari naar 1 april is meestal 1 maand en 4 dagen, maar als je op 1 april kijkt welke datum 1 maand en 4 dagen geleden was, dan kom je uit op 25 februari.

Al deze mensen proberen met andere definities voor datums te werken.
Hoezo komt daar wat anders uit? Als je de ene kant op rekent, moet je datum + 1 maand + 4 dagen uitrekenen, reken je de andere kant op moet je de datum - 4 dagen - 1 maand uitrekenen. Dit is gewoon een kwestie van definitie.

[ Voor 3% gewijzigd door sopsop op 26-11-2007 16:47 ]


Acties:
  • 0 Henk 'm!

  • Grum
  • Registratie: Juni 2001
  • Niet online
Probleem ligt erin dat de 'entiteiten' niet een vaste gedefineerde grootte hebben.

Ik vind persoonlijk tussen 1 feb en 1 maart precies 1 maand zit en het zou me een zier kunnen zijn of dat nou 28,29,30,31 dagen is.

Maarja dan heb je nog steeds 30 dagen zitten tussen 29 jan en 28 feb, maar dat is dan ook meteen het 'raarste' wat kan gebeuren.

Het simpelste is toch om te rekenen in defineerde tijdseenheden. Dit zou jammerlijk 'week' het grootste maken.

En zoals eerder gemeld, significantie is hier ook zeker van toepassing, waarom uren/minuten/secondes vermelden als je nog naar maanden of weken zit te staren?

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Confusion schreef op maandag 26 november 2007 @ 16:10:
[...]

Je hebt mijn praktijkervaring gelezen. Klant wil inkomsten per dag weten ...
...dus geef je gewoon een aantal dagen. Klaar. :Y)

Dit topic gaat nergens meer over. Als een tijdspanne duidelijk gecommuniceerd moet worden gebruik je gewoon een duidelijke eenheid, of bedenk je met z'n alleen een conventie, waarbij een maand == 30 dagen weldegelijk een regelmatig gebruikte conventie is. :) Kan het allemaal wat informeler, of wordt er niet op 1 dag meer of minder gekeken, kan je gewoon prima het aantal maanden gebruiken.

{signature}


Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 15-07 19:07

Dido

heforshe

Zip McOccup schreef op maandag 26 november 2007 @ 15:56:
Nu krijg je dus wel bizarre zaken: tussen 27 feb 2000 en 31 mrt 2000 zit volgens mijn script 33 dagen.
Toch denk ik dat dit de meest correcte oplossing is, aangezien er geen hele maand tussen valt...
Hoe noem je de periode van 27/2 tot 27/3 dan :? Ik, en de meeste mensen met mij, vinden dat precies een maand ;)

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Zou het niet "slimmer" zijn, om te kijken:
- of en hoeveel hele jaren er tussen de 2 data liggen
- of en hoeveel hele maanden er tussen de 2 data liggen
- of en hoeveel hele weken er dan nog over blijven
- dagen
- uren
- minuten
- etc.?

En dat dan allemaal met de standaard strtotime functies.. is dat niet de meest acurate manier?

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Dat doet mijn Java voorbeeld inderdaad. Gewoon van groot naar klein berekenen en weergeven. Van klein naar groot is een no-go, zoals de halve discussie hier al aantoont. Hoeveel dagen er in een maand gaan boeit totaal niet.

Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Rainmaker1987 schreef op maandag 26 november 2007 @ 15:51:
Een tweede versie gemaakt die ook op die wijze denkt, waar Dido helemaal gelijk in heeft overigens:

Volgens mij houdt hij netjes rekening met schrikkeljaren etc. en de voorbeelden zijn hetzelfde als wat de NS aangeeft. Hij rekent nu dus echt de dagen ertussen in plaats het verschil. Kwestie van 1 erbij optellen uiteraard. Wel apart blijft dat hij bij regel 13 -2 nodig heeft ipv -1, dit heeft waarschijnlijk te maken met de maandoverschrijding. http://tweakers.wikichess.net/tweakers2.php

Ps. uiteraard heeft deze weer 2 arrays nodig array('jaar', 'maand','dag')
Getal voorbeeld van wat Dido bedoelt:

27 Februari 2007 naar 27 Maart 2007 -> 1 Maand en -1 dag ? !

Ik zou echt gaan voor of Maanden en precisie van dagen (laat staan uren en minuten) laten vallen, of lekker gaan voor een maand met precies 1/12 jaar lengte.
Ik raad ook gewoon de mktime aan, volgens mij is al het extra rekenwerk alleen maar nodig om het ingewikkelder te maken en snappen mensen het toch niet meer.

[ Voor 16% gewijzigd door Semyon op 26-11-2007 22:18 ]

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Confusion schreef op maandag 26 november 2007 @ 16:10:
[...]

Je hebt mijn praktijkervaring gelezen. Klant wil inkomsten per dag weten en is niet blij als ik de maandinkomsten voor februari 2004 dan deel door 28 of door 30, omdat er dan opeens een rare afwijking in februari zit. Afwijkingen van 3% in dat soort getallen kunnen relevant zijn.
Met een zinnig datamodel heb je geen rare conversies naar periodes nodig om inkomsten per dag te weten te komen dunkt me, daar is het dus een non-issue bij.

Ik blijf bij mijn standpunt, als de TS nou gewoon zijn doelstelling aangeeft, dan kan er tenminste nog gericht gediscussieerd worden. Code-onderhoud-technisch lijkt me een functie van 200 a 300 regels die niet veel zinnigs doen nogal onzin in een codebase, maar goed, wie ben ik.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
xces schreef op maandag 26 november 2007 @ 19:12:
Zou het niet "slimmer" zijn, om te kijken:
- of en hoeveel hele jaren er tussen de 2 data liggen
- of en hoeveel hele maanden er tussen de 2 data liggen
- of en hoeveel hele weken er dan nog over blijven
- dagen
- uren
- minuten
- etc.?

En dat dan allemaal met de standaard strtotime functies.. is dat niet de meest acurate manier?
Of deze specificatie is niet nauwkeurig genoeg of je loopt tegen mijn genoemd probleem aan dat je verschillende data hebt die met een zelfde periode naar een andere dag gaan, of een dag hebt die met dezelfde periode naar verschillende eind dagen gaan.

Nogmaals, de maand is geen nette tijdsduur. Een implementatie op basis hiervan gaat fouten leveren. Een 'patch' is de maand een vaste tijdsduur te geven van precies 1/12 jaar, maar het moge duidelijk zijn dat dit een (vieze) patch is. Je krijgt consitentie tenminste, dat vind ik persoonlijk belangrijk, alhoewel er wel wat merkwaardige verlopen gaan plaatsvinden.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 23:04
ik heb in java ooit iets geschreven en daar was een array maandlengtes met {31, 28, 31 ..... } etc.

krijg je iets als
code:
1
2
3
4
5
6
7
8
9
10
11
int dagenover = 300;
int counter = 0;

while (dagenover > 0)
{
dagenover -= maandlengtes[counter];
counter += 1;
}

int maand = counter;
dagenover += maandlengtes[counter-2];


//edit: dan krijg je dus als resultaat bijvoorbeeld 14-3 (dagenover - maand, 14 dagen en 3 maanden dus)

zoiets dus uit mn hoofd, moet je alleen nog even iets zoeken voor schrikkeljaren (if schrikkeljaar then maandlengtes = {31, 29, 31 etc.} else maandlengtes = {31,28,31 etc.})

[ Voor 19% gewijzigd door creator1988 op 26-11-2007 23:43 ]


Acties:
  • 0 Henk 'm!

Anoniem: 14829

therat10430 schreef op zaterdag 24 november 2007 @ 20:27:
Ik heb ooit een keer een app voor visual basic geschreven die leeftijd moest uitreken door geboortedagum van huidige datum af te trekken, de truuk daarin was dat elk jaar 365,25 dagen heeft. Als je de ,25 mee rekent kun je een stuk eenvoudiger gaan rekenen
Ooit 's (in 1991) de conversie functie die de HP 10C rekenmachine gebruikte omgezet naar Pascal ('trunc' is 'floor' in een hoop andere talen, en 'div' is een integer deling):
Delphi:
1
2
3
4
5
function DateConv(year, month, day: word): longint;
begin
  DateConv := trunc(365.25 * year) + trunc(30.6 * month) + day
              - (year div 100) + (year div 400) - 723241;    {01-jan-1980 = 1}
end;

Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
creator1988 schreef op maandag 26 november 2007 @ 23:41:
ik heb in java ooit iets geschreven en daar was een array maandlengtes met {31, 28, 31 ..... } etc.

krijg je iets als
code:
1
2
3
4
5
6
7
8
9
10
11
int dagenover = 300;
int counter = 0;

while (dagenover > 0)
{
dagenover -= maandlengtes[counter];
counter += 1;
}

int maand = counter;
dagenover += maandlengtes[counter-2];


//edit: dan krijg je dus als resultaat bijvoorbeeld 14-3 (dagenover - maand, 14 dagen en 3 maanden dus)

zoiets dus uit mn hoofd, moet je alleen nog even iets zoeken voor schrikkeljaren (if schrikkeljaar then maandlengtes = {31, 29, 31 etc.} else maandlengtes = {31,28,31 etc.})
Leuk idee, maar je hebt niet eens een begin en eind datum?

Nogmaal als je eerst gaat kijken hoeveel maanden je over hebt en dan dagen aanvult krijg je het probleem dat ik noemde op:
Semyon @ zondag 25 november 2007 22:49

Als je eerst dagen aanvult en dan maanden krijg je het probleem dat o.a. Rainmaker1987 heeft.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Grijze Vos schreef op maandag 26 november 2007 @ 22:42:
Ik blijf bij mijn standpunt, als de TS nou gewoon zijn doelstelling aangeeft, dan kan er tenminste nog gericht gediscussieerd worden. Code-onderhoud-technisch lijkt me een functie van 200 a 300 regels die niet veel zinnigs doen nogal onzin in een codebase, maar goed, wie ben ik.
Dat heb ik toch al 3x gedaan? ik wil textueel weten hoeveel tijd er tussen 2 datums zitten. Of ik dat nu voor een geboortedatum of voor de periode dat iemand geregistreerd is gebruik maakt geen kont uit.

@Semyon;
met mijn opmerking van groot naar klein bedoelde ik door te werken met strtotime. Deze houd volgens mij overal rekening mee. D.w.z. als je daartegen zegt:
strtotime("+1 months", '1-2-2000') hij op 1-3-2000 uitkomt en er geen x dagen bij optelt.

Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 23:04
@Semyon, dit was even een voorbeeld hoe ik om zou gaan met de periode van maanden

Het lijkt mij het meest logische om bij het berekenen van het verschil tussen data uit te gaan dat datum1 = 1/1/1900 en datum2 = verschil + 1/1/1900. Als je vervolgens het aantal millisecondes tussen de 2 data uitrekent kan je daarna jaren, dagen, uren, secondes etc. gaan aftrekken.

Vervolgens pas je op het aantal overgebleven dagen de functie van mij toe.

Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Dido schreef op maandag 26 november 2007 @ 17:55:
[...]

Hoe noem je de periode van 27/2 tot 27/3 dan :? Ik, en de meeste mensen met mij, vinden dat precies een maand ;)
Heb je helemaal gelijk in. Je zit gewoon met het probleem hoe je de tussenliggende tijd berekent. Bijvoorbeeld tussen 27/2/2004 en 2/4/2004:

Methode 1:
27feb => 1mrt is 3dagen. 1mrt => 1apr is 1 maand. 1april => 2april is 1 dag.
Totaal: 1mnd 4 dagen

Methode 2:
27feb => 27mrt is 1 maand. 27mrt => 2 april is 6 dagen.
Totaal 1mnd 6 dagen.

Dat heb ik proberen te ondervangen met die 33 dagen. Toch nog even kijken of het eleganter kan.

edit:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function DateDifference($newDate, $oldDate) {

    $newDay = date('d',$newDate);
    $newMonth = date('m',$newDate);
    $newYear = date('Y',$newDate);
    $oldDay = date('d',$oldDate);
    $oldMonth = date('m',$oldDate);
    $oldYear = date('Y',$oldDate);
    $daysInMonth = date('d', mktime(0, 0, 0, $newMonth, 0, $oldYear));

    $substractExtraMonth = 0;
    $substractExtraYear = 0;

    
    if ($newDay < $oldDay) {
        $dayDiff = $newDay - $oldDay + $daysInMonth;
        $substractExtraMonth = 1;
    } else {
        $dayDiff = $newDay - $oldDay;
    }

    
    if ($newMonth < $oldMonth + $substractExtraMonth) {
        $monthDiff = $newMonth - $oldMonth - $substractExtraMonth + 12 ;
        $substractExtraYear = 1;
    } else {
        $monthDiff = $newMonth - $oldMonth - $substractExtraMonth;
    }
    
    $yearDiff = $newYear - $oldYear - $substractExtraYear;
    
    echo "Tussen ".date("d F Y", $oldDate)." en ".date("d F Y", $newDate)." zit ".$dayDiff." dag(en) en ".$monthDiff." maand(en) en ".$yearDiff. " jaar.";
    
}


Met deze php functie gebruik ik "methode 2" (zie hierboven). Tussen 27/2 en 27/3 zit nu 1 maand. :)

[ Voor 50% gewijzigd door Zip McOccup op 27-11-2007 13:20 ]


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Zip McOccup schreef op dinsdag 27 november 2007 @ 11:13:
[...]


Heb je helemaal gelijk in. Je zit gewoon met het probleem hoe je de tussenliggende tijd berekent. Bijvoorbeeld tussen 27/2/2004 en 2/4/2004:

Methode 1:
27feb => 1mrt is 3dagen. 1mrt => 1apr is 1 maand. 1april => 2april is 1 dag.
Totaal: 1mnd 4 dagen

Methode 2:
27feb => 27mrt is 1 maand. 27mrt => 2 april is 6 dagen.
Totaal 1mnd 6 dagen.

Dat heb ik proberen te ondervangen met die 33 dagen...

Toch nog even kijken of het eleganter kan.
Hmm dat is een goeie.. Daar heb ik nog niet eens aan gedacht! Ik zou eigenlijk willen zeggen, kies voor methode 1, maar methode 2 is ook juist..

Hoe PHP dit doet zou je simpel kunnen berekenen. Kan nu ff niet testen...
PHP:
1
2
echo date('d-m-Y', strtotime("+1 months +6 days", mktime(0, 0, 0, 2, 27, 2000)))."\r\n";
echo date('d-m-Y', strtotime("+1 months +4 days", mktime(0, 0, 0, 2, 27, 2000)))."\r\n";

Acties:
  • 0 Henk 'm!

  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Het is een algemeen geaccepteerd standaard dat een tijdsperiode van groot naar klein wordt aangegeven (heck, je vermeldt het zelfs in de uitkomst! "x maand en y dagen" ipv "y dagen en x maand"). Methode 2 voldoet hier dus aan.

[ Voor 24% gewijzigd door BalusC op 27-11-2007 12:09 ]


Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 15-07 19:07

Dido

heforshe

Semyon schreef op maandag 26 november 2007 @ 22:16:
Getal voorbeeld van wat Dido bedoelt:

27 Februari 2007 naar 27 Maart 2007 -> 1 Maand en -1 dag ? !
Aangezien het gaat om het aantal dagen tussen twee datums, tel ik de datums zelf niet mee, zoals ook uit mijn voorbeelden bleek.

Tussen 27/2 en 27/3 zitten in 2007 dus 0 maanden en 27 dagen.

Je moet bij het bepalen of er minimaal een maand tussen zit daar rekening mee houden.

Simpel gezegd: er zit minimaal een maand tussen datum A en datum B als datum B verder ligt dan de eerste dag na de laatste geldigheidsdatum van een NS maandkaart die op datum A-1 ingaat.

Als je wilt weten hoelang een project geduurd heeft wil je trouwens begin- en einddatum meetellen, dan wordt het:
Een project heeft minimaal een maand geduurd als de einddatum van het project minimaal gelijk is aan de laatste geldigheidsdag van een NS-maandkaart die op de begindatum ingaat.

Die laatste zou je de echte NS-regel kunnen noemen :D

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
BalusC schreef op dinsdag 27 november 2007 @ 12:08:
Het is een algemeen geaccepteerd standaard dat een tijdsperiode van groot naar klein wordt aangegeven (heck, je vermeldt het zelfs in de uitkomst! "x maand en y dagen" ipv "y dagen en x maand"). Methode 2 voldoet hier dus aan.
Ik heb het nu aangepast. Je hebt gelijk. Volgens mij berekent mijn script nu van groot naar klein.
Dido schreef op dinsdag 27 november 2007 @ 12:22:
[...]

Aangezien het gaat om het aantal dagen tussen twee datums, tel ik de datums zelf niet mee, zoals ook uit mijn voorbeelden bleek.
Hier ben ik het niet eens. Ik denk dat het relevanter is om naar het verschil in data te kijken.
Tussen vandaag en morgen zit 1 dag verschil. Er zit geen dag tussen. Nu vind ik het laatste feit niet echt relevant en een beetje misleidend.

[ Voor 36% gewijzigd door Zip McOccup op 27-11-2007 13:26 ]


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Zip McOccup schreef op dinsdag 27 november 2007 @ 11:13:
Methode 1:
27feb => 1mrt is 3dagen. 1mrt => 1apr is 1 maand. 1april => 2april is 1 dag.
Totaal: 1mnd 4 dagen

Methode 2:
27feb => 27mrt is 1 maand. 27mrt => 2 april is 6 dagen.
Totaal 1mnd 6 dagen.
Even samenvattend, de mogenlijkheden (met dank aan Zip McOccup)

Methode 1 heeft als resultaat dat
27 feb -> 30 Maart 1 Maand en 3 dagen is
27 feb -> 1 April ook 1 Maand en 3 dagen is
Wil je echt dat er tussen 27 Feb & 30 Maart even veel tijd zit als tussen 27 Feb en 1 April?

Methode 2 heeft als resultaat dat
30 Augustus -> 1 Okt is 1 Maand 1 dag (eerst maand, naar 30 Sept dan nog 1 dag)
1 Sept -> 1 Okt is 1 Maand
Nu kunnen we voor 31 Augustus -> 1 Okt kiezen dat het hetzelfde is als 30 Aug of als 1 Sept
Wil je echt dat er tussen 31 Augustus -> 1 Okt even veel tijd zit als 30 Augustus -> 1 Okt?

De Patch
we noemen dingen dagen soms.
27 Feb naar 27 Maart is geen (!) 1 maand maar maar 31 dagen
of 27 dagen als we Dido volgen
wil je echt dat 27 Feb -> 27 Maart, geen 1 maand is?

Als je op alle vragen nee zegt zegt besef je dat je een probleem met maanden hebt.
xces schreef op dinsdag 27 november 2007 @ 10:22:
met mijn opmerking van groot naar klein bedoelde ik door te werken met strtotime. Deze houd volgens mij overal rekening mee. D.w.z. als je daartegen zegt:
strtotime("+1 months", '1-2-2000') hij op 1-3-2000 uitkomt en er geen x dagen bij optelt.
wat doet:
strtotime("+1 months", '31-08-2000') dan? 31-09-2000 bestaat niet, er komt hetzelfde uit als
strtotime("+1 months", '1-09-2000') of strtotime("+1 months", '30-08-2000') wat aangeeft dat het niet overal rekening meehoudt.

Oplossingen:
Als je om genoemde redenen niet wilt gaat voor een van deze oplossingen, (Of je accepteert de problemen hier mee) krijg je de volgende oplossingen in mijn ogen.

nr 1
We slaan maanden over. Een maand zit toch al in de zelfde orde van grote als een week, weken zijn precies, we geven dingen lekker met weken aan en zwijgen over maanden.

nr 2
We nemen voor een maand 1/12 jaar, altijd, we krijgen nog steeds problemen maar consitentie.


@dido
de
27 Februari 2007 naar 27 Maart 2007 -> 1 Maand en -1 dag ? !
was een resultaat van rainmakers' script

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Zip McOccup schreef op dinsdag 27 november 2007 @ 13:23:
[...]


Ik heb het nu aangepast. Je hebt gelijk. Volgens mij berekent mijn script nu van groot naar klein.
Ter illustratie voor methode 2, je script doet dit:

code:
1
2
3
DateDifference(mktime(0,0,0,10, 1, 2006, -1),mktime(0,0,0,8, 31, 2006, -1));

DateDifference(mktime(0,0,0,10, 1, 2006, -1),mktime(0,0,0,9, 1, 2006, -1));


Tussen 31 August 2006 en 01 October 2006 zit 0 dag(en) en 1 maand(en) en 0 jaar.
Tussen 01 September 2006 en 01 October 2006 zit 0 dag(en) en 1 maand(en) en 0 jaar.

Het lijkt mij merkwaardig dat vanaf 1 Oktober er zowel een precies een maand zit naar 31 Aug als naar 01 Sept.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Damn, het probleem is toch nog lastiger dan ik had gedacht. Het laatste geval moet idd 1 maand en 1 dag worden. Dit komt door de regel
PHP:
1
$newDay - $oldDay + $daysInMonth;


In dit geval wordt dat namelijk:

1 - 31 + 30 = 0. Das natuurlijk fout.

Je krijgt een nog belachelijkere fout als je kijkt naar het interval 31-1-2001 en 1-3-2001:
code:
1
Tussen 31 January 2001 en 01 March 2001 zit 0 jaar en 1 maand(en) en -2 dag(en).


Ik zie waar de fout vandaan komt. Ik ga er nog eens even op broeden. Het laat me niet los.

Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Zip McOccup schreef op dinsdag 27 november 2007 @ 15:02:
Damn, het probleem is toch nog lastiger dan ik had gedacht. Het laatste geval moet idd 1 maand en 1 dag worden.
Denk je?
Dus jij zegt 31 Aug -> 1 Okt is 1 Maand en 1 Dag

Maar dat hebben we toch al voor:
Maar ook 30 Aug -> 1 Okt is 1 Maand en 1 Dag

30 Aug + 1 Maand is 30 Sept. Nog 1 Dag erbij en we zitten op 1 Okt.

Zit er dan tussen 31 Aug -> 1 Okt en 30 Aug en 1 Okt allebei precies 1 Maand?

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Semyon schreef op dinsdag 27 november 2007 @ 15:10:
[...]


Denk je?
Dus jij zegt 31 Aug -> 1 Okt is 1 Maand en 1 Dag

Maar dat hebben we toch al voor:
Maar ook 30 Aug -> 1 Okt is 1 Maand en 1 Dag

30 Aug + 1 Maand is 30 Sept. Nog 1 Dag erbij en we zitten op 1 Okt.

Zit er dan tussen 31 Aug -> 1 Okt en 30 Aug en 1 Okt allebei precies 1 Maand?
Dit is een lastige. In feite zit er in beide gevallen 1 maand en 1 dag tussen... Maar beide gevallen zijn niet aan elkaar gelijk. Dat is het rare eraan. Wat vind jij dan? Tussen 31aug en 1 okt => 1 maand en 0 dagen?

Dat vind ik namelijk ook niet logisch.
Semyon schreef op dinsdag 27 november 2007 @ 14:28:
[...]

Even samenvattend, de mogenlijkheden (met dank aan Zip McOccup)

Methode 1 heeft als resultaat dat
27 feb -> 30 Maart 1 Maand en 3 dagen is
27 feb -> 1 April ook 1 Maand en 3 dagen is
Wil je echt dat er tussen 27 Feb & 30 Maart even veel tijd zit als tussen 27 Feb en 1 April?

Methode 2 heeft als resultaat dat
30 Augustus -> 1 Okt is 1 Maand 1 dag (eerst maand, naar 30 Sept dan nog 1 dag)
1 Sept -> 1 Okt is 1 Maand
Nu kunnen we voor 31 Augustus -> 1 Okt kiezen dat het hetzelfde is als 30 Aug of als 1 Sept
Wil je echt dat er tussen 31 Augustus -> 1 Okt even veel tijd zit als 30 Augustus -> 1 Okt?

De Patch
we noemen dingen dagen soms.
27 Feb naar 27 Maart is geen (!) 1 maand maar maar 31 dagen
of 27 dagen als we Dido volgen
wil je echt dat 27 Feb -> 27 Maart, geen 1 maand is?

Als je op alle vragen nee zegt zegt besef je dat je een probleem met maanden hebt.


[...]


wat doet:
strtotime("+1 months", '31-08-2000') dan? 31-09-2000 bestaat niet, er komt hetzelfde uit als
strtotime("+1 months", '1-09-2000') of strtotime("+1 months", '30-08-2000') wat aangeeft dat het niet overal rekening meehoudt.

Oplossingen:
Als je om genoemde redenen niet wilt gaat voor een van deze oplossingen, (Of je accepteert de problemen hier mee) krijg je de volgende oplossingen in mijn ogen.

nr 1
We slaan maanden over. Een maand zit toch al in de zelfde orde van grote als een week, weken zijn precies, we geven dingen lekker met weken aan en zwijgen over maanden.

nr 2
We nemen voor een maand 1/12 jaar, altijd, we krijgen nog steeds problemen maar consitentie.


@dido
de
27 Februari 2007 naar 27 Maart 2007 -> 1 Maand en -1 dag ? !
was een resultaat van rainmakers' script
Hier heb je dan natuurlijk wel een punt. Geen van de methoden geeft altijd een uniek antwoord.
Ik denk dat de beste oplossing is om de kleine "foutjes" voor lief te nemen. In feite is het natuurlijk niet eens fout ;) .

[ Voor 61% gewijzigd door Zip McOccup op 27-11-2007 15:33 . Reden: typo en toevoeging ]


Acties:
  • 0 Henk 'm!

  • xces
  • Registratie: Juli 2001
  • Laatst online: 07-07 20:37

xces

To got or not to got..

Topicstarter
Weet je wat het is, als je het resultaat (bij mijn genoemde oplossing) vervolgens meegeeft als strtotime bij de laagste datum, kom je wel bij de andere datum uit.. Dus het lijkt mij wel te kloppen, het gaat dan meer om de notificatie dan de berekening toch?

Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
xces schreef op dinsdag 27 november 2007 @ 15:33:
Weet je wat het is, als je het resultaat (bij mijn genoemde oplossing) vervolgens meegeeft als strtotime bij de laagste datum, kom je wel bij de andere datum uit.. Dus het lijkt mij wel te kloppen, het gaat dan meer om de notificatie dan de berekening toch?
Dat is nou juist het hele punt. De berekening is niet lastig. De uitkomst ervan op een eenduidige en correcte manier weergeven is het probleem ;)

Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Semyon schreef op dinsdag 27 november 2007 @ 14:28:
[...]

Methode 2 heeft als resultaat dat
30 Augustus -> 1 Okt is 1 Maand 1 dag (eerst maand, naar 30 Sept dan nog 1 dag)
1 Sept -> 1 Okt is 1 Maand
Nu kunnen we voor 31 Augustus -> 1 Okt kiezen dat het hetzelfde is als 30 Aug of als 1 Sept
Wil je echt dat er tussen 31 Augustus -> 1 Okt even veel tijd zit als 30 Augustus -> 1 Okt?
Dit is zo te zien de methode die in alle software op mijn werk gebruikt wordt.

Dit is afgeleid van de add_months functie in Oracle. Deze functie werkt als volgt
Als je een aantal maanden (1e argument: x) bij een datum (tweede argument: DD/MM/YYYY) optelt, dan geldt
* als de datum de laatste dag van de maand is, dan blijft dit zo.
* als de datum niet de laatste dag van de maand is, dan wordt simpelweg het aantal maanden erbij opgeteld, dus DD / ([MM+x]mod12) / (YYYY+[MM+x]div12). Mocht dit een niet bestaande datum zijn omdat de maand minder dagen heeft, dan zal DD de laatste dag van die maand worden.

Grootste probleem van de functie is dat het geen bijectie is. Als x=1, dan worden zowel 30 augustus als 31 augustus gemapt naar 30 september.

De inverse functie (hoeveel maanden liggen er tussen twee datums) definieren we via de add_month functie: het aantal hele maanden is precies die x zodat add_months(startdatum,x+1) voorbij einddatum ligt. Het aantal overgebleven dagen is einddatum-add_months(startdatum,x).

Dit is methode 2. Het antwoord op de vraag is: ja, we willen dat er tussen 31 Augustus -> 1 Okt even veel tijd zit als 30 Augustus -> 1 Okt. Belangrijkste reden is dat we "de laatste dag van de maand" als een apart geval zien, en hier ook een andere logica op los laten.

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • Semyon
  • Registratie: April 2001
  • Laatst online: 10:15
Zip McOccup schreef op dinsdag 27 november 2007 @ 15:26:
[...]


Dit is een lastige. In feite zit er in beide gevallen 1 maand en 1 dag tussen... Maar beide gevallen zijn niet aan elkaar gelijk. Dat is het rare eraan. Wat vind jij dan? Tussen 31aug en 1 okt => 1 maand en 0 dagen?

Dat vind ik namelijk ook niet logisch.
Het is niet dat dit probleem net is komen boven drijven :) Ergens aan het begin van topic vroeg ik al wat je met deze situatie moet, het blijkt dat sommige mensen wel vinden dat het 1 Maand en 0 dagen is (bijv Creepy).

Wat ik vind :) ... Ik vind dat zoals ik gezegd heb vanaf het begin, "maand" moet laten vallen.
Er zijn in het topic nu al 4 verschillende manieren voor bij gekomen, het is dus niet dat een antwoord intuitief zal zijn. Wat je toch wilt, anders begrijpt niemand het. Verder heeft elke methode een heus probleem. Reken lekker met weken. Of defineer een vaste maand lengte.

Wat ook nog eens het voordeel heeft het dat je ook gewoon mktime() kan gebruiken zoals ik in mijn eerste post al aangaf, en je dus met 2 regels a 3 regels code klaar bent. Alle extra code maakt de boel alleen maar ellendiger.
Zip McOccup schreef op dinsdag 27 november 2007 @ 15:26:
[...]


Hier heb je dan natuurlijk wel een punt. Geen van de methoden geeft altijd een uniek antwoord.
Ik denk dat de beste oplossing is om de kleine "foutjes" voor lief te nemen. In feite is het natuurlijk niet eens fout ;) .
Misschien niet echt "fout" je krijgt echt hele rare dingen. Stel dat je per uur aftelt:

Nog "1 Maand en 1 dag en 2 uur" voordat ...
Nog "1 Maand en 1 dag en 1 uur" voordat ...
Nog "1 Maand en 1 dag" voordat ...
Nog "1 Maand en 1 dag en 23 uur" voordat ...

ga dat maar eens verkopen aan iemand die aan het wachten is.

sowieso slaan uren en minuten en secondes nergens op als je notatie die nauwkeurigheid bij dagen al heeft opgegeven.

Only when it is dark enough, can you see the stars


Acties:
  • 0 Henk 'm!

  • Zip McOccup
  • Registratie: Februari 2001
  • Laatst online: 15-07 15:47
Semyon schreef op dinsdag 27 november 2007 @ 22:37:
[...]


Misschien niet echt "fout" je krijgt echt hele rare dingen. Stel dat je per uur aftelt:

Nog "1 Maand en 1 dag en 2 uur" voordat ...
Nog "1 Maand en 1 dag en 1 uur" voordat ...
Nog "1 Maand en 1 dag" voordat ...
Nog "1 Maand en 1 dag en 23 uur" voordat ...

ga dat maar eens verkopen aan iemand die aan het wachten is.

sowieso slaan uren en minuten en secondes nergens op als je notatie die nauwkeurigheid bij dagen al heeft opgegeven.
Het is niet echt een gebrek aan nauwkurigheid, maar meer de tekortkoming van de definitie "maand". Om je nauwkeurigheid te behouden zou je dan idd het beste ervoor kunnen kiezen om de periode in weken/dagen enz uit te drukken.

Dat verklaart ook direct waarom ik op het internet nog nooit zo'n countdown heb gezien met maanden erin. Alleen weken en dagen :+

Een oplossing die ik eerder aandroeg kan echter wel altijd correct zijn; tel alleen de gehele tussenliggende maanden. Maar dan kan een periode bijv 1maand en 33 dagen worden... Ook niet echt wenselijk...
Pagina: 1 2 Laatste