2013-07-18 14 views
9

sto cercando di ottenere da un tempo di cella formattata (hh: mm: ss) il valore delle ore, i valori possono essere più grande 24:00:00 per esempio 20000: 00 : 00 dovrebbe dare 20000:Come leggere i valori di tempo corretti da Google Spreadsheet

Tabella:

two Google Spread Sheet

se il vostro leggere il valore di E1:

var total = sheet.getRange("E1").getValue(); 
Logger.log(total); 

il risultato è:

0.123.516,41 mila

Sab 12 Apr 07:09:21 GMT + 00: 09 1902

Ora ho cercato di convertirlo in un oggetto Date e ottenere l'Unix timestamp di esso:

var date = new Date(total); 
    var milsec = date.getTime(); 
    Logger.log(Utilities.formatString("%11.6f",milsec)); 
    var hours = milsec/1000/60/60; 
    Logger.log(hours) 

1374127872020,000000

381702,1866722222

La domanda è come ottenere il valore corretto di 20000?

risposta

8

Per i futuri lettori. Ci sono due nuove funzioni getDisplayValue() e getDisplayValues() fornite da persone Script app che restituiscono il valore visualizzato. Controlla la documentazione here

+0

Usando questo per un documento di testo di Google Documenti, ottengo "non definito" – Ralf

+0

Domanda e risposta riguarda specificamente i fogli. – llaaalu

+1

Grazie, sì, ho bisogno di recuperare in modo specifico orari e date dai fogli in documenti. Visualizza valori, non incasinato da fusi orari o altro. Ora ho lavorato attorno ad esso impostando fusi orari in tutti i file e gli script relativi a "GMT (senza l'ora legale)". – Ralf

6

Il valore che si vede (Sab 12 Aprile 07:09:21 GMT + 00: 09 1902) è la data equivalente in JavaScript tempo standard che è 20000 ore più tardi la data rif.

si dovrebbe rimuovere semplicemente il valore di riferimento foglio di calcolo dal vostro risultato per ottenere quello che vuoi.

Questo codice fa il trucco:

function getHours(){ 
    var sh = SpreadsheetApp.getActiveSpreadsheet(); 
    var cellValue = sh.getRange('E1').getValue(); 
    var eqDate = new Date(cellValue);// this is the date object corresponding to your cell value in JS standard 
    Logger.log('Cell Date in JS format '+eqDate) 
    Logger.log('ref date in JS '+new Date(0,0,0,0,0,0)); 
    var testOnZero = eqDate.getTime();Logger.log('Use this with a cell value = 0 to check the value to use in the next line of code '+testOnZero); 
    var hours = (eqDate.getTime()+ 2.2091616E12)/3600000 ; // getTime retrieves the value in milliseconds, 2.2091616E12 is the difference between javascript ref and spreadsheet ref. 
    Logger.log('Value in hours with offset correction : '+hours); // show result in hours (obtained by dividing by 3600000) 
} 

enter image description here

nota: questo codice ottiene solo poche ore, se la vostra intenzione di avere minuti e/o secondi allora dovrebbe essere sviluppato per gestire anche questo. .. fateci sapere se ne avete bisogno.


EDIT: una parola di spiegazione ...

Fogli di utilizzare una data di riferimento del 12/30/1899, mentre Javascript sta usando 01/01/1970, che significa che v'è una differenza di 25568 giorni tra entrambi i riferimenti. Tutto ciò presupponendo di utilizzare lo stesso fuso orario in entrambi i sistemi. Quando convertiamo un valore di data in un foglio di calcolo in un oggetto data javascript, il motore GAS aggiunge automaticamente la differenza per mantenere la coerenza tra le date.

In questo caso non vogliamo conoscere la data reale di qualcosa ma piuttosto un valore di ore assolute, cioè una "durata", quindi dobbiamo rimuovere lo sfasamento di 25568 giorni. Questo viene fatto usando il metodo getTime() che restituisce i millisecondi contati dalla data di riferimento JS, l'unica cosa che dobbiamo sapere è il valore in millisecondi della data di riferimento del foglio elettronico e sottrarre questo valore dall'oggetto data reale. Quindi un po 'di matematica per ottenere ore invece di millisecondi e abbiamo finito.

So che questo sembra un po 'complicato e non sono sicuro che il mio tentativo di spiegare chiarirà davvero la domanda, ma vale sempre la pena provare, vero?

Ad ogni modo il risultato è quello di cui avevamo bisogno fino a quando (come indicato nei commenti) si regola il valore di offset in base alle impostazioni del fuso orario del foglio di calcolo. Ovviamente sarebbe possibile lasciare che lo script gestisse automaticamente, ma avrebbe reso lo script più complesso, non sicuro che fosse davvero necessario.

+0

Modulo dove viene questo valore in arrivo: 2.2091616E12? – patrick

+0

vedere il commento nel codice –

+0

ok grazie mille, questo mi ha risparmiato giorni inn investigazione – patrick

16

Espandendo ciò che Serge ha fatto, ho scritto alcune funzioni che dovrebbero essere un po 'più facili da leggere e tenere conto delle differenze di fuso orario tra il foglio di calcolo e lo script.

function getValueAsSeconds(range) { 
    var value = range.getValue(); 

    // Get the date value in the spreadsheet's timezone. 
    var spreadsheetTimezone = range.getSheet().getParent().getSpreadsheetTimeZone(); 
    var dateString = Utilities.formatDate(value, spreadsheetTimezone, 
     'EEE, d MMM yyyy HH:mm:ss'); 
    var date = new Date(dateString); 

    // Initialize the date of the epoch. 
    var epoch = new Date('Dec 30, 1899 00:00:00'); 

    // Calculate the number of milliseconds between the epoch and the value. 
    var diff = date.getTime() - epoch.getTime(); 

    // Convert the milliseconds to seconds and return. 
    return Math.round(diff/1000); 
} 

function getValueAsMinutes(range) { 
    return getValueAsSeconds(range)/60; 
} 

function getValueAsHours(range) { 
    return getValueAsMinutes(range)/60; 
} 

È possibile utilizzare queste funzioni in questo modo:

var range = SpreadsheetApp.getActiveSheet().getRange('A1'); 
Logger.log(getValueAsHours(range)); 

Inutile dire, questo è un sacco di lavoro per ottenere il numero di ore da un intervallo. Si prega di stella Issue 402 che è una richiesta di funzionalità per avere la possibilità di ottenere il valore di stringa letterale da una cella.

+0

Grazie per questa bella piccola funzione, molto più conveniente del mio codice ;-) btw ho fatto una confusione tra JS e SS riferimento nel mio tentativo di spiegare, ho corretto la mia spiegazione ora sperando che sia comprensibile a chiunque ... –

+0

un dettaglio : Ho appena notato che per i fusi orari "speciali" come 03:30, ad esempio, non restituisce un intero ... aggiungere un Math.round() sui valori restituiti finali (minuti e ore) potrebbe essere utile in questo speciale Astuccio. Dopotutto non disturba gli altri casi ;-) –

+0

Grazie Serge, ho regolato la logica in modo tale da gestire correttamente gli offset del fuso orario che non sono intere ore. –

4

Per semplici fogli di calcolo si può essere in grado di cambiare il fuso orario GMT foglio di calcolo per, senza risparmio di luce del giorno e usare questa breve funzione di conversione: la risposta di

function durationToSeconds(value) { 
    var timezoneName = SpreadsheetApp.getActive().getSpreadsheetTimeZone(); 
    if (timezoneName != "Etc/GMT") { 
    throw new Error("Timezone must be GMT to handle time durations, found " + timezoneName); 
    } 
    return (Number(value) + 2209161600000)/1000; 
} 

Eric Koleda è per molti versi più generali. Ho scritto questo mentre cercavo di capire come gestisce i casi d'angolo con il fuso orario del foglio di calcolo, il fuso orario del browser e le variazioni del fuso orario nel 1900 in Alaska e Stoccolma.

+0

"GMT senza l'ora legale" - geniale. Grazie mille, amico. – Ralf

Problemi correlati