webmcp

view framework/env/parse/date.lua @ 382:810c020b0da4

Reverted changes to mondelefant_result_index and mondelefant_result_newindex C-functions (proxying of JSON document)
author jbe
date Mon Nov 16 18:31:49 2015 +0100 (2015-11-16)
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

Impressum / About Us