Autore Topic: CountDown  (Letto 1441 volte)

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
CountDown
« il: 17 Aprile 2012, 11:25:23 CEST »
0
Guardata un pochino questo codice che dovrebbe visualizzare un countdown nel formato giorni : ore : minuti e secondi

Codice (Java): [Seleziona]
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tempo_text = (TextView)findViewById(R.id.tempo_textv);
        new TempoIndietro(86400000,1000).start(); //1 giorno
    }
   
    public class TempoIndietro extends CountDownTimer{

                public TempoIndietro(long millisInFuture, long countDownInterval) {
                        super(millisInFuture, countDownInterval);      
                }

                @Override
                public void onFinish() {
                }

                @Override
                public void onTick(long millisUntilFinished) {
                        SimpleDateFormat df = new SimpleDateFormat("dd : HH: mm: ss");
            df.setTimeZone(TimeZone.getDefault());
            String risultato = df.format(new Date(millisUntilFinished)); //arg0 tempo in ms preso dall'onTick
            tempo_text.setText(risultato);

                };
       
    }

Qualcuno mi saprebbe dire perchè se setto 86400000 (quindi 1 giorno) il countdown lo visualizzo così 01 : 23 : 59 : 59 cioè mi aggiunge 1 giorno perchè dovrebbe essere 00 : 23 : 59 : 59 .(

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:CountDown
« Risposta #1 il: 17 Aprile 2012, 12:24:29 CEST »
+1
Perché stai partendo da un presupposto sbagliato: che SimpleDateFormat formatti un tempo, invece formatta una data:-)

Codice (Java): [Seleziona]
      long milliseconds = 86400000;
      Date data = new Date(milliseconds); // 1 gennaio 1970 + 1 giorno!
     
      TimeZone gmt = TimeZone.getTimeZone("GMT"); // greenwich meridian time
      String format = "dd : HH: mm: ss";
      String extendFormat = "dd MMM : HH: mm: ss";
      SimpleDateFormat df = new SimpleDateFormat(format);
      SimpleDateFormat df2 = new SimpleDateFormat(extendFormat);
      df.setTimeZone(gmt);
      df2.setTimeZone(gmt);
      String risultato = df.format(data); // 02 : 00 : 00 : 00  - sbagliato??
      String risultato2 = df2.format(data); // 02 gen : 00 : 00 : 00  - è giusto! perché la data è effettivamente il 2 gennaio

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:CountDown
« Risposta #2 il: 17 Aprile 2012, 12:27:07 CEST »
0
Si infatti, in una data non esiste un giorno col numero ZERO. Sarà almeno 1.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #3 il: 17 Aprile 2012, 12:53:37 CEST »
0
Perché stai partendo da un presupposto sbagliato: che SimpleDateFormat formatti un tempo, invece formatta una data:-)

Codice (Java): [Seleziona]
      long milliseconds = 86400000;
      Date data = new Date(milliseconds); // 1 gennaio 1970 + 1 giorno!
     
      TimeZone gmt = TimeZone.getTimeZone("GMT"); // greenwich meridian time
      String format = "dd : HH: mm: ss";
      String extendFormat = "dd MMM : HH: mm: ss";
      SimpleDateFormat df = new SimpleDateFormat(format);
      SimpleDateFormat df2 = new SimpleDateFormat(extendFormat);
      df.setTimeZone(gmt);
      df2.setTimeZone(gmt);
      String risultato = df.format(data); // 02 : 00 : 00 : 00  - sbagliato??
      String risultato2 = df2.format(data); // 02 gen : 00 : 00 : 00  - è giusto! perché la data è effettivamente il 2 gennaio

Aspetta non ci ho capito nulla...ti spiego direttamente quello che dovrei fare :
1) Fornire una data ed ora all'applicazione del tipo 18/04/2012 21:00
2) Calcolare la data ed ora del dispositivo
3) Fare la differenza tra le 2
4) La differenza in millisecondi la devo mettere nel CountDownTimer(differenza,1000);

Come dovrei fare ???  ???

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:CountDown
« Risposta #4 il: 17 Aprile 2012, 14:11:35 CEST »
0
Per prima cosa non usare il SimpleDateFormat, perché ha un altro scopo rispetto a quello che ti serve.

Quello che hai fatto va benissimo, ma se vuoi formattare la differenza esprimendola in giorni/ore/minuti/secondi devi formattartela a mano (java, e quindi android, non ha un formattatore simile di suo).

Io farei una classe per questo tipo di formattazione, in stile SimpleDateFormat ma che formatti un tempo e non una data.
Qualcosa del tipo:

Codice (Java): [Seleziona]
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class SimpleTimeFormat {
  protected String           pattern = "$HH$ : $mm$ : $ss$";

  public static final String ms      = "$ms$";
  public static final String ss      = "$ss$";
  public static final String mm      = "$mm$";
  public static final String HH      = "$HH$";
  public static final String dd      = "$dd$";

  public SimpleTimeFormat(String pattern) {
    this.pattern = pattern;
  }

  public String format(long milliseconds) {
    String out = "?";

    long time = milliseconds;

    long milli = time - ((time / 1000) * 1000);
    time -= milli;
    time /= 1000;

    long sec = time - ((time / 60) * 60);
    time -= sec;
    time /= 60;

    long min = time - ((time / 60) * 60);
    time -= min;
    time /= 60;

    long hour = time - ((time / 24) * 24);
    time -= hour;
    time /= 24;

    long day = time;

    out = pattern;
    out = out.replace(ms, "" + milli);
    out = out.replace(ss, "" + sec);
    out = out.replace(mm, "" + min);
    out = out.replace(HH, "" + hour);
    out = out.replace(dd, "" + day);

    return out;
  }

  public static void main(String[] args) {

    Calendar cal = GregorianCalendar.getInstance();

    cal.set(Calendar.DAY_OF_MONTH, 1);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);

    Date firstDayOfThisMonth = cal.getTime();
    Date today = new Date();

    long diff = today.getTime() - firstDayOfThisMonth.getTime();

    SimpleTimeFormat test = new SimpleTimeFormat("Since first day of month: $dd$ days $HH$ hours $mm$ minutes $ss$ seconds $ms$ milliseconds");

    String out = test.format(diff);

    System.out.println(out);
  }
}

Un po' grezza e da ripulire/sistemare, ma funziona.

E la userei al posto del SimpleDateFormat:
Codice (Java): [Seleziona]
  @Override
  public void onTick(long millisUntilFinished) {
    SimpleTimeFormat tf = new SimpleTimeFormat("$dd$ : $HH$: $mm$: $ss$");    
    String risultato = tf.format(millisUntilFinished); // arg0 tempo
                                                                 // in ms preso
                                                                 // dall'onTick
    tempo_text.setText(risultato);
  };

« Ultima modifica: 17 Aprile 2012, 14:15:48 CEST da Sakazaki »

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #5 il: 17 Aprile 2012, 14:27:23 CEST »
0
GRAZIE ! ora si che funziona!! unico problema è che se metto come date

OGGI : 17/04/2012 14:27
FINE : 17/05/2012  14:27

mi dà 31 giorni invece che 30...

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:CountDown
« Risposta #6 il: 17 Aprile 2012, 14:47:44 CEST »
0
OGGI : 17/04/2012 14:27
FINE : 17/05/2012  14:27

mi dà 31 giorni invece che 30...

Come detto l'ho scritto di corsa, per cui ci sta benissimo che non sia a prova d'errore.

Però da una prova rapida a "me va"(TM)

Codice (Java): [Seleziona]
    cal = new GregorianCalendar();
    cal.set(Calendar.DAY_OF_MONTH, 17);
    cal.set(Calendar.MONTH, 3);
    cal.set(Calendar.HOUR_OF_DAY, 14);
    cal.set(Calendar.MINUTE, 27);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
   
    Date data1 = cal.getTime();
   
    cal = new GregorianCalendar();
    cal.set(Calendar.DAY_OF_MONTH, 17);
    cal.set(Calendar.MONTH, 4);
    cal.set(Calendar.HOUR_OF_DAY, 14);
    cal.set(Calendar.MINUTE, 27);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
   
    Date data2 = cal.getTime();
   
    diff = data2.getTime() - data1.getTime();
   
    test = new SimpleTimeFormat("$dd$ - $HH$ - $mm$ - $ss$");
    out = test.format(diff); // 30 - 0 - 0 - 0 ok

Prova a giocarci un po' per capire cosa non torna, e magari quando lo scopri faccelo sapere (mi sa che tornerà utile pure a me questo TimeFormat...)  :-)

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #7 il: 17 Aprile 2012, 14:53:05 CEST »
0
Se la data la metti manualmente funziona mentre se te la fai ricavare non va...a questo punto penso che dipenda dal TimeZone

Dato che l'applicazione la usano anche gli stranieri e che quindi possono avere fusorario diverso dal nostro (quindi anche data) occorrerebbe trovare un modo per prendere il TimeZone del loro dispositivo non vedo alternative...

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:CountDown
« Risposta #8 il: 17 Aprile 2012, 15:46:55 CEST »
0
Se la data la metti manualmente funziona mentre se te la fai ricavare non va...a questo punto penso che dipenda dal TimeZone

Dato che l'applicazione la usano anche gli stranieri e che quindi possono avere fusorario diverso dal nostro (quindi anche data) occorrerebbe trovare un modo per prendere il TimeZone del loro dispositivo non vedo alternative...

Può essere che sia il TimeZone che ci mette del suo, non sapendo bene come ricavi le date...

Per toglierti il dubbio come dici converrebbe convertire entrambe le date ad un fuso orario neutro come "GMT" (in rete ci sono montagne di esempi a riguardo), controllare il loro valore dopo la conversione (giusto per evitare sorprese... che il TimeZone riserva sempre!), fare la differenza e vedere se effettivamente ottieni il risultato atteso.


Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #9 il: 17 Aprile 2012, 16:35:32 CEST »
0
Aspetta perchè il mio scopo è quello di inserire una data tipo 19/04/2012 ore 21:00 (che è la data ed ora di inizio di un telefilm in america) ma in italia devono visualizzare come data 20/04/2012 ore 02:00 del mattino e così via in base al paese dove si trova l'utente....è un casino.... :(

Non posso fare come dici tu perchè sul countdown del mio cellulare devo visualizzare che manca ad esempio 1 giorno e 3 ore quello in cina visualizzerà che ne sò che mancano 12 ore e 30 minuti....mi spiego...

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:CountDown
« Risposta #10 il: 17 Aprile 2012, 17:48:59 CEST »
+1
Aspetta perchè il mio scopo è quello di inserire una data tipo 19/04/2012 ore 21:00 (che è la data ed ora di inizio di un telefilm in america) ma in italia devono visualizzare come data 20/04/2012 ore 02:00 del mattino e così via in base al paese dove si trova l'utente....è un casino.... :(

Non posso fare come dici tu perchè sul countdown del mio cellulare devo visualizzare che manca ad esempio 1 giorno e 3 ore quello in cina visualizzerà che ne sò che mancano 12 ore e 30 minuti....mi spiego...

Calma e sangue freddo, qui stiamo parlando di due cose leggermente diverse (se non sto prendendo una colossale cantonata):

1 - fornita una data espressa in un certo fuso orario (19/04/2012 ore 21:00 East Coast), convertirla nell'equivalente locale (20/04/2012 ore 04:00 Roma, ci sono 7 ore di differenza se non ricordo male)

2 - fornita una data in un certo fuso orario dire quanti giorni/ore/minuti/secondi mancano all'evento, rispetto al fuso orario locale.

Entrambe le cose le puoi risolvere facilmente solo sapendo il fuso orario in cui è espressa la data bersaglio e il fuso orario locale di riferimento (che in realtà hai sempre, perché e quello che usa il dispositivo di default); se hai queste due informazioni è solo una questione di conversione.

1 - per convertire le date puoi usare le funzioni che seguono:

Codice (Java): [Seleziona]
    /**
     * Fornita una data con timezone locale la converte nell'equivalente data
     * con timezone specificato
     *
     * @param data data da convertire
     * @param timeZoneCode codice del timezone di destinazione
     * @return la data corrispondente nel fuso orario richiesto
     * @throws ParseException se non è possibile eseguire la conversione in base al timeZoneCode fornito
     */

    public static Date convertToTimeZone(Date data, String timeZoneCode) throws ParseException {      
      return convertFromTimeZone2TimeZone(data, Calendar.getInstance().getTimeZone().getID(), timeZoneCode);
    }
   
    /**
     * Fornita una data con timezone conosciuto la converte nell'equivalente data
     * locale
     *
     * @param data data da convertire
     * @param timeZoneCode codice del timezone in cui è espressa la data
     * @return la data corrispondente nel fuso orario locale
     * @throws ParseException se non è possibile eseguire la conversione in base al timeZoneCode fornito
     */

    public static Date convertFromTimeZone(Date data, String timeZoneCode) throws ParseException {      
      return convertFromTimeZone2TimeZone(data, timeZoneCode, Calendar.getInstance().getTimeZone().getID());
    }
   
    /**
     * Fornita una data, il timezone in cui è espressa e un timezone di destinazione
     * converte la data da un timezone all'altro.
     *
     * @param data data da convertire
     * @param fromTimeZone codice del timezone in cui è espressa la data
     * @param toTimeZone codice del timezone in cui si vuole convertire la data
     * @return la data corrispondente nel fuso orario richiesto
     * @throws ParseException se non è possibile eseguire la conversione in base al timeZoneCode fornito
     */

    public static Date convertFromTimeZone2TimeZone(Date data, String fromTimeZone, String toTimeZone) throws ParseException {
      SimpleDateFormat dateFormatFrom = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss:SSS");      
      dateFormatFrom.setTimeZone(TimeZone.getTimeZone(fromTimeZone));
     
      SimpleDateFormat dateFormatTo = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss:SSS");
      dateFormatTo.setTimeZone(TimeZone.getTimeZone(toTimeZone));
     
      Date convertedDate = dateFormatFrom.parse(dateFormatTo.format(data));
      return convertedDate;
    }

Se hai la data bersaglio e il suo fuso orario (GMT-5 per l'east coast) puoi sempre sapere qual'è l'equivalente data/ora locale.

2 - Per fare la differenza devi confrontare date omogenee tra loro, ma con le funzioni che ho scritto sopra puoi saltellare a qualsiasi fuso orario desideri

Codice (Java): [Seleziona]
   // ora... nel fuso orario del dispositivo
   Date oggiLocale = new Date();

   // da dove pigli pigli, basta che sei certo del fuso orario a cui fa riferimento
   Date dataEastCoast = ...;

   // converti nel fuso orario del dispositivo
   Date equivalenteDataLocale = convertFromTimeZone(dataEastCoast, "GMT-5");

  // differenza tra date omogenee tra loro
  long quantoManca = equivalenteDataLocale .getTime() - oggiLocale.getTime();

  // formatto quanto manca
  SimpleTimeFormat tf = new SimpleTimeFormat("$dd$ : $HH$: $mm$: $ss$");    
  String risultato = tf.format(quantoManca);

Ripeto: sempre che non ho preso una cantonata, e sempre se sai il fuso orario in cui è espressa la data bersaglio.
« Ultima modifica: 17 Aprile 2012, 18:04:00 CEST da Sakazaki »

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #11 il: 17 Aprile 2012, 18:04:43 CEST »
0
Cavolo sei grande è proprio quello che mi serviva!! Che poi non sò come hai fatto a capire che il TimeZone della data 19/04/2012 21:00 era proprio quello della East Coast !!!!  :-o

Ora mi devo un attimino studiare il codice ed adattarlo alle mie esigenze...certo che per creare un semplice countdown universale è proprio comico che si debba fare tutto sto casino!!!

Comunque....il TimeZone dell'utente lo prendo dal dispositivo con TimeZone.getDefualt(); quello della East Coast sai qual'è il codice ?

REP+ per te ;)

Offline Sakazaki

  • Utente normale
  • ***
  • Post: 396
  • Respect: +74
    • Mostra profilo
  • Dispositivo Android:
    Sony xperia Z
  • Play Store ID:
    Saka Labs
  • Sistema operativo:
    Windows 8
Re:CountDown
« Risposta #12 il: 17 Aprile 2012, 18:15:22 CEST »
0
Cavolo sei grande è proprio quello che mi serviva!! Che poi non sò come hai fatto a capire che il TimeZone della data 19/04/2012 21:00 era proprio quello della East Coast !!!!  :-o

Ho sparato a caso!!!

Citazione
Comunque....il TimeZone dell'utente lo prendo dal dispositivo con TimeZone.getDefualt(); quello della East Coast sai qual'è il codice?

Esattamente quello che ho usato nell'esempio GMT-5

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #13 il: 17 Aprile 2012, 18:17:12 CEST »
0
:D Grande...appena ho il codice pronto lo posto tanto servirà anche ad altri ;)

Offline mimmog

  • Utente senior
  • ****
  • Post: 731
  • Respect: +11
    • MisterX_Dev
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Note e Galaxy Nexus
  • Play Store ID:
    MisterX_Dev
  • Sistema operativo:
    Windows 7
Re:CountDown
« Risposta #14 il: 18 Aprile 2012, 14:20:28 CEST »
0
Non riesco a capire una cosa....

Passo la data a convertFromTimeZone così :
Codice (Java): [Seleziona]
Calendar c = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 19);
cal.set(Calendar.MONTH, 04);
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.HOUR_OF_DAY, 21);
cal.set(Calendar.MINUTE, 00);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date data_convertita = convertFromTimeZone(data, "GMT-5");
ma mi restituisce data_convertita = Sun May 20 04:00:00 CEST 2012

Mi dovrebbe ritornare 20/04/2012 21:00...