The full ISO 8601 format cannot be performed with a single pattern match. Too many changes.
Some examples from the wikipedia page :
- There is a “compressed” format that does not separate numbers:
YYYYMMDD vs YYYY-MM-DD - Day can be omitted:
YYYY-MM-DD and YYYY-MM are valid dates - The ordinal date is also valid:
YYYY-DDD , where DDD is the day of the year (1-365 / 6) - When presenting time, you can count minutes and seconds:
hh:mm:ss , hh:mm and hh are all valid time intervals - In addition, time also has a compressed version:
hhmmss , hhmm - In addition, time takes fractions, using both a period and a comma, to indicate the fraction of the lower time element in the time section.
14:30,5 , 1430,5 , 14:30.5 or 1430.5 all represent 14 hours, 30 seconds and a half. - Finally, the time zone section is optional. If available, it can be either the letter Z,
±hh:mm , ±hh , or ±hhmm .
Thus, there are many possible exceptions to consider if you intend to disassemble in accordance with the full specification. In this case, your source code might look like this:
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
And then you will need to create parseDate , parseTime and parseOffset . Later, they should return time offsets from UTC, while the first two will have to take into account such things as compressed formats, time fractions, comma delimiters or periods, etc.
parseDate will most likely use the "^" character at the beginning of pattern matches, since the date must be at the beginning of the line. parseTime patterns most likely begin with a "T" . And parseOffset will end with "$" since the time offsets, when they exist, are at the end.
The full ISO parseOffset might look something like this:
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
By the way, I assume that your computer is running in UTC. If this is not the case, you will need to add an additional offset to your hours / minutes to account for this.
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
To get the local offset, you can look at http://lua-users.org/wiki/TimeZone .
Hope this helps. Hello!