Skip to content

Commit a1ed482

Browse files
committed
Update to make dates like feb 24 work in a more intuitive way
1 parent 6fab925 commit a1ed482

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,10 @@ MONTH
138138
this MONTH
139139
next MONTH
140140
(last | previous | prev) MONTH
141+
DAY MONTH
142+
MONTH DAY
141143
[+/-]NUM MONTH
142-
MONTH [+/-]NUM -- this is somewhat ambiguous with MONTH YEAR
144+
MONTH [+/-]NUM
143145
```
144146

145147
For the details of date parsing

lua/daily-notes/config.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ local default = {
2424
"%Y/%m/%d",
2525
"%d/%m/%Y",
2626
"%m/%d/%Y",
27+
"%d %B, %Y",
28+
"%d %b, %Y",
29+
"%B %d, %Y",
30+
"%b %d, %y",
2731
"%A, %B %d %Y",
2832
"%a, %B %d %Y",
2933
},

lua/daily-notes/fuzzy-time.lua

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ M.get_timestamp = function(date_string, opts)
1818
return nil
1919
end
2020
local date_table = os.date("*t", timestamp)
21+
-- let awkward dates like Feb 21 be interpreted as days, not months
22+
if period == "month" and (format == "%B %Y" or format == "%b %Y") and date_table.year <= 31 then
23+
return nil
24+
end
2125
if (period == "month" or period == "year") and date_table.day ~= 1 then
2226
-- correct strange off-by-one error from strptime
2327
timestamp = timestamp + (24 * 60 * 60)
@@ -195,6 +199,31 @@ M.weekstamp = function(date_string, opts)
195199
return token
196200
end
197201

202+
M.number = function(min_digits, max_digits)
203+
local closure = function(date_string, opts)
204+
local digit_part = ""
205+
if max_digits <= 0 then
206+
digit_part = "%d+"
207+
else
208+
for i = 1, max_digits do
209+
if i <= min_digits then
210+
digit_part = digit_part .. "%d"
211+
else
212+
digit_part = digit_part .. "%d?"
213+
end
214+
end
215+
end
216+
local matched = M.match(digit_part .. "%s*")(date_string)
217+
if matched == nil then
218+
return nil
219+
end
220+
local stripped = string.gsub(matched.captured, "%s", "")
221+
local num = tonumber(stripped)
222+
return { type = "number", number = num, str = matched.str }
223+
end
224+
return closure
225+
end
226+
198227
M.number_offset = function(inverse)
199228
local closure = function(date_string, opts)
200229
local joiner = function(tokens)
@@ -414,6 +443,43 @@ M.weekday_number_offset = function(date_string, opts)
414443
return parser(date_string, opts)
415444
end
416445

446+
M.join_day_of_month = function(tokens, opts)
447+
local month_name = nil
448+
for _, token in pairs(tokens) do
449+
if token.type == "match" then
450+
month_name = string.gsub(token.captured, "%s", "")
451+
break
452+
end
453+
end
454+
if month_name == nil then
455+
return nil
456+
end
457+
local day_num = 0
458+
for _, token in pairs(tokens) do
459+
if token.type == "number" then
460+
day_num = token.number
461+
end
462+
end
463+
if day_num > 31 or day_num < 1 then
464+
return nil
465+
end
466+
local this_dt = datetime.get_month_from_today(month_name, opts.parsing.resolve_strategy.month.this, opts)
467+
if this_dt == nil then
468+
return nil
469+
end
470+
this_dt.day = day_num
471+
-- check that this isn't a nonsense date e.g. "Feb 31"
472+
local normalised = os.date("*t", os.time(this_dt))
473+
if normalised.day ~= this_dt.day then
474+
return nil
475+
end
476+
return {
477+
type = "period",
478+
period = { this_dt, "day" },
479+
str = tokens[#tokens].str
480+
}
481+
end
482+
417483

418484
M.join_month_numerical = function(tokens, opts)
419485
local month_name = nil
@@ -482,6 +548,14 @@ M.single_token_month = function(date_string, opts)
482548
return { type = "period", period = { dt, "month" }, str = "" }
483549
end
484550

551+
M.day_of_month = function(date_string, opts)
552+
local parser = M.select({
553+
M.join({ M.number(1, 2), M.match_month }, M.join_day_of_month),
554+
M.join({ M.match_month, M.number(1, 2) }, M.join_day_of_month)
555+
})
556+
return parser(date_string, opts)
557+
end
558+
485559
M.month_verbal_offset = function(date_string, opts)
486560
local parser = M.join({
487561
M.word_offset,
@@ -504,6 +578,7 @@ M.get_ambiguous_period = function(date_string, opts)
504578
M.weekday_verbal_offset,
505579
M.weekday_number_offset,
506580
M.single_token_month,
581+
M.day_of_month,
507582
M.month_verbal_offset,
508583
M.month_number_offset,
509584
})

0 commit comments

Comments
 (0)