Italian gestione orario-scadenze

guidoarfini

Member
Licensed User
Longtime User
Dove sbaglio? perchè mi da un calcolo sbagliato di tempo alla rimanenza?Sia che usi il giorno o solamente l'ora?Grazie

Dim GiornoAttuale,GiornoScadenza,OraAttuale,OraScadenza,ore,minuti,secondi As String


Sub BtnSalvaSER_Click
scorrimento.Initialize("Scorrimento",1000)
scorrimento.Enabled=True
End Sub
Sub scorrimento_Tick
Dim AllaScadenza,Days,hours,Minutes,Seconds,now As Long

GiornoAttuale = DateTime.Date(DateTime.Now)
OraAttuale = DateTime.Time(DateTime.Now)

LbloraAttuale.Text = GiornoAttuale & " " & OraAttuale

Dim date1, date2 As Long
'date1 = DateTime.DateParse(GiornoAttuale) +DateTime.TimeParse(oraAttuale)
date1 = DateTime.TimeParse(oraAttuale)
'date2 = DateTime.DateParse(GiornoAttuale) + DateTime.TimeParse("23:59:59")
date2 = DateTime.TimeParse("23:59:59")
AllaScadenza = date2 - date1

seconds=DateTime.GetSecond(AllaScadenza)
minutes=DateTime.GetMinute(AllaScadenza)
Hours=DateTime.GetHour(AllaScadenza)


'DateTime.DateFormat = "yyyy-MM-dd" 'set for sqlite
'DateTime.TimeFormat = "HH:mm:ss" 'also for sqlite

LblOraFine.Text= hours & ":" & minutes & ":" & seconds


End Sub
 

magalt

Member
Licensed User
Longtime User
Ciao Guido
La cosa sembra dipendere dalla mancata considerazione della "timezone".
Vedi http://www.b4x.com/forum/basic4android-updates-questions/8775-time-zones.html#post52263

Ho modificato il tuo codice adeguandolo per tener conto anche del fattore mancante.

B4X:
Sub Globals
   Dim BtnSalvaSER As Button
   Dim scorrimento As Timer 
End Sub

Sub BtnSalvaSER_Click
   Scorrimento.Initialize("Scorrimento",1000)
   Scorrimento.Enabled = True
End Sub

Sub Scorrimento_Tick
   Dim AllaScadenza, Adesso As Long
   Dim Hours, Minutes, Seconds As String
   Dim GiornoAttuale, OraAttuale As String

   Adesso = DateTime.now : 'Memorizzo subito il tempo per evitare di usare tempi diversi nelle successive chiamate a DateTime.now
   GiornoAttuale = DateTime.Date(Adesso)
   OraAttuale = DateTime.Time(Adesso)

   Dim date1, date2 As Long
   date1 = DateTime.TimeParse(OraAttuale) + DateTime.GetTimeZoneOffsetAt(Adesso) * DateTime.TicksPerHour
   date2 = DateTime.TimeParse("23:59:59")
   AllaScadenza = date2 - date1

   Seconds = NumberFormat(DateTime.GetSecond(AllaScadenza), 2, 0)
   Minutes = NumberFormat(DateTime.GetMinute(AllaScadenza), 2, 0)
   Hours = NumberFormat(DateTime.GetHour(AllaScadenza), 1, 0)

   Msgbox("Mancano " & Hours & ":" & Minutes & ":" & Seconds & " alle 23:59:59", "Data e ora di adesso: " & GiornoAttuale & " " & OraAttuale)
End Sub

Ciao
Marco
 

guidoarfini

Member
Licensed User
Longtime User
per Marco

Il tuo aiuto mi è servito...Grazie Funziona... ma io sono :BangHead: ..
riferendomi alla parte di codice che mi hai corretto ho tentato di modificarlo per adeguarlo alla mia situazione... io registro data e ora inizio nel DBSqlite, poi devo registrare la data e ora di fine (e qui nasce il problema di oggi) e poi con cursor...etc vado ad aggiornare la mia listview...(e questo era il problema che mi hai già risolto).... mi vorresti aiutare ancora?

Dim AllaScadenza, Adesso As Long
Dim Hours, Minutes, Seconds As String
Dim GiornoAttuale, OraAttuale As String
Adesso = DateTime.now
GiornoAttuale = DateTime.Date(Adesso)
OraAttuale = DateTime.Time(Adesso)
Dim date1, date2 As Long

date1 = DateTime.TimeParse(OraAttuale) + DateTime.GetTimeZoneOffsetAt(Adesso) * DateTime.TicksPerHour
date2 = DateTime.TimeParse(DurataSER) ' DurataSer è nel database e mi torna come stringa per exemp 01:20:00

allascadenza= date1 + date2

Seconds = NumberFormat(DateTime.GetSecond(AllaScadenza), 2, 0)
Minutes = NumberFormat(DateTime.GetMinute(AllaScadenza), 2, 0)
Hours = NumberFormat(DateTime.GetHour(AllaScadenza), 1, 0)
Msgbox("ORA ATTUALE : " & OraAttuale & " DURATA :" & DurataSER, "Data e ora di adesso: " & GiornoAttuale)
Msgbox("ORA FINALE : " & Hours & ":" & Minutes & ":" & Seconds , "")

Grazie...
 

magalt

Member
Licensed User
Longtime User
Sperando di aver interpretato bene il tuo problema residuo, ripropongo il codice con in coda la parte relativa al tempo finale.
Non avendo molta dimestichezza con il trattamento del tempo (il tuo problema è stato uno stimolo a studiare le funzioni) non ho trovato di meglio nella somma dei tempi.

Ciao
Marco

B4X:
Sub Scorrimento_Tick
   Dim AllaScadenza, Adesso As Long
   Dim Hours, Minutes, Seconds As String
   Dim GiornoAttuale, OraAttuale As String

   Adesso = DateTime.now : 'Memorizzo subito il tempo per evitare di usare tempi diversi nelle successive chiamate a DateTime.now
   GiornoAttuale = DateTime.Date(Adesso)
   OraAttuale = DateTime.Time(Adesso)

   Dim date1, date2 As Long
   date1 = DateTime.TimeParse(OraAttuale) + DateTime.GetTimeZoneOffsetAt(Adesso) * DateTime.TicksPerHour
   date2 = DateTime.TimeParse("23:59:59")
   AllaScadenza = date2 - date1

   Seconds = NumberFormat(DateTime.GetSecond(AllaScadenza), 2, 0)
   Minutes = NumberFormat(DateTime.GetMinute(AllaScadenza), 2, 0)
   Hours = NumberFormat(DateTime.GetHour(AllaScadenza), 1, 0)

   Msgbox("Mancano " & Hours & ":" & Minutes & ":" & Seconds & " alle 23:59:59", "Data e ora di adesso: " & GiornoAttuale & " " & OraAttuale)
   
   Dim DurataSER As String
   Dim GiornoScadenza, OraScadenza As String
   Dim TempoScadenza, MillisecondiDaAgg As Long
   Dim PrimoDuePunti, SecondoDuePunti As Int
   Dim OreDaAgg, MinDaAgg, SecDaAgg As Int
   
   DurataSER = "1:20:00"
   PrimoDuePunti = DurataSER.IndexOf(":")
   OreDaAgg = DurataSER.SubString2(0, PrimoDuePunti)
   SecondoDuePunti = DurataSER.LastIndexOf(":")
   MinDaAgg = DurataSER.SubString2(PrimoDuePunti + 1, SecondoDuePunti)
   SecDaAgg = DurataSER.SubString2(SecondoDuePunti + 1, DurataSER.Length)
   
   MillisecondiDaAgg = DateTime.TicksPerHour * OreDaAgg + DateTime.TicksPerMinute * MinDaAgg + DateTime.TicksPerSecond * SecDaAgg
   
   TempoScadenza = DateTime.TimeParse(OraAttuale) + MillisecondiDaAgg
   GiornoScadenza = DateTime.Date(TempoScadenza)
   OraScadenza = DateTime.Time(TempoScadenza)
   
   Msgbox("Scade il " & GiornoScadenza & " alle ore: " & OraScadenza, "Data e ora di adesso: " & GiornoAttuale & " " & OraAttuale)
End Sub
 

magalt

Member
Licensed User
Longtime User
migliorìe

Come al solito, insistendo si migliora.
Ho ridotto il codice della parte relativa al calcolo dei millisecondi da aggiungere e corretto il calcolo di date1 e date2 (anche se il valore della variabile 'AllaScadenza' non cambia).

Ciao
Marco

B4X:
Sub Scorrimento_Tick
   Dim AllaScadenza, Adesso As Long
   Dim Hours, Minutes, Seconds As String
   Dim GiornoAttuale, OraAttuale As String

   Adesso = DateTime.now : 'Memorizzo subito il tempo per evitare di usare tempi diversi nelle successive chiamate a DateTime.now
   GiornoAttuale = DateTime.Date(Adesso)
   OraAttuale = DateTime.Time(Adesso)

   Dim date1, date2 As Long
   date1 = DateTime.TimeParse(OraAttuale) 
   date2 = DateTime.TimeParse("23:59:59") - DateTime.GetTimeZoneOffsetAt(Adesso) * DateTime.TicksPerHour
   AllaScadenza = date2 - date1

   Seconds = NumberFormat(DateTime.GetSecond(AllaScadenza), 2, 0)
   Minutes = NumberFormat(DateTime.GetMinute(AllaScadenza), 2, 0)
   Hours = NumberFormat(DateTime.GetHour(AllaScadenza), 1, 0)

   Msgbox("Mancano " & Hours & ":" & Minutes & ":" & Seconds & " alle 23:59:59", "Data e ora di adesso: " & GiornoAttuale & " " & OraAttuale)
   
   Dim DurataSER As String
   Dim GiornoScadenza, OraScadenza As String
   Dim TempoScadenza, MillisecondiDaAgg As Long
   
   DurataSER = "1:20:00"
   MillisecondiDaAgg = DateTime.TimeParse(DurataSER) - DateTime.TimeParse("0:00:00")
   
   TempoScadenza = DateTime.TimeParse(OraAttuale) + MillisecondiDaAgg
   GiornoScadenza = DateTime.Date(TempoScadenza)
   OraScadenza = DateTime.Time(TempoScadenza)
   
   Msgbox("Scade il " & GiornoScadenza & " alle ore: " & OraScadenza, "Data e ora di adesso: " & GiornoAttuale & " " & OraAttuale)
End Sub
 

guidoarfini

Member
Licensed User
Longtime User
sono propio di coccio...

:BangHead::BangHead::BangHead:

Allora... ciao Marco... c'è qualcosa che non capisco proprio... ho gardato anche il link che mi avevi proposto... ho esaminato i codici che mi hai messo.... ma :BangHead::BangHead::BangHead:
i toui codici funzionano bene.... ma ha me sfugge qualcosa di importante.. che devo aver compreso male .. perchè non riesco ad andare avanti, ma non voglio la soluzione... voglio capire cosa ho compreso male... per risolvere il mio problema:sign0104:

e spero che sia uno stimolo anche per altri...

vediamo cosa ho capito...
quando uso la funzione...dateparse.time trasformo una stringa compilata a modo(00:00:01) in un numero long che dovrebbe essere il calcolo matematico dei minuti + ore+ secondi * i millisecondi contenuti in esso...

usando la DateTime.GetTimeZoneOffsetAt(adesso) vado a calcolare la differenza d'oraio nel sistema ...(e questo ho dubbi)

poi con i vari DateTime.GetSecond,getMinuti etc riconverto il numero long in stringa....

... la mia situazione è questa...:BangHead:

grazie...

Nel mio programma io salvo l'inizio del servizio in una cella, calcolo la fine prevista del servizio, se il servizio è finito calcolo da quanto... mi manca "solo" calcolare quanti servizi ho fatto da (impostabile per esempio 00:20:00) per poi moltiplicarlo per il costo:BangHead:
 

magalt

Member
Licensed User
Longtime User
Inizialmente ho sbattuto la testa anch'io e dopo qualche lettura e qualche prova mi sono convinto che:

1) DateTime.TimeParse(Adesso) --> trasforma il tempo (ma più in generale data+ora) in millisecondi a partire "dall'inizio dei tempi" che per Android è l'ora 00:00:00 dell'1/1/1970.

2) DateTime.TimeParse(Adesso) --> calcola il tempo (in millisecondi) comprensivo del TimeZone relativo all'impostazione corrente (per noi quella relativa a Roma).

3) DateTime.TimeParse(1:20:00) --> calcola il tempo (in millisecondi) comprensivo del TimeZone relativo al meridiano iniziale (quello relativo a Londra).

4) Se voglio avere un determinato tempo (esempio 1:20:00) in millisecondi riferito al mio TimeZone devo correggerlo mediante il ricorso alla funzione DateTime.GetTimeZoneOffsetAt(Adesso) [che mi restituisce il TimeZone in ore] moltiplicandolo per DateTime.TicksPerHour [numero di millisecondi in un'ora]. In altre parole, se imposto un tempo come costante allora lo riferisce a TimeZone 0 (Londra); se leggo il tempo (Now) allora lo riferisce a TimeZone del posto (Roma).

Ecco perché nel post #6 quando calcolo la differenza di tempi
AllaScadenza = date2 - date1
il primo valore (date2) ha bisogno di correzione del TimeZone mentre il secondo (date1) no.

Invece, quando - qualche riga più in basso - calcolo i millisecondi da aggiungere (in MillisecondiDaAgg)
nella differenza fra DateTime.TimeParse(DurataSER) e DateTime.TimeParse("0:00:00") non ho bisogno di correggere il tempo con il TimeZone in quanto entrambi i riferimenti (DurataSER = "1:20:00" e "0:00:00") sono calcolati da DateTime.TimeParse con lo stesso TimeZone, che scompare nella sottrazione.

In effetti, sottrarre il tempo "0:00:00" ad un tempo definito (es. "1:20:00") è il modo più veloce per calcolare i millisecondi corrispondenti a 1 ora e 20 minuti. Nel post #5 (non avendo pensato a questa soluzione) ero stato costretto a calcolarli scomponendo il tempo stesso in ore, minuti e secondi.

Ciao
Marco
 

guidoarfini

Member
Licensed User
Longtime User
sono propio di coccio...

:BangHead::BangHead::BangHead:

Allora... ciao Marco... c'è qualcosa che non capisco proprio... ho gardato anche il link che mi avevi proposto... ho esaminato i codici che mi hai messo.... ma :BangHead::BangHead::BangHead:
i toui codici funzionano bene.... ma ha me sfugge qualcosa di importante.. che devo aver compreso male .. perchè non riesco ad andare avanti, ma non voglio la soluzione... voglio capire cosa ho compreso male... per risolvere il mio problema:sign0104:

e spero che sia uno stimolo anche per altri...

vediamo cosa ho capito...
quando uso la funzione...dateparse.time trasformo una stringa compilata a modo(00:00:01) in un numero long che dovrebbe essere il calcolo matematico dei minuti + ore+ secondi * i millisecondi contenuti in esso...

usando la DateTime.GetTimeZoneOffsetAt(adesso) vado a calcolare la differenza d'oraio nel sistema ...(e questo ho dubbi)

poi con i vari DateTime.GetSecond,getMinuti etc riconverto il numero long in stringa....

... la mia situazione è questa...:BangHead:

grazie...

Nel mio programma io salvo l'inizio del servizio in una cella, calcolo la fine prevista del servizio, se il servizio è finito calcolo da quanto... mi manca "solo" calcolare quanti servizi ho fatto da (impostabile per esempio 00:20:00) per poi moltiplicarlo per il costo:BangHead:
 

magalt

Member
Licensed User
Longtime User
Sicuramente hai fatto un copia e incolla del tuo precedente post, però non riesco a capire se volevi aggiungere altro sull'argomento in trattazione.

Ciao
Marco
 

guidoarfini

Member
Licensed User
Longtime User
Nulla da fare ...

Marco.... non riesco proprio a capire... ho creato un mini app apposta .. per poter capire il "tempo"... ma non riesco a far tornare i conti... anche "alla scadenza non funziona correttamente se il servizio il servizio inizia prima della mezza notte e termina il giorno dopo...
ti posto il file..... :BangHead::BangHead: scusa se approfitto di te ma vedo che nononostante l'argomento sembra interessare visto le visite del post l'unico che ha la bonta di aiutarmi sei tu.. grazie
 

Attachments

  • testtempi.zip
    8.3 KB · Views: 297

magalt

Member
Licensed User
Longtime User
Ho provato a metterci le mani. Spero di non aver sbagliato ad interpretare il tuo codice.

Nel file "dataOra_commentato.b4a" trovi qualche annotazione a chiarimento.
Il file "dataOra.b4a" è ripulito dal superfluo.

C'è ancora qualche riga di codice da inserire per affrontare i casi di reiterazione di tentativi "Start-Stop/Countdown-Cronometro".

Ciao
Marco

NB: Il programma è in versione 1.80 mentre il tuo sorgente è in versione 1.70. Se hai problemi nel caricamento dovrebbe bastare modificare - con un editor di testo - il numero di versione (da 1.80 a 1.70), cancellando la 13-ima riga
"ManifestCode=".
 

guidoarfini

Member
Licensed User
Longtime User
c'è qualcosa che non va...

Marco.. inanzitutto ti ringrazio oer quello che stai facendo.. ma c'è qualcosa che non va.... ho letto anche tutti i tuoi commenti e tralasciando il discorso delle sicurezze per non interromepere il servizio etc che non mi interessano dato che questa è un applicazione per capire il "tempo" e non è la mia applicazione... Io ho creato tante textbox per manipolarare le ore di inizio etc... per potermi muovere e testare il sistema dato che normalmente le vado a scrivere in un database.. Succede questo.. se si imposta l'ora d'inizio del servizio(del giorno corrente) a countdown alle ore 23.58.00 gli impostiamo che dura 00:20:00, quindi finisce il giorno dopo alle 00:18:00...:signOops: non funziona, in altrettanto modo se impostiamo il servizio a cronometro e superiamo la mezza notte :signOops: calcola in modo erroneo.... :BangHead::BangHead:
 

magalt

Member
Licensed User
Longtime User
Ciao Guido.
Anche per me la faccenda si è rivelata dura. :BangHead:

Per semplificare le cose ho ridotto il progetto alle sole cose essenziali.

Al momento, la situazione è questa:
- all'interno dello stesso giorno, aggiungendo un tempo, calcola correttamente sia il tempo finale che il tempo mancante;
- a fine giorno, aggiungendo un tempo tale da superare la mezzanotte, calcola correttamente sia il tempo finale che il tempo mancante (compreso il cambio di giorno);
- dopo aver superato la mezzanotte, aggiungendo un tempo, calcola correttamente il tempo finale ma non il tempo mancante, poiché si rifiuta di impostare correttamente il giorno se non scatta l'una di notte!
- dopo l'una di notte tutto riprende a funzionare correttamente.

Probabilmente il TimeZone fa la differenza, ma non capisco ancora il meccanismo di correzione.

In allegato trovi il codice. Io mollo qui...

Ciao
Marco
 

guidoarfini

Member
Licensed User
Longtime User
forse ci siamo

devo fare ancora qualche test, ma ripartendo dal mio codice e modificano cosi il countdown....

Sub CountDown_tick


FusoOrario = DateTime.GetTimeZoneOffsetAt(Adesso) * DateTime.TicksPerHour


giorno1 = DateTime.DateParse(EdtPartenzaGiorno.Text)
date1 =DateTime.TimeParse(OraAttuale)


giorno2 = DateTime.DateParse(EdtFineServizioData.Text)
date2 =DateTime.TimeParse(EdtFineServizioORA.text)

' cosi ricavo ore effettive differenza
giornoDifferenza2= date2 - giorno2 - FusoOrario
giornoDifferenza1= date1 - giorno1
allascadenza= giornoDifferenza2-giornoDifferenza1


If giornoDifferenza1 < giornoDifferenza2 Then
LblStato.Text= "scaduto"
End If

seconds = NumberFormat(DateTime.GetSecond(allascadenza), 2, 0)
minutes = NumberFormat(DateTime.GetMinute(allascadenza), 2, 0)
Hours = NumberFormat(DateTime.GetHour(allascadenza), 1, 0)

EdtStato.Text= Hours & ":" & minutes & ":" & seconds


End Sub

grazie di tutto Marco
 
Top