Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    Problema con Formattazione data

    Ciao

    Lavorando in JS per creare una data uso questa forma, che sinora ha sempre funzionato:
    codice:
    var tmp  = new Date(1947, 1, 12); 
    var data1 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate());
    document.write(data1.toLocaleDateString())
    che quando vado a stampare mi restituisce la giusta data 12/1/1947.

    Ora ho un problema con questo piccolo script:
    codice:
    function calculateAge(birthday, now) { 
        var nowYear = now.getFullYear(); 
        var birtYear = birthday.getFullYear(); 
        var age = nowYear - birtYear; 
        return age; 
    } 
    
    var oggi = new Date(); 
    var tmp  = new Date(1947, 1, 12); 
    var data1 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate()); 
    var tmp  = new Date(1991, 01, 29); 
    var data2 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate()); 
    var tmp  = new Date(1963, 08, 28); 
    var data3 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate()); 
    
    var eta1 = calculateAge(data1, oggi); 
    var eta2 = calculateAge(data2, oggi); 
    var eta3 = calculateAge(data3, oggi); 
    
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data1.toLocaleDateString() + ":<br />") 
    document.write(eta1 + " anni<br />"); 
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data2.toLocaleDateString() + ":<br />") 
    document.write(eta2 + " anni<br />"); 
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data3.toLocaleDateString() + ":<br />") 
    document.write(eta3 + " anni<br />"); 
    che mi restituisce:
    tra 27/1/2016 e 12/1/1947:
    69 anni
    tra 27/1/2016 e 1/2/1991:
    25 anni
    tra 27/1/2016 e 27/8/1963:
    53 anni
    Gli anni restituiti immagino che siano giusti ma ho problema con le date che mi vengono restituite.
    La prima data (12/1/1947) è giusta
    La seconda e la terza data sono sbagliate e non riesco a capirne il motivo.

    La seconda data restituita è 1/2/1991 invece di 29/1/1991.
    La seconda data restituita è 27/8/1963 invece di 28/8/1963.

    Il codice mi sembra corretto, ma non riesco a capire questi errori.

    Grazie se riuscirete a farmi superare questo errore.

    Ultima modifica di micdas; 27-01-2016 a 01:33

  2. #2
    Moderatore di JavaScript L'avatar di br1
    Registrato dal
    Jul 1999
    Messaggi
    19,998
    quando crei la data devi tener presente che il mese va da 0 a 11.


    var tmp = new Date(1991, 01, 29); // 29 febbraio 1991 ??? non esiste, automaticamente trasformato in 1 marzo 1991
    var data2 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate());
    // passaggio intermedio:
    var data2 = new Date(1991, 2 -1, 1); // quindi 1 febbraio 1991

    Non mi risulta che la terza data restituita, nonostante l'errore concettuale, sia sbagliata
    Ultima modifica di br1; 27-01-2016 a 09:21
    Il guaio per i poveri computers e' che sono gli uomini a comandarli.

    Attenzione ai titoli delle discussioni: (ri)leggete il regolamento
    Consultate la discussione in rilievo: script / discussioni utili
    Usate la funzione di Ricerca del Forum

  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,696
    Ciao, quoto br1 per il discorso del 29 febbraio nell'anno non bisestile ma, a parte quello, io parlerei comunque di vari errori concettuali e non. Ho l'impressione che il tuo script faccia acqua un po' da tutte le parti.

    Mentre, riguardo questo:
    Non mi risulta che la terza data restituita, nonostante l'errore concettuale, sia sbagliata
    Da prendere con le pinze ciò che sto dicendo perché non ho idea del perché accada ma, testando (con Vista) su FF, CH e IE9, posso confermare che effettivamente, su FF e CH, sembrerebbe ci sia un qualche problema nella gestione delle date antecedenti il 1978 (a seconda anche del mese specificato), per cui viene restituito lo scarto di un giorno.

    Questo script:
    codice:
    var data = new Date(1963, 8, 28);
    console.log(data);
    console.log(data.toLocaleDateString());
    mi restituisce:

    - con FF
    Date 1963-09-27T22:00:00.000Z
    27/9/1963


    - con CH
    Sat Sep 28 1963 00:00:00 GMT+0200 (ora legale Europa occidentale)
    27/9/1963


    - con IE9
    Registro: Sat Sep 28 00:00:00 UTC+0200 1963
    Registro: sabato 28 settembre 1963


    Da notare che su CH l'oggetto Date riporta correttamente il giorno mentre avviene lo scarto solo con toLocaleDateString().

    Potrei pensare ad una qualche convenzione (diversa tra i vari browser) usata sull'impostazione dei fusi orari... ma non ho cercato molto a riguardo e non saprei cosa consigliare in questo caso, se non impostare anche un'ora "fittizia" sull'oggetto Date. Ripeto -da prendere con le pinze-.

    Una cosa tipo:
    codice:
    new Date(1963, 8, 28, 12);
    In tal caso i valori restituiti sono corretti in tutti i browser su cui ho testato.

    A prescindere da questi problemi, ti chiedo:

    - Che senso ha impostare un oggetto Date quando poi nella funzione fai solo il confronto con l'anno?
    In questo caso non avrebbe più senso usare una semplice variabile in cui riportare solo l'anno, e quindi confrontare questo valore con l'anno della data corrente?

    A dirla tutta, se vuoi ottenere l'età reale, sarebbe opportuno fare la differenza tra la data corrente e la data, per intero, di nascita; non solo tra il valore degli anni, perché questo potrebbe restituire uno scarto di un intero anno, sfalsando quindi il risultato... Oggi è 27/01/2016, supponendo che io sia nato il 31/12/2015, dovrei avere meno di un mese, mentre la tua funzione mi restituisce "1 anni"

    - Che senso ha usare un oggetto Date temporaneo, facendo quel passaggio intermedio (evidenziato da br1), se poi nella riga dopo vai semplicemente a ri-passare i tre dati in un ulteriore oggetto Date, decrementando giusto il mese (che peraltro è un procedimento che può restituire risultati inattesi, come hai constatato nel secondo caso di cui br1 ha chiarito il problema)?
    Non puoi semplicemente impostare l'oggetto Date decrementando direttamente di 1 il valore del mese, senza il passaggio intermedio?

    - Altro piccolo "errore" di brutta programmazione è la dichiarazione multipla della variabile tmp. L'interprete JavaScript sorvola su questo ma è chiaro che è brutto a vedersi e che non ti serve a nulla dichiarare la stessa variabile più volte all'interno di uno stesso scope. Anche se assume dei valori differenti, andrebbe dichiarata una sola volta, magari all'inizio del codice.

    - Ancora, l'uso di valori numerici preceduti dallo 0, potrebbe comportare una falsa interpretazione in JavaScript che li converte automaticamente (o cerca di farlo) in valori ottali.
    Questa riga, presa così com'è:
    codice:
    var tmp  = new Date(1963, 08, 28);
    su FF genera il seguente errore:
    codice:
    SyntaxError: 08 is not a legal ECMA-262 octal constant
    Meglio, in questo caso, scrivere il numero senza zeri iniziali.

    Lavorando in JS per creare una data uso questa forma, che sinora ha sempre funzionato
    Buon per te
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4
    Grazie a br1 e KillerWorm per le risposte.
    Avete entrambi ragione, però dovete sapere che sino ad un mese fa il Javascript era per me un tabù e non pensavo minimamente di poter aprire una discussione su questo argomento.
    Quello che sto facendo è solo un primo studio per trovare la differenza in anni tra due date.
    Già dalle vostre risposte sto rivedendo il mio codice per cercare di ovviare a questi errori logici e programmatici.

    @br1
    quando crei la data devi tener presente che il mese va da 0 a 11
    Il fatto che in JS i mesi iniziano da 0 e non da 1 lo avevo capito, per questo quell'istruzione
    codice:
    data1 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate())
    cerca di riportare la data da "1" (gennaio), che per il JS corrisponde a febbraio, al giusto valore che dovrebbe essere "0".

    @KillerWorm
    ...sembrerebbe ci sia un qualche problema nella gestione delle date antecedenti il 1978...
    So che in JS la gestione della data restituisce il numero dei millisecondi trascorsi dalla mezzanotte del 1 gennaio 1970.
    Che senso ha impostare un oggetto Date quando poi nella funzione fai solo il confronto con l'anno?
    ...........
    A dirla tutta, se vuoi ottenere l'età reale, sarebbe opportuno fare la differenza tra la data corrente e la data, per intero, di nascita
    Sto iniziando da questo passaggio.
    So che la differenza tra i soli anni è troppo semplicistico e che invece si dovrebbe eseguire la differenza sull'intera data. Ma poi occorre lavorare sulla differenza dei due timestamp. (penso di arrivarci)
    Ma per ora sono solo nella fase di apprendimento e spero di andare oltre questo limite.
    Che senso ha usare un oggetto Date temporaneo, facendo quel passaggio intermedio (evidenziato da br1), se poi nella riga dopo vai semplicemente a ri-passare i tre dati in un ulteriore oggetto Date, decrementando giusto il mese
    Solo perchè presuppongo di ricevere la data o da un input da un form o da una modifica allo script fatta anche in modo distratto (penso gennaio e scrivo 1).
    Altro piccolo "errore" di brutta programmazione è la dichiarazione multipla della variabile tmp
    Colpa del JS che non si lamenta apertamente e del VB che in caso di doppia dichiarazione di una variabile mi redarguisce aspramente. Già provveduto alla modifica delle dichiarazioni.
    Ancora, l'uso di valori numerici preceduti dallo 0
    E' solo colpa del mio copia-incolla fatto in un momento di test. Comunque 0 o non 0 il risultato non cambia.
    Lavorando in JS per creare una data uso questa forma, che sinora ha sempre funzionato
    Buon per te
    E' probabile che non mi sono ancora trovato a sperimentare con questo tipo di date.

    Quel che mi stupisce dalla creazione e gestione delle date è che nonostante il timestamp del JS inizia dal 1970, per la data che si riferisce al 1947, tutto è come atteso. Mentre i problemi sorgono per la data del 1991 (parzialmente giustificato a causa del mese) e per la data del 1963.
    Comunque sto lavorando al cambiamento dello script e tra breve ve lo mostrerò.
    Intanto attendo altri suggerimenti.

    Grazie

  5. #5
    Ciao,

    questa discussione mi ha incuriosito. Ho cercato un po' e ho trovato questo link che condivido:

    https://bugzilla.mozilla.org/show_bug.cgi?id=1122571

  6. #6
    Ciao MAeSI,
    ho visitato il link che hai postato e vedo che il problema non è solo mio.

    Intanto sono andato avanti col mio test per il calcolo degli anni.
    Per il momento lo script è ancora quello che ho mostrato perchè mi sto concentrando sulla formattazione delle date più che sul conteggio degli anni.
    Nel passaggio dopo la tmp, trascrivendo le varie parti di data ho aggiunto anche la porzione dell'ora in questa maniera:
    codice:
    tmp = new Date(1963, 8, 28);
    var data3 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate(), 1);
    Dopo questa modifica la situazione della data (1991, 1, 29) rimane sempre 1/2/1991 e mi sembra che, come dice br1 non c'è rimedio.
    Tuttavia per la data (1963, 08, 28) ora non è più 27/8/1963 ma è diventata quella giusta e cioè 28/8/1963.

    Per utilità di quanti si troveranno a leggere questa discussione posterò il codice modificato avvisando che comunque NON E' IDONEO PER IL CALCOLO DELLE ORE, come faceva notare KillerWorm. Per completezza ho aggiunto anche le date da lui suggerito.


    codice:
    function calculateAge(birthday, now) { 
        var nowYear = now.getFullYear(); 
        var birtYear = birthday.getFullYear(); 
        var age = nowYear - birtYear; 
        return age; 
    } 
    
    var oggi = new Date(); 
    var tmp; 
    tmp = new Date(1947, 1, 12); 
    var data1 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate(), 1); 
    tmp = new Date(1991, 1, 29); 
    var data2 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate(), 1); 
    tmp = new Date(1963, 8, 28); 
    var data3 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate(), 1); 
    tmp = new Date(2015, 12, 31); 
    var data4 = new Date(tmp.getFullYear(), tmp.getMonth()-1, tmp.getDate(), 1); 
    
    var eta1 = calculateAge(data1, oggi); 
    var eta2 = calculateAge(data2, oggi); 
    var eta3 = calculateAge(data3, oggi); 
    var eta4 = calculateAge(data4, oggi); 
    
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data1.toLocaleDateString() + ": <strong>") 
    document.write(eta1 + " anni</strong><br />"); 
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data2.toLocaleDateString() + ": <strong>") 
    document.write(eta2 + " anni</strong><br />"); 
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data3.toLocaleDateString() + ": <strong>") 
    document.write(eta3 + " anni</strong><br />"); 
    document.write("tra " + oggi.toLocaleDateString() + " e "  
            + data4.toLocaleDateString() + ": <strong>") 
    document.write(eta4 + " anni</strong><br />");
    Il risultato è il seguente:
    tra 27/1/2016 e 12/1/1947: 69 anni
    tra 27/1/2016 e 1/2/1991: 25 anni // la data non viene interpretata nel modo giusto
    tra 27/1/2016 e 28/8/1963: 53 anni // ora la data viene interpretata correttamente
    tra 27/1/2016 e 31/12/2015: 1 anni // ovviamente l'anno è sbagliato
    Ciao

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.