webmcp
view 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 |
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