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