La piena formato ISO 8601 può' si può fare con un solo pattern match. C'è troppa variazione.
Alcuni esempi: from the wikipedia page
- v'è un formato "compresso" che fa numeri non separate:
YYYYMMDD
vs YYYY-MM-DD
- La giornata può essere omited:
YYYY-MM-DD
e YYYY-MM
sono entrambe date valide
- La data ordinale è valida anche:
YYYY-DDD
, dove DDD
è il giorno dell'anno (1-365/6)
- Quando si rappresenta la t ime, minuti e secondi possono essere ommited:
hh:mm:ss
, hh:mm
e hh
sono sempre validi
- Inoltre, il tempo ha anche una versione compressa:
hhmmss
, hhmm
- E per di più, il tempo accetta frazioni, utilizzando sia il punto o la virgola per indicare le frazioni dell'elemento temporale inferiore nella sezione temporale.
14:30,5
, 1430,5
, 14:30.5
o 1430.5
rappresentano tutte 14 ore, 30 secondi e mezzo.
- Infine, la sezione del fuso orario è facoltativa. Quando presente, può essere la lettera Z,
±hh:mm
, ±hh
o ±hhmm
.
Quindi, ci sono molte possibili eccezioni da tenere in considerazione, se si intende analizzare secondo le specifiche complete. In questo caso, il codice iniziale potrebbe assomigliare a questo:
function parseDateTime(str)
local Y,M,D = parseDate(str)
local h,m,s = parseTime(str)
local oh,om = parseOffset(str)
return os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s})
end
E poi si dovrebbe creare parseDate
, parseTime
e parseOffset
. Le versioni successive dovrebbero restituire le correzioni dell'ora da UTC, mentre le prime due dovrebbero prendere in considerazione aspetti come formati compressi, frazioni temporali, separatori di virgola o punti e simili.
parseDate
probabilmente utilizzerà il carattere "^"
all'inizio delle sue corrispondenze modello, poiché la data deve essere all'inizio della stringa.Gli schemi parseTime
inizieranno probabilmente con "T"
. E gli parseOffset
terminano con "$"
, poiché le compensazioni temporali, quando esistono, sono alla fine.
Una funzione "full ISO" parseOffset
potrebbe essere simile a questo:
function parseOffset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local sign, oh, om = str:match("([-+])(%d%d):?(%d?%d?)$")
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
A proposito, sto supponendo che il computer sta lavorando in ora UTC. Se questo non è il caso, dovrai includere un offset aggiuntivo sulle ore/minuti per renderlo conto.
function parseDateTime(str)
local Y,M,D = parseDate(str)
local h,m,s = parseTime(str)
local oh,om = parseOffset(str)
local loh,lom = getLocalUTCOffset()
return os.time({year=Y, month=M, day=D, hour=(h+oh-loh), min=(m+om-lom), sec=s})
end
per ottenere il vostro locale di offset si potrebbe desiderare di guardare http://lua-users.org/wiki/TimeZone.
Spero che questo aiuti. Saluti!
BTW La risposta di kikito è buona; solo una nota: potrebbe essere una buona mossa accettare "" (spazio) e "T" per separare la data/ora, perché molte molte persone e strumenti scrivono in questo modo le date in stile ISO in quel modo (forse più di usa 'T'!). – snogglethorpe
Grazie per quel puntatore. Nel mio caso, non ho bisogno di preoccuparmi troppo perché il modello è noto: 2011-10-25T00: 29: 55.503-04: 00 –