webmcp
annotate framework/env/parse/date.lua @ 3:795b764629ca
Version 1.0.3
Important bugfix related to internal forwards (Bug was introduced by the restriction of views with underscore prefix in Version 1.0.2)
Important bugfix related to internal forwards (Bug was introduced by the restriction of views with underscore prefix in Version 1.0.2)
author | jbe |
---|---|
date | Thu Dec 10 12:00:00 2009 +0100 (2009-12-10) |
parents | 9fdfb27f8e67 |
children |
rev | line source |
---|---|
jbe/bsw@0 | 1 local function map_2digit_year(y2) |
jbe/bsw@0 | 2 local current_year = atom.date:get_current().year |
jbe/bsw@0 | 3 local guess2 = math.floor(current_year / 100) * 100 + tonumber(y2) |
jbe/bsw@0 | 4 local guess1 = guess2 - 100 |
jbe/bsw@0 | 5 local guess3 = guess2 + 100 |
jbe/bsw@0 | 6 if guess1 >= current_year - 80 and guess1 <= current_year + 10 then |
jbe/bsw@0 | 7 return guess1 |
jbe/bsw@0 | 8 elseif guess2 >= current_year - 80 and guess2 <= current_year + 10 then |
jbe/bsw@0 | 9 return guess2 |
jbe/bsw@0 | 10 elseif guess3 >= current_year - 80 and guess3 <= current_year + 10 then |
jbe/bsw@0 | 11 return guess3 |
jbe/bsw@0 | 12 end |
jbe/bsw@0 | 13 end |
jbe/bsw@0 | 14 |
jbe/bsw@0 | 15 function parse.date(str, dest_type, options) |
jbe/bsw@0 | 16 if dest_type ~= atom.date then |
jbe/bsw@0 | 17 error("parse.date(...) can only return dates, but a different destination type than atom.date was given.") |
jbe/bsw@0 | 18 end |
jbe/bsw@0 | 19 local date_format = locale.get("date_format") |
jbe/bsw@0 | 20 if date_format and string.find(date_format, "Y+%-D+%-M+") then |
jbe/bsw@0 | 21 error("Date format collision with ISO standard.") |
jbe/bsw@0 | 22 end |
jbe/bsw@0 | 23 if string.match(str, "^%s*$") then |
jbe/bsw@0 | 24 return nil |
jbe/bsw@0 | 25 end |
jbe/bsw@0 | 26 -- first try ISO format |
jbe/bsw@0 | 27 local year, month, day = string.match( |
jbe/bsw@0 | 28 str, "^%s*([0-9][0-9][0-9][0-9])%-([0-9][0-9])%-([0-9][0-9])%s*$" |
jbe/bsw@0 | 29 ) |
jbe/bsw@0 | 30 if year then |
jbe/bsw@0 | 31 return atom.date{ |
jbe/bsw@0 | 32 year = tonumber(year), |
jbe/bsw@0 | 33 month = tonumber(month), |
jbe/bsw@0 | 34 day = tonumber(day) |
jbe/bsw@0 | 35 } |
jbe/bsw@0 | 36 end |
jbe/bsw@0 | 37 if not date_format then |
jbe/bsw@0 | 38 return atom.date.invalid |
jbe/bsw@0 | 39 end |
jbe/bsw@0 | 40 local format_parts = {} |
jbe/bsw@0 | 41 local numeric_parts = {} |
jbe/bsw@0 | 42 for part in string.gmatch(date_format, "[YMD]+") do |
jbe/bsw@0 | 43 format_parts[#format_parts+1] = part |
jbe/bsw@0 | 44 end |
jbe/bsw@0 | 45 for part in string.gmatch(str, "[0-9]+") do |
jbe/bsw@0 | 46 numeric_parts[#numeric_parts+1] = part |
jbe/bsw@0 | 47 end |
jbe/bsw@0 | 48 if #format_parts ~= #numeric_parts then |
jbe/bsw@0 | 49 return atom.date.invalid |
jbe/bsw@0 | 50 end |
jbe/bsw@0 | 51 local year, month, day |
jbe/bsw@0 | 52 local function process_part(format_part, numeric_part) |
jbe/bsw@0 | 53 if string.find(format_part, "^Y+$") then |
jbe/bsw@0 | 54 if #numeric_part == 4 then |
jbe/bsw@0 | 55 year = tonumber(numeric_part) |
jbe/bsw@0 | 56 elseif #numeric_part == 2 then |
jbe/bsw@0 | 57 year = map_2digit_year(numeric_part) |
jbe/bsw@0 | 58 else |
jbe/bsw@0 | 59 return atom.date.invalid |
jbe/bsw@0 | 60 end |
jbe/bsw@0 | 61 elseif string.find(format_part, "^M+$") then |
jbe/bsw@0 | 62 month = tonumber(numeric_part) |
jbe/bsw@0 | 63 elseif string.find(format_part, "^D+$") then |
jbe/bsw@0 | 64 day = tonumber(numeric_part) |
jbe/bsw@0 | 65 else |
jbe/bsw@0 | 66 if not #format_part == #numeric_part then |
jbe/bsw@0 | 67 return atom.date.invalid |
jbe/bsw@0 | 68 end |
jbe/bsw@0 | 69 local year_str = "" |
jbe/bsw@0 | 70 local month_str = "" |
jbe/bsw@0 | 71 local day_str = "" |
jbe/bsw@0 | 72 for i = 1, #format_part do |
jbe/bsw@0 | 73 local format_char = string.sub(format_part, i, i) |
jbe/bsw@0 | 74 local number_char = string.sub(numeric_part, i, i) |
jbe/bsw@0 | 75 if format_char == "Y" then |
jbe/bsw@0 | 76 year_str = year_str .. number_char |
jbe/bsw@0 | 77 elseif format_char == "M" then |
jbe/bsw@0 | 78 month_str = month_str .. number_char |
jbe/bsw@0 | 79 elseif format_char == "D" then |
jbe/bsw@0 | 80 day_str = day_str .. number_char |
jbe/bsw@0 | 81 else |
jbe/bsw@0 | 82 error("Assertion failed.") |
jbe/bsw@0 | 83 end |
jbe/bsw@0 | 84 end |
jbe/bsw@0 | 85 if #year_str == 2 then |
jbe/bsw@0 | 86 year = map_2digit_year(year_str) |
jbe/bsw@0 | 87 else |
jbe/bsw@0 | 88 year = tonumber(year_str) |
jbe/bsw@0 | 89 end |
jbe/bsw@0 | 90 month = tonumber(month_str) |
jbe/bsw@0 | 91 day = tonumber(day_str) |
jbe/bsw@0 | 92 end |
jbe/bsw@0 | 93 end |
jbe/bsw@0 | 94 for i = 1, #format_parts do |
jbe/bsw@0 | 95 process_part(format_parts[i], numeric_parts[i]) |
jbe/bsw@0 | 96 end |
jbe/bsw@0 | 97 if not year or not month or not day then |
jbe/bsw@0 | 98 error("Date parser did not determine year, month and day. Maybe the 'date_format' locale is erroneous?") |
jbe/bsw@0 | 99 end |
jbe/bsw@0 | 100 return atom.date{ year = year, month = month, day = day } |
jbe/bsw@0 | 101 end |