webmcp

diff framework/env/parse/date.lua @ 0:9fdfb27f8e67

Version 1.0.0
author jbe/bsw
date Sun Oct 25 12:00:00 2009 +0100 (2009-10-25)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/framework/env/parse/date.lua	Sun Oct 25 12:00:00 2009 +0100
     1.3 @@ -0,0 +1,101 @@
     1.4 +local function map_2digit_year(y2)
     1.5 +  local current_year = atom.date:get_current().year
     1.6 +  local guess2 = math.floor(current_year / 100) * 100 + tonumber(y2)
     1.7 +  local guess1 = guess2 - 100
     1.8 +  local guess3 = guess2 + 100
     1.9 +  if guess1 >= current_year - 80 and guess1 <= current_year + 10 then
    1.10 +    return guess1
    1.11 +  elseif guess2 >= current_year - 80 and guess2 <= current_year + 10 then
    1.12 +    return guess2
    1.13 +  elseif guess3 >= current_year - 80 and guess3 <= current_year + 10 then
    1.14 +    return guess3
    1.15 +  end
    1.16 +end
    1.17 +
    1.18 +function parse.date(str, dest_type, options)
    1.19 +  if dest_type ~= atom.date then
    1.20 +    error("parse.date(...) can only return dates, but a different destination type than atom.date was given.")
    1.21 +  end
    1.22 +  local date_format = locale.get("date_format")
    1.23 +  if date_format and string.find(date_format, "Y+%-D+%-M+") then
    1.24 +    error("Date format collision with ISO standard.")
    1.25 +  end
    1.26 +  if string.match(str, "^%s*$") then
    1.27 +    return nil
    1.28 +  end
    1.29 +  -- first try ISO format
    1.30 +  local year, month, day = string.match(
    1.31 +    str, "^%s*([0-9][0-9][0-9][0-9])%-([0-9][0-9])%-([0-9][0-9])%s*$"
    1.32 +  )
    1.33 +  if year then
    1.34 +    return atom.date{
    1.35 +      year = tonumber(year),
    1.36 +      month = tonumber(month),
    1.37 +      day = tonumber(day)
    1.38 +    }
    1.39 +  end
    1.40 +  if not date_format then
    1.41 +    return atom.date.invalid
    1.42 +  end
    1.43 +  local format_parts = {}
    1.44 +  local numeric_parts = {}
    1.45 +  for part in string.gmatch(date_format, "[YMD]+") do
    1.46 +    format_parts[#format_parts+1] = part
    1.47 +  end
    1.48 +  for part in string.gmatch(str, "[0-9]+") do
    1.49 +    numeric_parts[#numeric_parts+1] = part
    1.50 +  end
    1.51 +  if #format_parts ~= #numeric_parts then
    1.52 +    return atom.date.invalid
    1.53 +  end
    1.54 +  local year, month, day
    1.55 +  local function process_part(format_part, numeric_part)
    1.56 +    if string.find(format_part, "^Y+$") then
    1.57 +      if #numeric_part == 4 then
    1.58 +        year = tonumber(numeric_part)
    1.59 +      elseif #numeric_part == 2 then
    1.60 +        year = map_2digit_year(numeric_part)
    1.61 +      else
    1.62 +        return atom.date.invalid
    1.63 +      end
    1.64 +    elseif string.find(format_part, "^M+$") then
    1.65 +      month = tonumber(numeric_part)
    1.66 +    elseif string.find(format_part, "^D+$") then
    1.67 +      day = tonumber(numeric_part)
    1.68 +    else
    1.69 +      if not #format_part == #numeric_part then
    1.70 +        return atom.date.invalid
    1.71 +      end
    1.72 +      local year_str  = ""
    1.73 +      local month_str = ""
    1.74 +      local day_str   = ""
    1.75 +      for i = 1, #format_part do
    1.76 +        local format_char = string.sub(format_part, i, i)
    1.77 +        local number_char = string.sub(numeric_part, i, i)
    1.78 +        if format_char == "Y" then
    1.79 +          year_str = year_str .. number_char
    1.80 +        elseif format_char == "M" then
    1.81 +          month_str = month_str .. number_char
    1.82 +        elseif format_char == "D" then
    1.83 +          day_str = day_str .. number_char
    1.84 +        else
    1.85 +          error("Assertion failed.")
    1.86 +        end
    1.87 +      end
    1.88 +      if #year_str == 2 then
    1.89 +        year = map_2digit_year(year_str)
    1.90 +      else
    1.91 +        year = tonumber(year_str)
    1.92 +      end
    1.93 +      month = tonumber(month_str)
    1.94 +      day = tonumber(day_str)
    1.95 +    end
    1.96 +  end
    1.97 +  for i = 1, #format_parts do
    1.98 +    process_part(format_parts[i], numeric_parts[i])
    1.99 +  end
   1.100 +  if not year or not month or not day then
   1.101 +    error("Date parser did not determine year, month and day. Maybe the 'date_format' locale is erroneous?")
   1.102 +  end
   1.103 +  return atom.date{ year = year, month = month, day = day }
   1.104 +end

Impressum / About Us