完整的ISO 8601格式可以」的用一個模式匹配來完成。變化太多了。
一些例子from the wikipedia page:
- 有一個 「壓縮」 格式,不包含獨立數字:
YYYYMMDD
VS YYYY-MM-DD
- 一天可以被遺漏:
YYYY-MM-DD
和YYYY-MM
都是有效日期
- 順序日期也有效:
YYYY-DDD
,其中DDD
是一年中的某天(1-365/6)
- 當代表t IME時,分,秒,可以中省略:
hh:mm:ss
,hh:mm
和hh
都是有效的時間
- 此外,時間也有一個壓縮版本:
hhmmss
,hhmm
- 而且最重要的是,一次使用接受分數,都點或逗號表示時間段中較低時間元素的分數。
14:30,5
,1430,5
,14:30.5
或1430.5
都代表14小時30秒半。
- 最後,時區部分是可選的。當存在時,它可以是字母Z,
±hh:mm
,±hh
或±hhmm
。
因此,如果要根據完整規範進行解析,可能有很多例外需要考慮。在這種情況下,你的初始代碼可能是這樣的:
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
然後,你需要創建parseDate
,parseTime
和parseOffset
。後者應該從UTC返回時間偏移量,而前兩者將不得不考慮壓縮格式,時間分數,逗號或點分隔符等等。
parseDate
可能會在模式匹配開始時使用"^"
字符,因爲日期必須位於字符串的開頭。parseTime
的模式可能會從"T"
開始。並且parseOffset
將以"$"
結尾,因爲時間偏移量在它們存在時處於末尾。
「全ISO」 parseOffset
功能可能看起來與此類似:
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
順便說一句,我假設你的計算機在UTC時間的工作。如果情況並非如此,那麼您必須在您的小時/分鐘內加上一個額外的偏移量來解釋這一點。
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
要獲得您當地的抵消額,您可能需要查看http://lua-users.org/wiki/TimeZone。
我希望這會有所幫助。問候!
BTW kikito的答案是好的;只是一個說明:接受''(空格)以及'T'來分隔日期/時間可能是一個好的舉動,因爲許多許多人和工具以這種方式寫ISO樣式的日期時間(可能超過使用'T'!)。 – snogglethorpe
感謝您的指針。就我而言,我不需要擔心它太多,因爲這種模式是已知的:2011-10-25T00:29:55.503-04:00 –