Newsgroup: it.comp.lang.visual-basic
Titolo: Problema con le date

Salute a tutti
Devo estrarre i record tra due date da un DB access 97 e faccio così:
Private Sub cmdCerca_Click()
Inizio = DTPicker1.Value
Fine = DTPicker2.Value
SQL = "select * from PROVA_TRAFFICO where DATA_CHIAMATA between " & _
      "#" & DateValue(Inizio) & "# and #" & DateValue(Fine) & "# "
etc. etc.
Se la data è inferiore al 1999 tutto funziona regolarmente. Se la data è
superiore o uguale al 2000 o non estrae nulla oppure tutti i record della
tabella.Qualcuno sa darmi una dritta???     Possibile che sia ancora alle
prese con il millenium bug???
CIAO
PAOLO

 [...] Devo estrarre i record tra due date da un DB access 97 [...]
Se posso permettermi un consiglio per tutti coloro che sono alle prese con
SQL, date e formati di data italiani, americani, ostrogoti, eccetera e non
riescono a venirne fuori: (stando ai post degli ultimi giorni sono
tanti...)la soluzione migliore, in assoluto, in questi casi, è quella di
usare strutture parametriche.
Ottima anche l'idea del costrutto "Between - And"!
Ciao,
Carlo.

Ottima anche l'idea del costrutto "Between - And"!
Io vorrei dare un suggerimento molto piu' efficace, che carichi meno
qualsiasi motore sql si usi e che funzioni in qualsiasi parte
dell'universo in cui si sappia l'ordine delle 10 cifre.
Anziche' usare il formato date e/o usare la data di sistema cosi' come
viene fornita, si *costruisce* la data odierna in questo formato:
aaaammgg
In questo modo *non esiste* alcuna possibilita' di sbagliare ad
inserire od estrarre date e *non c'e'* alcuna possibilita' di male
interpretazione del formato della data. E un order by non sbaglia *in
nessuna* parte del mondo, indipendentemente dal formato della data
locale.
Saluti.
-- 
      Gianni "bugbarbeq" Rondinini, 25, RA, 0.68, 152
  VBR - Vero Birro RomagnoloŽ, diffidate dalle imitazioni!
Nike Air Up Tempo Sad Walker -- Kawasaki "Gas Gas" ZZ-R 1100
 ICQ# 36893168 - IRCNet: bugbarbeq, @ on #linux-it & #NetBSD
   On contrary of popular belief, Unix *IS* user friendly:
    it just appears to be selective who it is friend with

> Ottima anche l'idea del costrutto "Between - And"!
GR> Io vorrei dare un suggerimento molto piu' efficace, che carichi meno
GR> qualsiasi motore sql si usi e che funzioni in qualsiasi parte
GR> dell'universo in cui si sappia l'ordine delle 10 cifre.
GR> Anziche' usare il formato date e/o usare la data di sistema cosi' come
GR> viene fornita, si *costruisce* la data odierna in questo formato:
GR> aaaammgg
Comparazione di due  stringhe di 10 caratteri con  comparazione di due
numeri binari... Forse si  guadagna che mi sa che il tipo  date è a 64
bit..., O.K.  finché  non ci si compra una  bella Ultrasparc :) meglio
usare  il  formato  aaaammgg. Anche  se  c'è  un  po' da  lavorar  per
stamparli.
-- 
Gian Uberto| main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Lauri      |                        David Korn, 1987 ioccc best one liner 
(aka saint)|-------------------------------------------------------------------
em@ail: 
sa...@eng.it
 ( vedere X-nospam nello header - see X-nospam in header )

 Comparazione di due  stringhe di 10 caratteri con  comparazione di due
numeri binari [...] meglio usare  il  formato  aaaammgg. Anche  se  c'č  un
po' da  lavorar  per stamparli.
Ho capito bene? Meglio due stringhe di due date in quanto a performance?
Se anche, e dico SE, cosě fosse, provatevi poi a far lavorare il motore DB
per:
1) Operare su differenze di date
2) Sommare un giorno ad una data
3) Sottrarre un mese ad una data
4) Leggere un record che ha una scadenza a 30/60 gg fine mese (per esempio)
rispetto alla data memorizzata
5) Eccetera eccetera
Poi ne riparliamo...
Ciao,
Carlo.

 Ho capito bene? Meglio due stringhe di due date in quanto a performance?
No, forse hai capito male: meglio due long, di due stringhe, purche' si mantenga il
formato aaaammgg
All'uopo riporto due funzioncine che servono proprio al caso... non sono un gran che
come ottimizzazione, ma fanno bene il loro lavoro e le ho usate in un db (dove le date
erano di tipo, appunto, long).
'input : a date in the format: "dd/mm/yyyy"
'output: a long in the format: yyyymmdd
Function Date2Long(ByVal dat As String) As Long
  On Error Resume Next
  Dim d, m, Y As String
  dat = Replace(dat, "_", "0") ' in the event that '_' is in the string
  d = Left$(dat, 2)
  m = Mid$(dat, 4, 2)
  Y = Right$(dat, 4)
  Date2Long = CLng(Y & m & d)
End Function
'input : a long in the format: yyyymmdd
'output: a date in the format: "dd/mm/yyyy"
Function Long2Date(ByVal dat As Long) As String
  On Error Resume Next
  Dim d, m, Y, m_date As String
  m_date = CStr(dat)
  If Len(m_date) < 8 Then
    m_date = Space$(8 - Len(m_date)) & m_date
    m_date = Replace(m_date, " ", "0")
  End If
  d = Right$(m_date, 2)
  m = Mid$(m_date, 5, 2)
  Y = Left$(m_date, 4)
  Long2Date = d & "/" & m & "/" & Y
End Function

 [...] No, forse hai capito male: meglio due long, di due stringhe, purche'
si mantenga il formato aaaammgg [...]
Ah, allora ok: concordo al 100%.
Ma allora chi ha scomodato le stringhe? Io no...
Ciao,
Carlo.

 ha scritto nel messaggio
news:9sf4d2$uok$1...@pegasus.tiscalinet.it...

Mah, anche se qualcuno le ha scomodate, l'importante e' che ci ripensi su e si
ricreda... :)))))

formato aaaammgg
Esattamente quello che intendevo.
L'order by funziona perfettamente senza problemi. La trasformazione
per ottenere la data e creare il long non e' pesante
--computazionalmente-- e ci si leva la preoccupazione delle date in un
batter d'occhio.


bit..., O.K.  finché  non ci si compra una  bella Ultrasparc :) meglio
Da te hanno mica qualche SparcStation da svendermi? Dalla SS2 in su,
prendo qualsiasi cosa. A dire la verita', anche una Classic ed una IPC
mi piacerebbero.
Saluti.
-- 
      Gianni "bugbarbeq" Rondinini, 25, RA, 0.68, 152
  VBR - Vero Birro Romagnolo®, diffidate dalle imitazioni!


 batter d'occhio.
D'accordo: Long meglio di Date e Order By impeccabile.
Però avete glissato sugli altri punti, eh?
Dovete manipolare le date a livello di motore di database. Con Jet, ad
esempio, che non conosce Trigger, non potete, a meno di implementare una
struttura con l'Immediate IF (IIf).
Per manipolazione intendo anche una sciocchezzuola del tipo: trovami la data
uguale a quella del record + 1 giorno. Come la trovate la coppia di Long che
soddisfa questa condizione senza "lavorare" un po' di codice (se per
sfortuna la data è 28 febbraio dovete implementare la policy del bisestile
per trovare la nuova data; se per sfortuna il giorno è il 31 dicembre
eccetera eccetera).
Quindi, riassumendo, diciamo che risolvete tutto da codice. Bel guadagno!
Poi, siccome il codice VB è notoriamente più performante di quello
ottimizzato del motore di database... ;-)
E se la vostra applicazione implementa dei log? Dove stanno scritti ore e
minuti, fondamentali per un log, nella data costruita con due Long? Allora
faremo una cosa spuria: un po' di date e un po' di doppi Long. Comodo ed
elegante :-)
No, perdonatemi, ma resto della mia idea: le date restino Date. In fin dei
conti, tutto ciò che sembra astruso e che confonde tanti colleghi (il motore
di database che insiste a capire solo il formato americano) è in realtà il
punto di forza di tutto il sistema: viene garantita la leggibilità dei dati
nonostante la localizzazione geografica diversa, viene garantito l'Order By
e finalmente possiamo lasciar lavorare il motore di database che per quanto
scarso sarà sempre più veloce di qualunque codice VB.
Ciao,
Carlo.

 scarso sarà sempre più veloce di qualunque codice VB.
Bla, bla, bla... solo per avere Data record + 1?
Voglio dire: condivido pienamente il tuo modo di pensare, la scelta migliore e'
sicuramente quella del tipo di dato "Date", ma svincolarsi dal non-standard che trovi su
Jet _forse_ potrebbe servire quando si prevede un passaggio a DB di altra natura (Oracle
e company). Ammetto la mia grande ignoranza e che dovrei documentarmi un pochino di +
sul trattamento delle date sotto Jet: in fondo non ho sicuramente l'esperienza che la
maggior parte di voi ha e a volte invento soluzioni alternative solo per non aver avuto
quel minuto di costanza in più per andarmi a documentare un po' + approfonditamente.

Ragazzi, sono quello che ha posto la domanda e vedo che si č innescata una
bella discussione anche se molte cose non le capisco sono riuscito a
risolvere il mio problema prendendo spunto dal fatto di convertire in
formato Long una data, ma non convertendo una stringa ma direttamente il
campo del DB. In pratica:
Inizio = CLng(DTPicker1.Value)
Fine = CLng(DTPicker2.Value)
On Error GoTo gesterr
Screen.MousePointer = 11
SQL = "select * from TRAFFICO where CLng(DATA_CHIAMATA) between " & Inizio &
" and " & Fine
etc. etc.
Cosě facendo ho risolto il fatto che non riuscivo ad estrarre record con
date superiori al 2000 visto che il confronto lo faccio su valori numerici e
non su formati data.
GRAZIE ANCORA A TUTTI E ALLA PROSSIMA
PAOLO