2011-09-30 15 views
7

Ottengo risultati imprevisti quando utilizzo DateTime.ParseExact. Ecco il mio codice di prova:Utilizzo di DateTime.ParseExact per ottenere solo l'ora (senza giorno)

Dim MinVal As DateTime = #12:00:01 AM# 
Dim MaxVal As DateTime = #11:59:59 PM# 
Dim TooBig1, Equal1 As Boolean 
Dim TooBig2, Equal2 As Boolean 

Dim dt1 As DateTime = #12:00:01 AM# 
Dim dt2 As DateTime = DateTime.ParseExact("12:00:01 AM", "hh:mm:ss tt", Globalization.DateTimeFormatInfo.InvariantInfo) 

TooBig1 = (dt1.CompareTo(MaxVal) > 0) 
Equal1 = (dt1.CompareTo(MinVal) = 0) 

TooBig2 = (dt2.CompareTo(MaxVal) > 0) 
Equal2 = (dt2.CompareTo(MinVal) = 0) 

Il risultato va bene per dt1:

  • mostra nel debugger come # 12: 00: 01 PM # (senza il giorno)
  • TooBig1 è false
  • Equal1 è true

Ma il risultato è (va?) inaspettata per dt2:

  • mostra nel debugger come al n.9/30/2011 12:00:01 #
  • TooBig2 è True
  • Equal2 è False

Sembra che sia perché il giorno è sistematicamente aggiunto da ParseExact anche se si specifica solo l'ora nel formato.

La mia domanda è: come posso leggere solo l'ora con DateTime.ParseExact?

risposta

4

Documentation stati:

Se formato definisce un tempo senza alcun elemento data e l'operazione di analisi riesce, il valore DateTime risultante ha una data di DateTime.Now.Date.

Se si desidera un tempo senza data, è possibile utilizzare:

var parsedDate = DateTime.ParseExact(...); 
var timeOnly = parsedDate - parsedDate.Date; 
+2

che diventa un oggetto 'TimeSpan', però, non è un' DateTime'. Il fatto di sorvolare questo importante dettaglio mostra ancora una volta che l'uso di variabili non tipizzate è una pratica terribile. – Nyerguds

+0

@Nyerguds: hai ragione che il risultato è un 'TimeSpan'. Apparentemente questo è ciò che l'OP voleva, o ha rapidamente capito come creare un nuovo 'DateTime' da esso. Non ci sono variabili non tipizzate in quello snippet di codice; entrambi sono fortemente tipizzati, come il compilatore renderebbe abbondantemente chiaro la prima volta che hai provato a usare 'timeOnly' come un' DateTime'. Forse intendevi dire che sfruttare l'inferenza di tipo è una brutta cosa? –

+3

Sì, con "non tipizzato" intendevo "non specificatamente digitato nel codice", che in realtà significa inferenza di tipo. Anche questo è un perfetto esempio; non è affatto visibile da quel codice che 'DateTime' meno' DateTime' è uguale a _non_ a 'DateTime'. – Nyerguds

2

Se non si specifica un giorno, assume a quanto pare oggi. (Non irragionevole se stai scrivendo, per esempio, software di tracciamento del tempo.)

Se vuoi solo la parte del tempo, potresti analizzarla come stai già facendo, e poi prendere solo l'ora del giorno porzione:

' Existing code: 
Dim dt2 As DateTime = DateTime.ParseExact("12:00:01 AM", "hh:mm:ss tt", _ 
    Globalization.DateTimeFormatInfo.InvariantInfo) 
' Now grab just the time: 
Dim ts2 As TimeSpan = dt2.TimeOfDay 

che sarà un TimeSpan invece di un DateTime, ma se in realtà non necessità come un DateTime, TimeSpan è più appropriato per qualcosa che è solo ore/minuti/secondi, ma non giorni .

(Si potrebbe anche provare a utilizzare TimeSpan.ParseExact in primo luogo, ma non è stato creato per gestire AM/PM e analizzare 12: 0001 come 12 ore. Probabilmente si preferisce DateTime. ParseExact seguito da .TimeOfDay)


Se effettivamente fai necessità di rappresentarlo come un DateTime -. con una porzione della data di, diciamo, 1/1/0001 - si può sempre convertire tale TimeSpan torna a un DateTime manualmente:

Dim dt3 As New DateTime(1, 1, 1, ts2.Hours, ts2.Minutes, ts2.Seconds, ts2.Milliseconds) 
Problemi correlati