Problemi con i calcoli sulle date

Innanzitutto buongiorno, qui a Dalmine (BG) sono le 9.20 e la temperatura gi 31 gradi… il cervello comincia a bollire…

Ho un problemino che risale a due/tre anni fa con i calcoli sulle date.
In pratica nella procedura che calcola le scadenze dei pagamenti
In Mac OS / Linux funziona tutto bene, mentre in windows purtroppo NO

La scadenza in questione 30+60+90 fine mese con iva ad esigibilit immediata, facendo riferimento alla data del documento 01/01/2017 le scadenze dovrebbero essere :
al 31/01/2017 l’importo dell’iva
al 28/02/2017 la prima scadenza
al 31/03/2017 la seconda scadenza
e al 30/04/2017 l’ultima scadenza

Come scritto sopra tutto ok per MAC OS e LINUX mentre per windows non c’ nulla da fare.
Provo a postare il codice anche se ovviamente vi mancheranno un sacco di riferimenti.

[code]dim ddatainiziale as new date
dim ddatascadenza as new date
dim sdatainiziale as string
dim sdatafinale as string
dim conversione as boolean
dim cursore as integer
dim intervallo as integer
dim importo as Currency
dim importoiva as Currency
dim iniziorata as integer
dim totaledoc as Currency
dim lastimporto as Currency
dim numerorate as integer
dim offset as Currency
dim offsetnetto as Currency
dim offsetprovv as Currency
dim offsetprovv2 as Currency
dim primarata as integer
dim pagprimamese as integer
dim pagintervallomese as integer
dim importoprovv as Currency
dim importoprovv2 as Currency
dim importonetto as Currency

numerorate = self.pagrate

if self.pagprima mod 30 = 0 then
pagprimamese = self.pagprima / 30
end if

if self.pagintervallo mod 30 = 0 then
pagintervallomese = self.pagintervallo / 30
end if

lbscadenze.DeleteAllRows
select case self.pagtipoiva
case “0”
’ nelle rate
totaledoc = cdbl(txttotalepagare.text)
importo = arrotonda(totaledoc / numerorate,2)
importonetto = arrotonda(txtimportomerce.valore / numerorate,2)
importoprovv = self.totaleprovvigioni / numerorate
importoprovv2 = self.totaleprovvigioni2 / numerorate
offsetnetto = txtimportomerce.valore - (importonetto * numerorate)
offsetprovv = self.totaleprovvigioni - (importoprovv * numerorate)
offsetprovv2 = self.totaleprovvigioni2 - (importoprovv2 * numerorate)
offset = totaledoc - (importo * numerorate)
iniziorata = 0

case “5”
’ prima rata solo iva
importo = cdbl(txttotalepagare.text) - cdbl(txtdocimposta.text)
lbscadenze.AddRow “”
lbscadenze.cell(lbscadenze.ListCount - 1,0) = “1”
sdatainiziale = txtdatadocumento.text
conversione = ParseDate(sdatainiziale, ddatainiziale)
dim giorni as integer
giorni = datediff(txtdatadocumento.data,ddatainiziale)
lbscadenze.cell(lbscadenze.ListCount - 1,1) = ddatainiziale.dataitalia
lbscadenze.cell(lbscadenze.ListCount - 1,2) = self.tipopagiva
// 12/02/2016 CALCOLA I GIORNI
lbscadenze.cell(lbscadenze.ListCount - 1,3) = cstr(giorni)
lbscadenze.cell(lbscadenze.ListCount - 1,4) = self.pagivadescrizionetipo
lbscadenze.cell(lbscadenze.ListCount - 1,5) = format(importo,"-#,###,###,###.00")

totaledoc = cdbl(txtdocimponibile.text)
numerorate = self.pagrate
importo = arrotonda(totaledoc / numerorate,2)
importonetto = arrotonda(txtimportomerce.valore / numerorate,2)
importoprovv = self.totaleprovvigioni / numerorate
importoprovv2 = self.totaleprovvigioni2 / numerorate
offset = totaledoc - (importo * numerorate)
offsetnetto = txtimportomerce.valore - (importonetto * numerorate)
offsetprovv = self.totaleprovvigioni - (importoprovv * numerorate)
offsetprovv2 = self.totaleprovvigioni2 - (importoprovv2 * numerorate)
iniziorata = 1

case “1”, “3”
importoiva = cdbl(txtdocimposta.text)
totaledoc = cdbl(txtdocimponibile.text)
importo = arrotonda(totaledoc / numerorate,2)
importonetto = arrotonda(txtimportomerce.valore / numerorate,2)
importoprovv = arrotonda(self.totaleprovvigioni / numerorate,2)
importoprovv2 = arrotonda(self.totaleprovvigioni2 / numerorate, 2)
offsetnetto = txtimportomerce.valore - (importonetto * numerorate)
offsetprovv = self.totaleprovvigioni - (importoprovv * numerorate)
offsetprovv2 = self.totaleprovvigioni2 - (importoprovv2 * numerorate)
offset = totaledoc - (importo * numerorate)
iniziorata = 0

case “2”,“4”
// 04/07/2014 - numerorate = numerorate -1 perch una rata solo iva
importoiva = cdbl(txtdocimposta.text)
totaledoc = cdbl(txtdocimponibile.text)
importo = arrotonda(totaledoc / (numerorate -1) ,2)
importonetto = arrotonda(txtimportomerce.valore / (numerorate-1),2)
importoprovv = arrotonda(self.totaleprovvigioni / (numerorate-1),2)
importoprovv2 = arrotonda(self.totaleprovvigioni2 / (numerorate -1),2)
offset = totaledoc - (importo * (numerorate -1))
offsetnetto = txtimportomerce.valore - (importonetto * (numerorate-1))
offsetprovv = self.totaleprovvigioni - (importoprovv * (numerorate-1))
offsetprovv2 = self.totaleprovvigioni2 - (importoprovv2 * (numerorate-1))
iniziorata = 0

end select
[/code]
---- CONTINUA ----

Continuo con il codice

sdatainiziale = self.txtdatadocumento.text
conversione = ParseDate(sdatainiziale, ddatainiziale)

for cursore = 1 to numerorate
  if cursore = 1 then
    intervallo = 0
    primarata = self.pagprima
  else
    intervallo = 0
    primarata = primarata + self.pagintervallo
  end if
  conversione = ParseDate(sdatainiziale, ddatascadenza)
  
  ' per lo scarto dei 30 giorni su mese da 31 se aggiungo 30 al giorno 1 si verifica che diventa 31 e la scadenza potrebbe rimanere nello stesso mese.
  if primarata mod 30 = 0 then
    ddatascadenza.Month = ddatascadenza.Month + primarata/30
    txtscadenzavirtuale.data = ddatascadenza
  else
    ddatascadenza.day = ddatascadenza.Day + primarata
    txtscadenzavirtuale.data = ddatascadenza
  end if
  
  if self.pagposizione > 28 and self.pagposizione <= 31 then
    select case ddatascadenza.Month
    case 1,3,5,7,8,10,12
      ddatascadenza.Day = 31
      txtscadenzavirtuale.data = ddatascadenza
    case 2
      if floor(ddatascadenza.year / 4) = ddatascadenza.year / 4 then
        ddatascadenza.Day = 29
        txtscadenzavirtuale.data = ddatascadenza
      else
        ddatascadenza.Day = 28
        txtscadenzavirtuale.data = ddatascadenza
      end if
    case 4,6,9,11
      ddatascadenza.Day = 30
      txtscadenzavirtuale.data = ddatascadenza
    end select
  end if
  
  if self.pagposizione >= 1 and self.pagposizione <= 28 then
    select case ddatascadenza.month
    case 1,3,5,7,8,10,12
      // gennaio, marzo, maggio, luglio, agosto, ottobre, dicembre
      if ddatascadenza.Day = 31 then 
        ddatascadenza.day = ddatascadenza.day + 1
        txtscadenzavirtuale.data = ddatascadenza
      else
        ddatascadenza.month = ddatascadenza.month + 1
        ddatascadenza.day = 1
        txtscadenzavirtuale.data = ddatascadenza
      end if
    case 2
      // febbraio con definizione di anno bisestile
      if ddatascadenza.Year mod 4 = 0 then 
        if ddatascadenza.Day = 29 then
          ddatascadenza.day = ddatascadenza.day + 1
          txtscadenzavirtuale.data = ddatascadenza
        else
          ddatascadenza.month = ddatascadenza.month + 1
          ddatascadenza.day = 1
          txtscadenzavirtuale.data = ddatascadenza
        end if
      else
        if ddatascadenza.Day = 28 then
          ddatascadenza.day = ddatascadenza.day + 1
          txtscadenzavirtuale.data = ddatascadenza
        else
          ddatascadenza.month = ddatascadenza.month + 1
          ddatascadenza.day = 1
          txtscadenzavirtuale.data = ddatascadenza
        end if
      end if
    case 4,6,9,11
      // aprile, giugno, settembre, novembre
      if ddatascadenza.Day = 30 then
        ddatascadenza.day = ddatascadenza.day + 1
        txtscadenzavirtuale.data = ddatascadenza
      else
        ddatascadenza.month = ddatascadenza.month + 1
        ddatascadenza.day = 1
        txtscadenzavirtuale.data = ddatascadenza
      end if
    end select
    ddatascadenza.Day = self.pagposizione
    txtscadenzavirtuale.data = ddatascadenza
  end if
  
  if cursore = self.pagrate then
    importo = importo + offset
    importonetto = importonetto + offsetnetto
    importoprovv = importoprovv + offsetprovv
    importoprovv2 = importoprovv2 + offsetprovv2
    if self.pagtipoiva = "3" then
      ' per l'iva su ultima rata
      importo = importo + importoiva
      importonetto = importonetto + offsetnetto
      importoprovv = importoprovv + offsetprovv
      importoprovv2 = importoprovv2 + offsetprovv2
    end if
    
    if self.pagtipoiva = "4" then
      ' per l'iva su ultima rata
      importo = importoiva
    end if
    
  end if
  
  if cursore = 1 then
    
    if self.pagtipoiva = "1" then
      lastimporto = importo
      ' per l'iva su prima rata
      importo = importo + importoiva
      importonetto = importonetto + offsetnetto
      importoprovv = importoprovv + offsetprovv
      importoprovv2 = importoprovv2 + offsetprovv2
    end if
    
    if self.pagtipoiva = "2" then
      lastimporto = importo
      ' per l'iva su prima rata
      importo = importoiva
    end if
  end if
  
  sdatafinale = cstr(ddatascadenza.dataitalia)
  lbscadenze.AddRow ""
  lbscadenze.cell(lbscadenze.ListCount - 1,0) = str(cursore+iniziorata)
  lbscadenze.cell(lbscadenze.ListCount - 1,1) = cstr(ddatascadenza.dataitalia)
  lbscadenze.cell(lbscadenze.ListCount - 1,2) = self.tipopag
  lbscadenze.cell(lbscadenze.ListCount - 1,3) = str(iniziorata + intervallo)
  lbscadenze.cell(lbscadenze.ListCount - 1,4) = self.pagdescrizionetipo
  lbscadenze.cell(lbscadenze.ListCount - 1,5) = format(importo,"-#,###,###,###.00")
  lbscadenze.CellTag(lbscadenze.ListCount - 1,5) = format(importonetto,"-#,###,###,###.00")
  lbscadenze.Cell(lbscadenze.ListCount - 1,6) = format(importoprovv,"-#,###,###,###.00")
  lbscadenze.Cell(lbscadenze.ListCount - 1,7) = format(importoprovv2,"-#,###,###,###.00")
  
  if cursore = 1 then
    if self.pagtipoiva = "1" or self.pagtipoiva = "2" then
      importo = lastimporto
    end if
  end if
  
next

Nulla sto provando a sostituire alcune funzioni.
ad esempio Totalsecond + (606024*numero giorni) invece che addizionare di un giorno una data.
oppure di un mese una data. Ma semplicemente su Mac Os e linux funziona e su windows ancora nulla.

Hai provato a calcolare la data direttamente?
FineMese=inizioMeseCorrente+MesiDaSaltare-1 giorno
30/60/90 fine mese sono indicativi in realt sono FineMese(1mese|2mesi|2mesi)
Per cui utilizzando la data del framework Classico:

Public Function FineMese(extends dataOriginale as Date, mesi as integer=1) as Date
  //crei la data di destinazione
  //sono oggetti per cui non devi modificare quello passato in argomento
  //ma crearne uno nuovo
  Dim nuovaData As New Date
  
  //Cloni la data attuale
  nuovaData.SQLDateTime=dataOriginale.SQLDateTime
  
  //Ci posizioniamo all'inizio del mese
  nuovaData.Day=1
  
  //Ci spostiamo al mese seguente (+1 del valore richiesto)
  nuovaData.Month=nuovaData.Month+mesi+1
  
  //Andiamo all'ultimo giorno del mese precedente
  //ovvero alla data richiesta
  
  nuovaData.Day=nuovaData.Day-1
  
  Return nuovaData
End Function

Sto compilando nuovamente l’app per provarla in windows;

Ciao Massimiliano,

Qui a Brescia c’ ne sono 32 di gradi e proprio per questo motivo non ho neanche provato a leggere il tuo codice :stuck_out_tongue:
Pure io tempo fa ho avuto problemi con i calcoli delle scadenze perch mi sballava i conti sui fine mese. Per ovviare il problema ho usato la nuova struttura delle date( Xojo.Core.Date) in questo modo(faccio copia e incolla di alcuni pezzi di codice spero di non perdermi nulla):

  Dim fineMese As boolean
  Dim CET As New Xojo.Core.TimeZone("CET")
  Dim mmExtra As Xojo.Core.DateInterval
  Dim d as   Xojo.Core.Date 

'Parto dalla date del documento
d = New Xojo.Core.Date(val(a),val(m),val(g), CET) 
mmExtra = New Xojo.Core.DateInterval(0,1) 'Conteggio il mese della prima rata
d=d + mmExtra 'sommo il mese quindi ad esempio dal 12/01/2018 va a 12/02/2018

if fineMese then

      dim dt as new Xojo.Core.DateInterval(0, 1)
      d=d+dt 'Avanzo di un mese esatto 12/03/2018
      
      dt=new Xojo.Core.DateInterval(0, 0, d.day)
      d=d-dt 'andiamo indietro dei giorni trascorsi dall'inizio del mese quindi sottraggo 12 e va al mese prima
end if 

Ovviamente in tutto ci io ho un ciclo che legge da una tabella i metodo di pagamento impostati dall’utente e fa poi tutti i calcoli in base al numero di rate,finemese, gg extra ecc

Bene, innanzitutto vi ringrazio, stavo riscrivendo appunto la procedura per il calcolo delle scandenze la settimana scorsa quando il mio povero MAC BOOK pro, anno 2009 mi ha lasciato.
Ho acquistato in un negozio a Bergamo un macbook air usato ( met 2013 ) purtroppo le mie finanze mi impediscono di acquistarne uno nuovo considerando comunque che un mac book air 13’’ con hd da 120 gbyte e ram da 8 gbyte costa 880 euro da Mediaworld…
Va b sono cose che capitano.
Come mi capitato di passare la selezione a Poste Italiane, di avere la lettera di assunzione in mano, e di aspettare ancora la chiamata… ( E QUI MI GIRANO COME UN FRULLATORE ).
Comunque in questi giorni finir la procedura appunto per il calcolo delle scadenze. Sperando che funzioni allo stesso modo su MAC/LINUX e su WINDOWS
Ancora grazie infinite

Perfetto! credo di aver trovato un BUG sul calcolo delle date …

dim datascadenza as new date ' Datascadenza = 10/08/2018' datascadenza.day = datascadenza.day + 120

In Mac Os riporta 08/12/2018 ( 120 giorni )
In Windows riporta 07/12/2018 ( 119 giorni )

Spero sia solo un problema nel compilatore MAC OS per windows

Alla fine l’ho risolta … in Windows il mio datediff si mangia un giorno …
Per il resto, per il problema della procedura che calcola le scadenze ho utilizzato il sistema di Antonio di passare a date .sqldatetime e tutto si risolto per il meglio.
Avrei voluto compilare la mia app e finalmente venderla ma nel frattempo mi anno aggiornato i tracciati della fattura elettronica, il tracciato dei pagamenti SDD CORE e abolito lo spesometro.
Quindi … MI SPARO CHE FACCIO PRIMA