1package DateTime::Format::Natural::Lang::EN;
2
3use strict;
4use warnings;
5use base qw(DateTime::Format::Natural::Lang::Base);
6# XXX constant.pm true/false: workaround for a segmentation fault
7# in Perl_mg_find() on perl 5.8.9 and 5.10.0 when using boolean.pm
8# v0.20 (tested as of 12/02/2009).
9#use boolean qw(true false);
10use constant true  => 1;
11use constant false => 0;
12use constant skip  => true;
13
14use DateTime::Format::Natural::Helpers qw(%flag);
15
16our $VERSION = '1.69';
17
18our (%init,
19     %timespan,
20     %units,
21     %suffixes,
22     %regexes,
23     %re,
24     %RE,
25     %data_weekdays,
26     %data_weekdays_abbrev,
27     @data_weekdays_all,
28     %data_months,
29     %data_months_abbrev,
30     @data_months_all,
31     %data_conversion,
32     %data_helpers,
33     %data_duration,
34     %data_aliases,
35     %data_rewrite,
36     %extended_checks,
37     %grammar);
38
39%init     = (tokens  => sub {});
40%timespan = (literal => 'to');
41%units    = (ordered => [ qw(second minute hour day week month year) ]);
42%suffixes = (ordinal => join '|', qw(st nd rd th d));
43%regexes  = (format_ => qr!((?:\d+?(?:-(?:[a-zA-Z]+?|\d+?)-|[./]\d+?[./])\d+?) | (?:\d+?/\d+?))!x);
44
45$regexes{format} = qr/^$regexes{format_}(?:(?=\s)|$)/;
46
47%re = (number   => qr/(\d+)/,
48       year     => qr/(\d{4})/,
49       time     => qr/((?:\d{1,2})(?:\:\d{2}){0,2})/,
50       time_am  => qr/((?:\d{1,2})(?:\:\d{2}){0,2})am/i,
51       time_pm  => qr/((?:\d{1,2})(?:\:\d{2}){0,2})pm/i,
52       time_min => qr/(\d{1,2}(?:\:\d{2}){1,2})/,
53       day      => qr/(\d+)($suffixes{ordinal})?/i,
54       monthday => qr/(\d{1,2})($suffixes{ordinal})?/i);
55{
56    foreach my $name (keys %re) {
57        $RE{$name} = qr/^$re{$name}$/;
58    }
59
60    my $sort = sub
61    {
62        my ($data) = @_;
63        return sort { $data->{$a} <=> $data->{$b} } keys %$data;
64    };
65    my $sort_abbrev = sub
66    {
67        my ($data_abbrev, $data) = @_;
68        return sort {
69            $data->{$data_abbrev->{$a}} <=> $data->{$data_abbrev->{$b}}
70        } keys %$data_abbrev;
71    };
72
73    my $i = 1;
74
75    %data_weekdays = map {
76        $_ => $i++
77    } qw(Monday Tuesday Wednesday Thursday Friday Saturday Sunday);
78    %data_weekdays_abbrev = map {
79        substr($_, 0, 3) => $_
80    } keys %data_weekdays;
81
82    @data_weekdays_all = ($sort->(\%data_weekdays), $sort_abbrev->(\%data_weekdays_abbrev, \%data_weekdays));
83
84    my $days_re = join '|', @data_weekdays_all;
85    $re{weekday} = qr/($days_re)/i;
86    $RE{weekday} = qr/^$re{weekday}$/;
87
88    $days_re = join '|', map "${_}s?", @data_weekdays_all;
89    $re{weekdays} = qr/($days_re)/i;
90    $RE{weekdays} = qr/^$re{weekdays}$/;
91
92    $i = 1;
93
94    %data_months = map {
95        $_ => $i++
96    } qw(January February March April May June July August September
97         October November December);
98    %data_months_abbrev = map {
99        substr($_, 0, 3) => $_
100    } keys %data_months;
101
102    @data_months_all = ($sort->(\%data_months), $sort_abbrev->(\%data_months_abbrev, \%data_months));
103
104    my $months_re = join '|', @data_months_all;
105    $re{month} = qr/($months_re)/i;
106    $RE{month} = qr/^$re{month}$/;
107
108    %data_conversion = (
109        last_this_next    => { do { $i = -1; map { $_ => $i++ } qw(last this next)           } },
110        yes_today_tom     => { do { $i = -1; map { $_ => $i++ } qw(yesterday today tomorrow) } },
111        noon_midnight     => { noon => 12, midnight => 0                                       },
112        morn_aftern_even  => { do { $i = 0; map { $_ => $i++ } qw(morning afternoon evening) } },
113        before_after_from => { before => -1, after => 1, from => 1                             },
114    );
115
116    %data_helpers = (
117        suffix      => qr/s$/i,
118        normalize   => sub { ${$_[0]} = ucfirst lc ${$_[0]} },
119        abbreviated => sub { length ${$_[0]} == 3 },
120    );
121
122    %data_duration = (
123        for => {
124            regex   => qr/^for \s+ \d+ \s+ \S+$/ix,
125            present => 'now',
126        },
127        first_to_last => {
128            regexes => {
129                first   => qr/first/i,
130                last    => qr/last \s+ day \s+ of \s+ (?:$re{month}|$re{year})/ix,
131                extract => qr/^\S+? \s+ (.+)$/x,
132            },
133        },
134        from_count_to_count => {
135            regexes => {
136                time_meridiem => qr/\d{1,2}(?:\:\d{2}){0,2}(?:\s*?(?:am|pm))/i,
137                time          => qr/\d{1,2}(?:\:\d{2}){1,2}/,
138                day_ordinal   => qr/\d{1,3}(?:$suffixes{ordinal})/i,
139                day           => qr/\d{1,3}/,
140            },
141            order => [qw(
142                time_meridiem
143                time
144                day_ordinal
145                day
146            )],
147            categories => {
148                time_meridiem => 'time',
149                time          => 'time',
150                day_ordinal   => 'day',
151                day           => 'day',
152            },
153            extract => {
154                left => {
155                    time => qr/(?:$regexes{format_}|$re{day}\s+$re{month}|$re{month}\s+$re{day})/,
156                    day  => qr/$re{month}/,
157                },
158                right => {
159                    time => qr/(?:$re{day}\s+$re{month}|$re{month}\s+$re{day})/,
160                    day  => qr/(?:$re{month}|day)/i,
161                },
162            },
163        },
164    );
165
166    %data_aliases = (
167        words => {
168            tues  => 'tue',
169            thur  => 'thu',
170            thurs => 'thu',
171        },
172        tokens => {
173            sec  => 'second',
174            secs => 'seconds',
175            min  => 'minute',
176            mins => 'minutes',
177            hr   => 'hour',
178            hrs  => 'hours',
179            yr   => 'year',
180            yrs  => 'years',
181            '@'  => 'at',
182        },
183        short => {
184            min => 'minute',
185            d   => 'day',
186        },
187    );
188
189    %data_rewrite = (
190        at => {
191            match   => qr/\S+? \s+? at \s+? (\S+)/ix,
192            subst   => qr/\s+? at \b/ix,
193            daytime => qr/^(?:noon|midnight)$/i,
194        },
195    );
196}
197
198%extended_checks = (
199    meridiem => sub
200    {
201        my ($first_stack, $rest_stack, $pos, $error) = @_;
202
203        my ($hour) = split /:/, $first_stack->{$pos->[0]};
204
205        if ($hour == 0) {
206            $$error = 'hour zero must be literal 12';
207            return false;
208        }
209        elsif ($hour > 12) {
210            $$error = 'hour exceeds 12-hour clock';
211            return false;
212        }
213        return true;
214    },
215    ordinal => sub
216    {
217        my ($first_stack, $rest_stack, $pos, $error) = @_;
218
219        my $suffix = do {
220            local $_ = $rest_stack->{$pos->[0]}->[0];
221            defined $_ ? lc $_ : undef;
222        };
223        return skip unless defined $suffix;
224
225        my $numeral = $first_stack->{$pos->[0]};
226
227        my %ordinals = (
228            1 => { regex => qr/^st$/,  suffix => 'st' },
229            2 => { regex => qr/^n?d$/, suffix => 'nd' },
230            3 => { regex => qr/^r?d$/, suffix => 'rd' },
231        );
232
233        my $fail_message = sub { "letter suffix should be '$_[0]'" };
234
235        local $1;
236        if ($numeral == 0) {
237            unless ($suffix eq 'th') {
238                $$error = $fail_message->('th');
239                return false;
240            }
241            return true;
242        }
243        elsif ($numeral =~ /([1-3])$/ && $numeral !~ /1\d$/) {
244            unless ($suffix =~ $ordinals{$1}->{regex}) {
245                $$error = $fail_message->($ordinals{$1}->{suffix});
246                return false;
247            }
248            return true;
249        }
250        elsif ($numeral > 3) {
251            unless ($suffix eq 'th') {
252                $$error = $fail_message->('th');
253                return false;
254            }
255            return true;
256        }
257        return skip; # never reached
258    },
259    suffix => sub
260    {
261        my ($first_stack, $rest_stack, $pos, $error) = @_;
262
263        my @checks = (
264            { cond  => sub { $first_stack->{$pos->[0]} == 1 && $first_stack->{$pos->[1]} =~ $data_helpers{suffix} },
265              error => "suffix 's' without plural",
266            },
267            { cond  => sub { $first_stack->{$pos->[0]} >  1 && $first_stack->{$pos->[1]} !~ $data_helpers{suffix} },
268              error => "plural without suffix 's'",
269            },
270        );
271        foreach my $check (@checks) {
272            if ($check->{cond}->()) {
273                $$error = $check->{error};
274                return false;
275            }
276        }
277        return true;
278    },
279);
280
281# <keyword> => [
282#    [ <PERL TYPE DECLARATION>, ... ], ---------------------> declares how the tokens will be evaluated
283#    [
284#      { <token index> => <token value>, ... }, ------------> declares the index <-> value map
285#      [ [ <index(es) of token(s) to be passed> ], ... ], --> declares which tokens will be passed to the extended check(s)
286#      [ <subroutine(s) for extended check(s)>, ... ], -----> declares the extended check(s)
287#      [ [ <index(es) of token(s) to be passed> ], ... ], --> declares which tokens will be passed to the worker method(s)
288#      [ { <additional options to be passed> }, ... ], -----> declares additional options
289#      [ <name of method to dispatch to>, ... ], -----------> declares the worker method(s)
290#      { <shared option>, ... }, ---------------------------> declares shared options (post-processed)
291#    ],
292
293#
294# NOTE: the grammar here does not cover all valid input string
295# variations; see Rewrite.pm for how date strings are rewritten
296# before parsing.
297#
298
299%grammar = (
300    now => [
301       [ 'SCALAR' ],
302       [
303         { 0 => 'now' },
304         [],
305         [],
306         [ [] ],
307         [ {} ],
308         [ '_no_op' ],
309         {},
310       ],
311    ],
312    day => [
313       [ 'REGEXP' ],
314       [
315         { 0 => qr/^(today)$/i },
316         [],
317         [],
318         [
319           [
320             { 0 => [ $flag{yes_today_tom} ] },
321           ],
322         ],
323         [ { unit => 'day' } ],
324         [ '_unit_variant' ],
325         { truncate_to => [q(day)] },
326       ],
327       [
328         { 0 => qr/^(yesterday)$/i },
329         [],
330         [],
331         [
332           [
333             { 0 => [ $flag{yes_today_tom} ] },
334           ],
335         ],
336         [ { unit => 'day' } ],
337         [ '_unit_variant' ],
338         { truncate_to => [q(day)] },
339       ],
340       [
341         { 0 => qr/^(tomorrow)$/i },
342         [],
343         [],
344         [
345           [
346             { 0 => [ $flag{yes_today_tom} ] },
347           ],
348         ],
349         [ { unit => 'day' } ],
350         [ '_unit_variant' ],
351         { truncate_to => [q(day)] },
352       ],
353    ],
354    daytime => [
355       [ 'REGEXP' ],
356       [
357         { 0 => qr/^(morning)$/i },
358         [],
359         [],
360         [
361           [
362             { 0 => [ $flag{morn_aftern_even} ] },
363           ],
364         ],
365         [ {} ],
366         [ '_daytime_variant' ],
367         {
368           advance_future => true,
369           truncate_to    => [q(hour)],
370         },
371       ],
372       [
373         { 0 => qr/^(afternoon)$/i },
374         [],
375         [],
376         [
377           [
378             { 0 => [ $flag{morn_aftern_even} ] },
379           ],
380         ],
381         [ {} ],
382         [ '_daytime_variant' ],
383         {
384           advance_future => true,
385           truncate_to    => [q(hour)],
386         },
387       ],
388       [
389         { 0 => qr/^(evening)$/i },
390         [],
391         [],
392         [
393           [
394             { 0 => [ $flag{morn_aftern_even} ] },
395           ],
396         ],
397         [ {} ],
398         [ '_daytime_variant' ],
399         {
400           advance_future => true,
401           truncate_to    => [q(hour)],
402         },
403       ]
404    ],
405    daytime_noon_midnight => [
406       [ 'REGEXP' ],
407       [
408         { 0 => qr/^(noon)$/i },
409         [],
410         [],
411         [
412           [
413             { 0 => [ $flag{noon_midnight} ] },
414           ],
415         ],
416         [ {} ],
417         [ '_daytime' ],
418         {
419           advance_future => true,
420           truncate_to    => [q(hour)],
421         },
422       ],
423       [
424         { 0 => qr/^(midnight)$/i },
425         [],
426         [],
427         [
428           [
429             { 0 => [ $flag{noon_midnight} ] },
430           ]
431         ],
432         [ {} ],
433         [ '_daytime' ],
434         {
435           advance_future => true,
436           truncate_to    => [q(hour)],
437         },
438       ],
439    ],
440    daytime_noon_midnight_at => [
441       [ 'REGEXP', 'REGEXP' ],
442       [
443         { 0 => qr/^(yesterday)$/i, 1 => qr/^(noon)$/i },
444         [],
445         [],
446         [
447           [
448             { 0 => [ $flag{yes_today_tom} ] },
449           ],
450           [
451             { 1 => [ $flag{noon_midnight} ] },
452           ],
453         ],
454         [ { unit => 'day' }, {} ],
455         [ '_unit_variant', '_daytime' ],
456         { truncate_to => [undef, q(hour)] },
457       ],
458       [
459         { 0 => qr/^(yesterday)$/i, 1 => qr/^(midnight)$/i },
460         [],
461         [],
462         [
463           [
464             { 0 => [ $flag{yes_today_tom} ] },
465           ],
466           [
467             { 1 => [ $flag{noon_midnight} ] },
468           ],
469         ],
470         [ { unit => 'day' }, {} ],
471         [ '_unit_variant', '_daytime' ],
472         { truncate_to => [undef, q(hour)] },
473       ],
474       [
475         { 0 => qr/^(today)$/i, 1 => qr/^(noon)$/i },
476         [],
477         [],
478         [
479           [
480             { 0 => [ $flag{yes_today_tom} ] },
481           ],
482           [
483             { 1 => [ $flag{noon_midnight} ] },
484           ],
485         ],
486         [ { unit => 'day' }, {} ],
487         [ '_unit_variant', '_daytime' ],
488         { truncate_to => [undef, q(hour)] },
489       ],
490       [
491         { 0 => qr/^(today)$/i, 1 => qr/^(midnight)$/i },
492         [],
493         [],
494         [
495           [
496             { 0 => [ $flag{yes_today_tom} ] },
497           ],
498           [
499             { 1 => [ $flag{noon_midnight} ] },
500           ],
501         ],
502         [ { unit => 'day' }, {} ],
503         [ '_unit_variant', '_daytime' ],
504         { truncate_to => [undef, q(hour)] },
505       ],
506       [
507         { 0 => qr/^(tomorrow)$/i, 1 => qr/^(noon)$/i },
508         [],
509         [],
510         [
511           [
512             { 0 => [ $flag{yes_today_tom} ] },
513           ],
514           [
515             { 1 => [ $flag{noon_midnight} ] },
516           ]
517         ],
518         [ { unit => 'day' }, {} ],
519         [ '_unit_variant', '_daytime' ],
520         { truncate_to => [undef, q(hour)] },
521       ],
522       [
523         { 0 => qr/^(tomorrow)$/i, 1 => qr/^(midnight)$/i },
524         [],
525         [],
526         [
527           [
528             { 0 => [ $flag{yes_today_tom} ] },
529           ],
530           [
531             { 1 => [ $flag{noon_midnight} ] },
532           ],
533         ],
534         [ { unit => 'day' }, {} ],
535         [ '_unit_variant', '_daytime' ],
536         { truncate_to => [undef, q(hour)] },
537       ],
538    ],
539    daytime_variant_weekday => [
540       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
541       [
542         { 0 => qr/^(noon)$/i, 1 => qr/^(next)$/i, 2 => $RE{weekday} },
543         [],
544         [],
545         [
546           [
547             { 0 => [ $flag{noon_midnight} ] },
548           ],
549           [
550             { 1 => [ $flag{last_this_next} ] },
551             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
552           ],
553         ],
554         [ {}, {} ],
555         [ '_daytime', '_count_day_variant_week' ],
556         { truncate_to => [undef, q(hour)] },
557       ],
558       [
559         { 0 => qr/^(midnight)$/i, 1 => qr/^(next)$/i, 2 => $RE{weekday} },
560         [],
561         [],
562         [
563           [
564             { 0 => [ $flag{noon_midnight} ] },
565           ],
566           [
567             { 1 => [ $flag{last_this_next} ] },
568             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
569           ],
570         ],
571         [ {}, {} ],
572         [ '_daytime', '_count_day_variant_week' ],
573         { truncate_to => [undef, q(hour)] },
574       ],
575       [
576         { 0 => qr/^(noon)$/i, 1 => qr/^(this)$/i, 2 => $RE{weekday} },
577         [],
578         [],
579         [
580           [
581             { 0 => [ $flag{noon_midnight} ] },
582           ],
583           [
584             { 1 => [ $flag{last_this_next} ] },
585             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
586           ],
587         ],
588         [ {}, {} ],
589         [ '_daytime', '_count_day_variant_week' ],
590         { truncate_to => [undef, q(hour)] },
591       ],
592       [
593         { 0 => qr/^(midnight)$/i, 1 => qr/^(this)$/i, 2 => $RE{weekday} },
594         [],
595         [],
596         [
597           [
598             { 0 => [ $flag{noon_midnight} ] },
599           ],
600           [
601             { 1 => [ $flag{last_this_next} ] },
602             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
603           ],
604         ],
605         [ {}, {} ],
606         [ '_daytime', '_count_day_variant_week' ],
607         { truncate_to => [undef, q(hour)] },
608       ],
609       [
610         { 0 => qr/^(noon)$/i, 1 => qr/^(last)$/i, 2 => $RE{weekday} },
611         [],
612         [],
613         [
614           [
615             { 0 => [ $flag{noon_midnight} ] },
616           ],
617           [
618             { 1 => [ $flag{last_this_next} ] },
619             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
620           ],
621         ],
622         [ {}, {} ],
623         [ '_daytime', '_count_day_variant_week' ],
624         { truncate_to => [undef, q(hour)] },
625       ],
626       [
627         { 0 => qr/^(midnight)$/i, 1 => qr/^(last)$/i, 2 => $RE{weekday} },
628         [],
629         [],
630         [
631           [
632             { 0 => [ $flag{noon_midnight} ] },
633           ],
634           [
635             { 1 => [ $flag{last_this_next} ] },
636             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
637           ],
638         ],
639         [ {}, {} ],
640         [ '_daytime', '_count_day_variant_week' ],
641         { truncate_to => [undef, q(hour)] },
642       ],
643    ],
644    this_daytime => [
645       [ 'SCALAR', 'REGEXP' ],
646       [
647         { 0 => 'this', 1 => qr/^(morning)$/i },
648         [],
649         [],
650         [
651           [
652             { 1 => [ $flag{morn_aftern_even} ] },
653           ],
654         ],
655         [ {} ],
656         [ '_daytime_variant' ],
657         { truncate_to => [q(hour)] },
658       ],
659       [
660         { 0 => 'this', 1 => qr/^(afternoon)$/i },
661         [],
662         [],
663         [
664           [
665             { 1 => [ $flag{morn_aftern_even} ] },
666           ]
667         ],
668         [ {} ],
669         [ '_daytime_variant' ],
670         { truncate_to => [q(hour)] },
671       ],
672       [
673         { 0 => 'this', 1 => qr/^(evening)$/i },
674         [],
675         [],
676         [
677           [
678             { 1 => [ $flag{morn_aftern_even} ] },
679           ],
680         ],
681         [ {} ],
682         [ '_daytime_variant' ],
683         { truncate_to => [q(hour)] },
684       ],
685    ],
686    daytime_day => [
687       [ 'REGEXP', 'REGEXP' ],
688       [
689         { 0 => qr/^(yesterday)$/i, 1 => qr/^(morning)$/i },
690         [],
691         [],
692         [
693           [
694             { 0 => [ $flag{yes_today_tom} ] },
695           ],
696           [
697             { 1 => [ $flag{morn_aftern_even} ] },
698           ],
699         ],
700         [ { unit => 'day' }, {} ],
701         [ '_unit_variant', '_daytime_variant' ],
702         { truncate_to => [undef, q(hour)] },
703       ],
704       [
705         { 0 => qr/^(yesterday)$/i, 1 => qr/^(afternoon)$/i },
706         [],
707         [],
708         [
709           [
710             { 0 => [ $flag{yes_today_tom} ] },
711           ],
712           [
713             { 1 => [ $flag{morn_aftern_even} ] },
714           ]
715         ],
716         [ { unit => 'day' }, {} ],
717         [ '_unit_variant', '_daytime_variant' ],
718         { truncate_to => [undef, q(hour)] },
719       ],
720       [
721         { 0 => qr/^(yesterday)$/i, 1 => qr/^(evening)$/i },
722         [],
723         [],
724         [
725           [
726             { 0 => [ $flag{yes_today_tom} ] },
727           ],
728           [
729             { 1 => [ $flag{morn_aftern_even} ] },
730           ],
731         ],
732         [ { unit => 'day' }, {} ],
733         [ '_unit_variant', '_daytime_variant' ],
734         { truncate_to => [undef, q(hour)] },
735       ],
736       [
737         { 0 => qr/^(today)$/i, 1 => qr/^(morning)$/i },
738         [],
739         [],
740         [
741           [
742             { 0 => [ $flag{yes_today_tom} ] },
743           ],
744           [
745             { 1 => [ $flag{morn_aftern_even} ] },
746           ]
747         ],
748         [ { unit => 'day' }, {} ],
749         [ '_unit_variant', '_daytime_variant' ],
750         { truncate_to => [undef, q(hour)] },
751       ],
752       [
753         { 0 => qr/^(today)$/i, 1 => qr/^(afternoon)$/i },
754         [],
755         [],
756         [
757           [
758             { 0 => [ $flag{yes_today_tom} ] },
759           ],
760           [
761             { 1 => [ $flag{morn_aftern_even} ] },
762           ],
763         ],
764         [ { unit => 'day' }, {} ],
765         [ '_unit_variant', '_daytime_variant' ],
766         { truncate_to => [undef, q(hour)] },
767       ],
768       [
769         { 0 => qr/^(today)$/i, 1 => qr/^(evening)$/i },
770         [],
771         [],
772         [
773           [
774             { 0 => [ $flag{yes_today_tom} ] },
775           ],
776           [
777             { 1 => [ $flag{morn_aftern_even} ] },
778           ],
779         ],
780         [ { unit => 'day' }, {} ],
781         [ '_unit_variant', '_daytime_variant' ],
782         { truncate_to => [undef, q(hour)] },
783       ],
784       [
785         { 0 => qr/^(tomorrow)$/i, 1 => qr/^(morning)$/i },
786         [],
787         [],
788         [
789           [
790             { 0 => [ $flag{yes_today_tom} ] },
791           ],
792           [
793             { 1 => [ $flag{morn_aftern_even} ] },
794           ]
795         ],
796         [ { unit => 'day' }, {} ],
797         [ '_unit_variant', '_daytime_variant' ],
798         { truncate_to => [undef, q(hour)] },
799       ],
800       [
801         { 0 => qr/^(tomorrow)$/i, 1 => qr/^(afternoon)$/i },
802         [],
803         [],
804         [
805           [
806             { 0 => [ $flag{yes_today_tom} ] },
807           ],
808           [
809             { 1 => [ $flag{morn_aftern_even} ] },
810           ],
811         ],
812         [ { unit => 'day' }, {} ],
813         [ '_unit_variant', '_daytime_variant' ],
814         { truncate_to => [undef, q(hour)] },
815       ],
816       [
817         { 0 => qr/^(tomorrow)$/i, 1 => qr/^(evening)$/i },
818         [],
819         [],
820         [
821           [
822             { 0 => [ $flag{yes_today_tom} ] },
823           ],
824           [
825             { 1 => [ $flag{morn_aftern_even} ] },
826           ]
827         ],
828         [ { unit => 'day' }, {} ],
829         [ '_unit_variant', '_daytime_variant' ],
830         { truncate_to => [undef, q(hour)] },
831       ],
832    ],
833    weekday_daytime => [
834       [ 'REGEXP', 'REGEXP' ],
835       [
836         { 0 => $RE{weekday}, 1 => qr/^(morning)$/i },
837         [],
838         [],
839         [
840           [
841             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
842           ],
843           [
844             { 1 => [ $flag{morn_aftern_even} ] },
845           ]
846         ],
847         [ {}, {} ],
848         [ '_weekday', '_daytime_variant' ],
849         {
850           advance_future => true,
851           truncate_to    => [undef, q(hour)],
852         },
853       ],
854       [
855         { 0 => $RE{weekday}, 1 => qr/^(afternoon)$/i },
856         [],
857         [],
858         [
859           [
860             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
861           ],
862           [
863             { 1 => [ $flag{morn_aftern_even} ] },
864           ],
865         ],
866         [ {}, {} ],
867         [ '_weekday', '_daytime_variant' ],
868         {
869           advance_future => true,
870           truncate_to    => [undef, q(hour)],
871         },
872       ],
873       [
874         { 0 => $RE{weekday}, 1 => qr/^(evening)$/i },
875         [],
876         [],
877         [
878           [
879             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
880           ],
881           [
882             { 1 => [ $flag{morn_aftern_even} ] },
883           ]
884         ],
885         [ {}, {} ],
886         [ '_weekday', '_daytime_variant' ],
887         {
888           advance_future => true,
889           truncate_to    => [undef, q(hour)],
890         },
891       ],
892    ],
893    at_daytime => [
894       [ 'REGEXP', 'REGEXP' ],
895       [
896         { 0 => $RE{time}, 1 => qr/^(yesterday)$/i },
897         [],
898         [],
899         [
900           [ 0 ],
901           [
902             { 1 => [ $flag{yes_today_tom} ] },
903           ],
904         ],
905         [ {}, { unit => 'day' } ],
906         [ '_time', '_unit_variant' ],
907         { truncate_to => [undef, q(hour_minute)] },
908       ],
909       [
910         { 0 => $RE{time}, 1 => qr/^(today)$/i },
911         [],
912         [],
913         [
914           [ 0 ],
915           [
916             { 1 => [ $flag{yes_today_tom} ] },
917           ],
918         ],
919         [ {}, { unit => 'day' } ],
920         [ '_time', '_unit_variant' ],
921         { truncate_to => [undef, q(hour_minute)] },
922       ],
923       [
924         { 0 => $RE{time}, 1 => qr/^(tomorrow)$/i },
925         [],
926         [],
927         [
928           [ 0 ],
929           [
930             { 1 => [ $flag{yes_today_tom} ] },
931           ],
932         ],
933         [ {}, { unit => 'day' } ],
934         [ '_time', '_unit_variant' ],
935         { truncate_to => [undef, q(hour_minute)] },
936       ],
937       [
938         { 0 => $RE{time_am}, 1 => qr/^(yesterday)$/i },
939         [ [ 0 ] ],
940         [ $extended_checks{meridiem} ],
941         [
942           [
943             { 0 => [ $flag{time_am} ] },
944           ],
945           [
946             { 1 => [ $flag{yes_today_tom} ] },
947           ],
948         ],
949         [ {}, { unit => 'day' } ],
950         [ '_at', '_unit_variant' ],
951         { truncate_to => [undef, q(hour_minute)] },
952       ],
953       [
954         { 0 => $RE{time_am}, 1 => qr/^(today)$/i },
955         [ [ 0 ] ],
956         [ $extended_checks{meridiem} ],
957         [
958           [
959             { 0 => [ $flag{time_am} ] },
960           ],
961           [
962             { 1 => [ $flag{yes_today_tom} ] },
963           ],
964         ],
965         [ {}, { unit => 'day' } ],
966         [ '_at', '_unit_variant' ],
967         { truncate_to => [undef, q(hour_minute)] },
968       ],
969       [
970         { 0 => $RE{time_am}, 1 => qr/^(tomorrow)$/i },
971         [ [ 0 ] ],
972         [ $extended_checks{meridiem} ],
973         [
974           [
975             { 0 => [ $flag{time_am} ] },
976           ],
977           [
978             { 1 => [ $flag{yes_today_tom} ] },
979           ],
980         ],
981         [ {}, { unit => 'day' } ],
982         [ '_at', '_unit_variant' ],
983         { truncate_to => [undef, q(hour_minute)] },
984       ],
985       [
986         { 0 => $RE{time_pm}, 1 => qr/^(yesterday)$/i },
987         [ [ 0 ] ],
988         [ $extended_checks{meridiem} ],
989         [
990           [
991             { 0 => [ $flag{time_pm} ] },
992           ],
993           [
994             { 1 => [ $flag{yes_today_tom} ] },
995           ],
996         ],
997         [ {}, { unit => 'day' } ],
998         [ '_at', '_unit_variant' ],
999         { truncate_to => [undef, q(hour_minute)] },
1000       ],
1001       [
1002         { 0 => $RE{time_pm}, 1 => qr/^(today)$/i },
1003         [ [ 0 ] ],
1004         [ $extended_checks{meridiem} ],
1005         [
1006           [
1007             { 0 => [ $flag{time_pm} ] },
1008           ],
1009           [
1010             { 1 => [ $flag{yes_today_tom} ] },
1011           ],
1012         ],
1013         [ {}, { unit => 'day' } ],
1014         [ '_at', '_unit_variant' ],
1015         { truncate_to => [undef, q(hour_minute)] },
1016       ],
1017       [
1018         { 0 => $RE{time_pm}, 1 => qr/^(tomorrow)$/i },
1019         [ [ 0 ] ],
1020         [ $extended_checks{meridiem} ],
1021         [
1022           [
1023             { 0 => [ $flag{time_pm} ] },
1024           ],
1025           [
1026             { 1 => [ $flag{yes_today_tom} ] },
1027           ],
1028         ],
1029         [ {}, { unit => 'day' } ],
1030         [ '_at', '_unit_variant' ],
1031         { truncate_to => [undef, q(hour_minute)] },
1032       ],
1033    ],
1034    at_variant_weekday => [
1035       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1036       [
1037         { 0 => $RE{time}, 1 => qr/^(next)$/i, 2 => $RE{weekday} },
1038         [],
1039         [],
1040         [
1041           [ 0 ],
1042           [
1043             { 1 => [ $flag{last_this_next} ] },
1044             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1045           ],
1046         ],
1047         [ {}, {} ],
1048         [ '_time', '_count_day_variant_week' ],
1049         { truncate_to => [undef, q(hour_minute)] },
1050       ],
1051       [
1052         { 0 => $RE{time}, 1 => qr/^(this)$/i, 2 => $RE{weekday} },
1053         [],
1054         [],
1055         [
1056           [ 0 ],
1057           [
1058             { 1 => [ $flag{last_this_next} ] },
1059             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1060           ],
1061         ],
1062         [ {}, {} ],
1063         [ '_time', '_count_day_variant_week' ],
1064         { truncate_to => [undef, q(hour_minute)] },
1065       ],
1066       [
1067         { 0 => $RE{time}, 1 => qr/^(last)$/i, 2 => $RE{weekday} },
1068         [],
1069         [],
1070         [
1071           [ 0 ],
1072           [
1073             { 1 => [ $flag{last_this_next} ] },
1074             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1075           ],
1076         ],
1077         [ {}, {} ],
1078         [ '_time', '_count_day_variant_week' ],
1079         { truncate_to => [undef, q(hour_minute)] },
1080       ],
1081       [
1082         { 0 => $RE{time_am}, 1 => qr/^(next)$/i, 2 => $RE{weekday} },
1083         [ [ 0 ] ],
1084         [ $extended_checks{meridiem} ],
1085         [
1086           [
1087             { 0 => [ $flag{time_am} ] },
1088           ],
1089           [
1090             { 1 => [ $flag{last_this_next} ] },
1091             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1092           ],
1093         ],
1094         [ {}, {} ],
1095         [ '_at', '_count_day_variant_week' ],
1096         { truncate_to => [undef, q(hour_minute)] },
1097       ],
1098       [
1099         { 0 => $RE{time_am}, 1 => qr/^(this)$/i, 2 => $RE{weekday} },
1100         [ [ 0 ] ],
1101         [ $extended_checks{meridiem} ],
1102         [
1103           [
1104             { 0 => [ $flag{time_am} ] },
1105           ],
1106           [
1107             { 1 => [ $flag{last_this_next} ] },
1108             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1109           ],
1110         ],
1111         [ {}, {} ],
1112         [ '_at', '_count_day_variant_week' ],
1113         { truncate_to => [undef, q(hour_minute)] },
1114       ],
1115       [
1116         { 0 => $RE{time_am}, 1 => qr/^(last)$/i, 2 => $RE{weekday} },
1117         [ [ 0 ] ],
1118         [ $extended_checks{meridiem} ],
1119         [
1120           [
1121             { 0 => [ $flag{time_am} ] },
1122           ],
1123           [
1124             { 1 => [ $flag{last_this_next} ] },
1125             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1126           ],
1127         ],
1128         [ {}, {} ],
1129         [ '_at', '_count_day_variant_week' ],
1130         { truncate_to => [undef, q(hour_minute)] },
1131       ],
1132       [
1133         { 0 => $RE{time_pm}, 1 => qr/^(next)$/i, 2 => $RE{weekday} },
1134         [ [ 0 ] ],
1135         [ $extended_checks{meridiem} ],
1136         [
1137           [
1138             { 0 => [ $flag{time_pm} ] },
1139           ],
1140           [
1141             { 1 => [ $flag{last_this_next} ] },
1142             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1143           ],
1144         ],
1145         [ {}, {} ],
1146         [ '_at', '_count_day_variant_week' ],
1147         { truncate_to => [undef, q(hour_minute)] },
1148       ],
1149       [
1150         { 0 => $RE{time_pm}, 1 => qr/^(this)$/i, 2 => $RE{weekday} },
1151         [ [ 0 ] ],
1152         [ $extended_checks{meridiem} ],
1153         [
1154           [
1155             { 0 => [ $flag{time_pm} ] },
1156           ],
1157           [
1158             { 1 => [ $flag{last_this_next} ] },
1159             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1160           ],
1161         ],
1162         [ {}, {} ],
1163         [ '_at', '_count_day_variant_week' ],
1164         { truncate_to => [undef, q(hour_minute)] },
1165       ],
1166       [
1167         { 0 => $RE{time_pm}, 1 => qr/^(last)$/i, 2 => $RE{weekday} },
1168         [ [ 0 ] ],
1169         [ $extended_checks{meridiem} ],
1170         [
1171           [
1172             { 0 => [ $flag{time_pm} ] },
1173           ],
1174           [
1175             { 1 => [ $flag{last_this_next} ] },
1176             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1177           ],
1178         ],
1179         [ {}, {} ],
1180         [ '_at', '_count_day_variant_week' ],
1181         { truncate_to => [undef, q(hour_minute)] },
1182       ],
1183    ],
1184    variant_weekday_at => [
1185       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1186       [
1187         { 0 => qr/^(last)$/i, 1 => $RE{weekday}, 2 => $RE{time_am} },
1188         [ [ 2 ] ],
1189         [ $extended_checks{meridiem} ],
1190         [
1191           [
1192             { 0 => [ $flag{last_this_next} ] },
1193             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1194           ],
1195           [
1196             { 2 => [ $flag{time_am} ] },
1197           ],
1198         ],
1199         [ {}, {} ],
1200         [ '_count_day_variant_week', '_at' ],
1201         { truncate_to => [undef, q(hour_minute)] },
1202       ],
1203       [
1204         { 0 => qr/^(this)$/i, 1 => $RE{weekday}, 2 => $RE{time_am} },
1205         [ [ 2 ] ],
1206         [ $extended_checks{meridiem} ],
1207         [
1208           [
1209             { 0 => [ $flag{last_this_next} ] },
1210             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1211           ],
1212           [
1213             { 2 => [ $flag{time_am} ] },
1214           ],
1215         ],
1216         [ {}, {} ],
1217         [ '_count_day_variant_week', '_at' ],
1218         { truncate_to => [undef, q(hour_minute)] },
1219       ],
1220       [
1221         { 0 => qr/^(next)$/i, 1 => $RE{weekday}, 2 => $RE{time_am} },
1222         [ [ 2 ] ],
1223         [ $extended_checks{meridiem} ],
1224         [
1225           [
1226             { 0 => [ $flag{last_this_next} ] },
1227             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1228           ],
1229           [
1230             { 2 => [ $flag{time_am} ] },
1231           ],
1232         ],
1233         [ {}, {} ],
1234         [ '_count_day_variant_week', '_at' ],
1235         { truncate_to => [undef, q(hour_minute)] },
1236       ],
1237       [
1238         { 0 => qr/^(last)$/i, 1 => $RE{weekday}, 2 => $RE{time_pm} },
1239         [ [ 2 ] ],
1240         [ $extended_checks{meridiem} ],
1241         [
1242           [
1243             { 0 => [ $flag{last_this_next} ] },
1244             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1245           ],
1246           [
1247             { 2 => [ $flag{time_pm} ] },
1248           ],
1249         ],
1250         [ {}, {} ],
1251         [ '_count_day_variant_week', '_at' ],
1252         { truncate_to => [undef, q(hour_minute)] },
1253       ],
1254       [
1255         { 0 => qr/^(this)$/i, 1 => $RE{weekday}, 2 => $RE{time_pm} },
1256         [ [ 2 ] ],
1257         [ $extended_checks{meridiem} ],
1258         [
1259           [
1260             { 0 => [ $flag{last_this_next} ] },
1261             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1262           ],
1263           [
1264             { 2 => [ $flag{time_pm} ] },
1265           ],
1266         ],
1267         [ {}, {} ],
1268         [ '_count_day_variant_week', '_at' ],
1269         { truncate_to => [undef, q(hour_minute)] },
1270       ],
1271       [
1272         { 0 => qr/^(next)$/i, 1 => $RE{weekday}, 2 => $RE{time_pm} },
1273         [ [ 2 ] ],
1274         [ $extended_checks{meridiem} ],
1275         [
1276           [
1277             { 0 => [ $flag{last_this_next} ] },
1278             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1279           ],
1280           [
1281             { 2 => [ $flag{time_pm} ] },
1282           ],
1283         ],
1284         [ {}, {} ],
1285         [ '_count_day_variant_week', '_at' ],
1286         { truncate_to => [undef, q(hour_minute)] },
1287       ],
1288    ],
1289    month => [
1290       [ 'REGEXP' ],
1291       [
1292         { 0 => $RE{month} },
1293         [],
1294         [],
1295         [
1296           [
1297             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1298           ],
1299         ],
1300         [ { unit => 'month' } ],
1301         [ '_unit_date' ],
1302         {
1303           advance_future => true,
1304           truncate_to    => [q(month)],
1305         },
1306       ],
1307    ],
1308    month_day => [
1309       [ 'REGEXP', 'REGEXP' ],
1310       [
1311         { 0 => $RE{monthday}, 1 => $RE{month} },
1312         [ [ 0 ] ],
1313         [ $extended_checks{ordinal} ],
1314         [
1315           [
1316               0,
1317             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1318           ],
1319         ],
1320         [ {} ],
1321         [ '_month_day' ],
1322         {
1323           advance_future => true,
1324           truncate_to    => [q(day)],
1325         },
1326       ],
1327       [
1328         { 0 => $RE{month}, 1 => $RE{monthday} },
1329         [ [ 1 ] ],
1330         [ $extended_checks{ordinal} ],
1331         [
1332           [
1333               1,
1334             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1335           ],
1336         ],
1337         [ {} ],
1338         [ '_month_day' ],
1339         {
1340           advance_future => true,
1341           truncate_to    => [q(day)],
1342         },
1343       ]
1344    ],
1345    month_day_at => [
1346       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1347       [
1348         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{time_min} },
1349         [ [ 1 ] ],
1350         [ $extended_checks{ordinal} ],
1351         [
1352           [
1353               1,
1354             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1355           ],
1356           [ 2 ],
1357         ],
1358         [ {}, {} ],
1359         [ '_month_day', '_time' ],
1360         { truncate_to => [undef, q(minute)] },
1361       ],
1362       [
1363         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{time_am} },
1364         [ [ 1 ], [ 2 ] ],
1365         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1366         [
1367           [
1368               1,
1369             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1370           ],
1371           [
1372             { 2 => [ $flag{time_am} ] },
1373           ],
1374         ],
1375         [ {}, {} ],
1376         [ '_month_day', '_at' ],
1377         { truncate_to => [undef, q(hour_minute)] },
1378       ],
1379       [
1380         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{time_pm} },
1381         [ [ 1 ], [ 2 ] ],
1382         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1383         [
1384           [
1385               1,
1386             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1387           ],
1388           [
1389             { 2 => [ $flag{time_pm} ] },
1390           ],
1391         ],
1392         [ {}, {} ],
1393         [ '_month_day', '_at' ],
1394         { truncate_to => [undef, q(hour_minute)] },
1395       ],
1396    ],
1397    month_day_year_at => [
1398       [ 'REGEXP', 'REGEXP', 'REGEXP', 'REGEXP' ],
1399       [
1400         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{year}, 3 => $RE{time_min} },
1401         [ [ 1 ] ],
1402         [ $extended_checks{ordinal} ],
1403         [
1404           [
1405               1,
1406             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1407           ],
1408           [ 2 ],
1409           [ 3 ],
1410         ],
1411         [ {}, { unit => 'year' }, {} ],
1412         [ '_month_day', '_unit_date', '_time' ],
1413         { truncate_to => [undef, undef, q(minute)] },
1414       ],
1415       [
1416         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{year}, 3 => $RE{time_am} },
1417         [ [ 1 ], [ 3 ] ],
1418         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1419         [
1420           [
1421               1,
1422             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1423           ],
1424           [ 2 ],
1425           [
1426             { 3 => [ $flag{time_am} ] },
1427           ],
1428         ],
1429         [ {}, { unit => 'year' }, {} ],
1430         [ '_month_day', '_unit_date', '_at' ],
1431         { truncate_to => [undef, undef, q(hour_minute)] },
1432       ],
1433       [
1434         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{year}, 3 => $RE{time_pm} },
1435         [ [ 1 ], [ 3 ] ],
1436         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1437         [
1438           [
1439               1,
1440             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1441           ],
1442           [ 2 ],
1443           [
1444             { 3 => [ $flag{time_pm} ] },
1445           ],
1446         ],
1447         [ {}, { unit => 'year' }, {} ],
1448         [ '_month_day', '_unit_date', '_at' ],
1449         { truncate_to => [undef, undef, q(hour_minute)] },
1450       ],
1451    ],
1452    day_month_at => [
1453       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1454       [
1455         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{time_min} },
1456         [ [ 0 ] ],
1457         [ $extended_checks{ordinal} ],
1458         [
1459           [
1460               0,
1461             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1462           ],
1463           [ 2 ],
1464         ],
1465         [ {}, {} ],
1466         [ '_month_day', '_time' ],
1467         { truncate_to => [undef, q(minute)] },
1468       ],
1469       [
1470         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{time_am} },
1471         [ [ 0 ], [ 2 ] ],
1472         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1473         [
1474           [
1475               0,
1476             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1477           ],
1478           [
1479             { 2 => [ $flag{time_am} ] },
1480           ],
1481         ],
1482         [ {}, {} ],
1483         [ '_month_day', '_at' ],
1484         { truncate_to => [undef, q(hour_minute)] },
1485       ],
1486       [
1487         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{time_pm} },
1488         [ [ 0 ], [ 2 ] ],
1489         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1490         [
1491           [
1492               0,
1493             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1494           ],
1495           [
1496             { 2 => [ $flag{time_pm} ] },
1497           ],
1498         ],
1499         [ {}, {} ],
1500         [ '_month_day', '_at' ],
1501         { truncate_to => [undef, q(hour_minute)] },
1502       ],
1503    ],
1504    day_month_year_at => [
1505       [ 'REGEXP', 'REGEXP', 'REGEXP', 'REGEXP' ],
1506       [
1507         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{year}, 3 => $RE{time_min} },
1508         [ [ 0 ] ],
1509         [ $extended_checks{ordinal} ],
1510         [
1511           [
1512               0,
1513             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1514           ],
1515           [ 2 ],
1516           [ 3 ],
1517         ],
1518         [ {}, { unit => 'year' }, {} ],
1519         [ '_month_day', '_unit_date', '_time' ],
1520         { truncate_to => [undef, undef, q(minute)] },
1521       ],
1522       [
1523         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{year}, 3 => $RE{time_am} },
1524         [ [ 0 ], [ 3 ] ],
1525         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1526         [
1527           [
1528               0,
1529             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1530           ],
1531           [ 2 ],
1532           [
1533             { 3 => [ $flag{time_am} ] },
1534           ],
1535         ],
1536         [ {}, { unit => 'year' }, {} ],
1537         [ '_month_day', '_unit_date', '_at' ],
1538         { truncate_to => [undef, undef, q(hour_minute)] },
1539       ],
1540       [
1541         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{year}, 3 => $RE{time_pm} },
1542         [ [ 0 ], [ 3 ] ],
1543         [ $extended_checks{ordinal}, $extended_checks{meridiem} ],
1544         [
1545           [
1546               0,
1547             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1548           ],
1549           [ 2 ],
1550           [
1551             { 3 => [ $flag{time_pm} ] },
1552           ],
1553         ],
1554         [ {}, { unit => 'year' }, {} ],
1555         [ '_month_day', '_unit_date', '_at' ],
1556         { truncate_to => [undef, undef, q(hour_minute)] },
1557       ],
1558    ],
1559    at_month_day => [
1560       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1561       [
1562         { 0 => $RE{time_min}, 1 => $RE{month}, 2 => $RE{monthday} },
1563         [ [ 2 ] ],
1564         [ $extended_checks{ordinal} ],
1565         [
1566           [ 0 ],
1567           [
1568               2,
1569             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1570           ],
1571         ],
1572         [ {}, {} ],
1573         [ '_time', '_month_day' ],
1574         { truncate_to => [undef, q(minute)] },
1575       ],
1576       [
1577         { 0 => $RE{time_am}, 1 => $RE{month}, 2 => $RE{monthday} },
1578         [ [ 0 ], [ 2 ] ],
1579         [ $extended_checks{meridiem}, $extended_checks{ordinal} ],
1580         [
1581           [
1582             { 0 => [ $flag{time_am} ] },
1583           ],
1584           [
1585               2,
1586             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1587           ],
1588         ],
1589         [ {}, {} ],
1590         [ '_at', '_month_day' ],
1591         { truncate_to => [undef, q(hour_minute)] },
1592       ],
1593       [
1594         { 0 => $RE{time_pm}, 1 => $RE{month}, 2 => $RE{monthday} },
1595         [ [ 0 ], [ 2 ] ],
1596         [ $extended_checks{meridiem}, $extended_checks{ordinal} ],
1597         [
1598           [
1599             { 0 => [ $flag{time_pm} ] },
1600           ],
1601           [
1602               2,
1603             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1604           ],
1605         ],
1606         [ {}, {} ],
1607         [ '_at', '_month_day' ],
1608         { truncate_to => [undef, q(hour_minute)] },
1609       ],
1610    ],
1611    day_month_year_ago => [
1612      [ 'REGEXP', 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
1613      [
1614        { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{number}, 3 => qr/^(years?)$/i, 4 => 'ago' },
1615        [ [ 0 ], [ 2, 3 ] ],
1616        [ $extended_checks{ordinal}, $extended_checks{suffix} ],
1617        [
1618          [
1619              0,
1620            { 1 => [ $flag{month_name}, $flag{month_num} ] },
1621          ],
1622          [ 2 ],
1623        ],
1624        [ {}, { unit => 'year' } ],
1625        [ '_month_day', '_ago_variant' ],
1626        { truncate_to => [undef, q(day)] },
1627      ],
1628    ],
1629    day_month_variant_year => [
1630      [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
1631      [
1632        { 0 => $RE{monthday}, 1 => $RE{month}, 2 => qr/^(next)$/i, 3 => 'year' },
1633        [ [ 0 ] ],
1634        [ $extended_checks{ordinal} ],
1635        [
1636          [
1637              0,
1638            { 1 => [ $flag{month_name}, $flag{month_num} ] },
1639          ],
1640          [
1641            { 2 => [ $flag{last_this_next} ] },
1642          ],
1643        ],
1644        [ {}, { unit => 'year' } ],
1645        [ '_month_day', '_unit_variant' ],
1646        { truncate_to => [undef, q(day)] },
1647      ],
1648      [
1649        { 0 => $RE{monthday}, 1 => $RE{month}, 2 => qr/^(this)$/i, 3 => 'year' },
1650        [ [ 0 ] ],
1651        [ $extended_checks{ordinal} ],
1652        [
1653          [
1654              0,
1655            { 1 => [ $flag{month_name}, $flag{month_num} ] },
1656          ],
1657          [
1658            { 2 => [ $flag{last_this_next} ] },
1659          ],
1660        ],
1661        [ {}, { unit => 'year' } ],
1662        [ '_month_day', '_unit_variant' ],
1663        { truncate_to => [undef, q(day)] },
1664      ],
1665      [
1666        { 0 => $RE{monthday}, 1 => $RE{month}, 2 => qr/^(last)$/i, 3 => 'year' },
1667        [ [ 0 ] ],
1668        [ $extended_checks{ordinal} ],
1669        [
1670          [
1671              0,
1672            { 1 => [ $flag{month_name}, $flag{month_num} ] },
1673          ],
1674          [
1675            { 2 => [ $flag{last_this_next} ] },
1676          ]
1677        ],
1678        [ {}, { unit => 'year' } ],
1679        [ '_month_day', '_unit_variant' ],
1680        { truncate_to => [undef, q(day)] },
1681      ],
1682    ],
1683    month_day_year => [
1684       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1685       [
1686         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{year} },
1687         [ [ 1 ] ],
1688         [ $extended_checks{ordinal} ],
1689         [
1690           [
1691               1,
1692             { 0 => [ $flag{month_name}, $flag{month_num} ] },
1693           ],
1694           [ 2 ],
1695         ],
1696         [ {}, { unit => 'year' } ],
1697         [ '_month_day', '_unit_date' ],
1698         { truncate_to => [undef, q(day)] },
1699       ],
1700    ],
1701    year_month_day => [
1702       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
1703       [
1704         { 0 => $RE{year}, 1 => $RE{month}, 2 => $RE{monthday} },
1705         [ [ 2 ] ],
1706         [ $extended_checks{ordinal} ],
1707         [
1708           [ 0 ],
1709           [
1710               2,
1711             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1712           ],
1713         ],
1714         [ { unit => 'year' }, {} ],
1715         [ '_unit_date', '_month_day' ],
1716         { truncate_to => [undef, q(day)] },
1717       ],
1718    ],
1719    week_variant => [
1720       [ 'REGEXP', 'SCALAR' ],
1721       [
1722         { 0 => qr/^(next)$/i, 1 => 'week' },
1723         [],
1724         [],
1725         [
1726           [
1727             { 0 => [ $flag{last_this_next} ] },
1728           ],
1729         ],
1730         [ { unit => 'week' } ],
1731         [ '_unit_variant' ],
1732         { truncate_to => [q(day)] },
1733       ],
1734       [
1735         { 0 => qr/^(this)$/i, 1 => 'week' },
1736         [],
1737         [],
1738         [
1739           [
1740             { 0 => [ $flag{last_this_next} ] },
1741           ],
1742         ],
1743         [ { unit => 'week' } ],
1744         [ '_unit_variant' ],
1745         { truncate_to => [q(day)] },
1746       ],
1747       [
1748         { 0 => qr/^(last)$/i, 1 => 'week' },
1749         [],
1750         [],
1751         [
1752           [
1753             { 0 => [ $flag{last_this_next} ] },
1754           ]
1755         ],
1756         [ { unit => 'week' } ],
1757         [ '_unit_variant' ],
1758         { truncate_to => [q(day)] },
1759       ]
1760    ],
1761    weekday => [
1762       [ 'REGEXP' ],
1763       [
1764         { 0 => $RE{weekday} },
1765         [],
1766         [],
1767         [
1768           [
1769             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1770           ]
1771         ],
1772         [ {} ],
1773         [ '_weekday' ],
1774         {
1775           advance_future => true,
1776           truncate_to    => [q(day)],
1777         },
1778       ],
1779    ],
1780    weekday_variant => [
1781       [ 'REGEXP', 'REGEXP' ],
1782       [
1783         { 0 => qr/^(next)$/i, 1 => $RE{weekday} },
1784         [],
1785         [],
1786         [
1787           [
1788             { 0 => [ $flag{last_this_next} ] },
1789             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1790           ],
1791         ],
1792         [ {} ],
1793         [ '_count_day_variant_week' ],
1794         { truncate_to => [q(day)] },
1795       ],
1796       [
1797         { 0 => qr/^(this)$/i, 1 => $RE{weekday} },
1798         [],
1799         [],
1800         [
1801           [
1802             { 0 => [ $flag{last_this_next} ] },
1803             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1804           ],
1805         ],
1806         [ {} ],
1807         [ '_count_day_variant_week' ],
1808         { truncate_to => [q(day)] },
1809       ],
1810       [
1811         { 0 => qr/^(last)$/i, 1 => $RE{weekday} },
1812         [],
1813         [],
1814         [
1815           [
1816             { 0 => [ $flag{last_this_next} ] },
1817             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
1818           ],
1819         ],
1820         [ {} ],
1821         [ '_count_day_variant_week' ],
1822         { truncate_to => [q(day)] },
1823       ],
1824    ],
1825    year_variant => [
1826       [ 'REGEXP', 'SCALAR' ],
1827       [
1828         { 0 => qr/^(last)$/i, 1 => 'year' },
1829         [],
1830         [],
1831         [
1832           [
1833             { 0 => [ $flag{last_this_next} ] },
1834           ],
1835         ],
1836         [ { unit => 'year' } ],
1837         [ '_unit_variant' ],
1838         { truncate_to => [q(year)] },
1839       ],
1840       [
1841         { 0 => qr/^(this)$/i, 1 => 'year' },
1842         [],
1843         [],
1844         [
1845           [
1846             { 0 => [ $flag{last_this_next} ] },
1847           ],
1848         ],
1849         [ { unit => 'year' } ],
1850         [ '_unit_variant' ],
1851         { truncate_to => [q(year)] },
1852       ],
1853       [
1854         { 0 => qr/^(next)$/i, 1 => 'year' },
1855         [],
1856         [],
1857         [
1858           [
1859             { 0 => [ $flag{last_this_next} ] },
1860           ],
1861         ],
1862         [ { unit => 'year' } ],
1863         [ '_unit_variant' ],
1864         { truncate_to => [q(year)] }
1865       ],
1866    ],
1867    month_variant => [
1868       [ 'REGEXP', 'REGEXP' ],
1869       [
1870         { 0 => qr/^(last)$/i, 1 => $RE{month} },
1871         [],
1872         [],
1873         [
1874           [
1875             { 0 => [ $flag{last_this_next} ] },
1876             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1877           ],
1878         ],
1879         [ {} ],
1880         [ '_month_variant' ],
1881         { truncate_to => [q(month)] },
1882       ],
1883       [
1884         { 0 => qr/^(this)$/i, 1 => $RE{month} },
1885         [],
1886         [],
1887         [
1888           [
1889             { 0 => [ $flag{last_this_next} ] },
1890             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1891           ]
1892         ],
1893         [ {} ],
1894         [ '_month_variant' ],
1895         { truncate_to => [q(month)] },
1896       ],
1897       [
1898         { 0 => qr/^(next)$/i, 1 => $RE{month} },
1899         [],
1900         [],
1901         [
1902           [
1903             { 0 => [ $flag{last_this_next} ] },
1904             { 1 => [ $flag{month_name}, $flag{month_num} ] },
1905           ],
1906         ],
1907         [ {} ],
1908         [ '_month_variant' ],
1909         { truncate_to => [q(month)] },
1910       ],
1911    ],
1912    time_literal_variant => [
1913       [ 'REGEXP', 'SCALAR' ],
1914       [
1915         { 0 => qr/^(last)$/i, 1 => 'second' },
1916         [],
1917         [],
1918         [
1919           [
1920             { 0 => [ $flag{last_this_next} ] },
1921           ],
1922         ],
1923         [ { unit => 'second' } ],
1924         [ '_unit_variant' ],
1925         {},
1926       ],
1927       [
1928         { 0 => qr/^(this)$/i, 1 => 'second' },
1929         [],
1930         [],
1931         [
1932           [
1933             { 0 => [ $flag{last_this_next} ] },
1934           ],
1935         ],
1936         [ { unit => 'second' } ],
1937         [ '_unit_variant' ],
1938         {},
1939       ],
1940       [
1941         { 0 => qr/^(next)$/i, 1 => 'second' },
1942         [],
1943         [],
1944         [
1945           [
1946             { 0 => [ $flag{last_this_next} ] },
1947           ],
1948         ],
1949         [ { unit => 'second' } ],
1950         [ '_unit_variant' ],
1951         {},
1952       ],
1953       [
1954         { 0 => qr/^(last)$/i, 1 => 'minute' },
1955         [],
1956         [],
1957         [
1958           [
1959             { 0 => [ $flag{last_this_next} ] },
1960           ],
1961         ],
1962         [ { unit => 'minute' } ],
1963         [ '_unit_variant' ],
1964         { truncate_to => [q(minute)] },
1965       ],
1966       [
1967         { 0 => qr/^(this)$/i, 1 => 'minute' },
1968         [],
1969         [],
1970         [
1971           [
1972             { 0 => [ $flag{last_this_next} ] },
1973           ],
1974         ],
1975         [ { unit => 'minute' } ],
1976         [ '_unit_variant' ],
1977         { truncate_to => [q(minute)] },
1978       ],
1979       [
1980         { 0 => qr/^(next)$/i, 1 => 'minute' },
1981         [],
1982         [],
1983         [
1984           [
1985             { 0 => [ $flag{last_this_next} ] },
1986           ],
1987         ],
1988         [ { unit => 'minute' } ],
1989         [ '_unit_variant' ],
1990         { truncate_to => [q(minute)] },
1991       ],
1992       [
1993         { 0 => qr/^(last)$/i, 1 => 'hour' },
1994         [],
1995         [],
1996         [
1997           [
1998             { 0 => [ $flag{last_this_next} ] },
1999           ],
2000         ],
2001         [ { unit => 'hour' } ],
2002         [ '_unit_variant' ],
2003         { truncate_to => [q(hour)] },
2004       ],
2005       [
2006         { 0 => qr/^(this)$/i, 1 => 'hour' },
2007         [],
2008         [],
2009         [
2010           [
2011             { 0 => [ $flag{last_this_next} ] },
2012           ],
2013         ],
2014         [ { unit => 'hour' } ],
2015         [ '_unit_variant' ],
2016         { truncate_to => [q(hour)] },
2017       ],
2018       [
2019         { 0 => qr/^(next)$/i, 1 => 'hour' },
2020         [],
2021         [],
2022         [
2023           [
2024             { 0 => [ $flag{last_this_next} ] },
2025           ],
2026         ],
2027         [ { unit => 'hour' } ],
2028         [ '_unit_variant' ],
2029         { truncate_to => [q(hour)] },
2030       ],
2031    ],
2032    date_literal_variant => [
2033       [ 'REGEXP', 'SCALAR' ],
2034       [
2035         { 0 => qr/^(last)$/i, 1 => 'day' },
2036         [],
2037         [],
2038         [
2039           [
2040             { 0 => [ $flag{last_this_next} ] },
2041           ],
2042         ],
2043         [ { unit => 'day' } ],
2044         [ '_unit_variant' ],
2045         { truncate_to => [q(day)] },
2046       ],
2047       [
2048         { 0 => qr/^(this)$/i, 1 => 'day' },
2049         [],
2050         [],
2051         [
2052           [
2053             { 0 => [ $flag{last_this_next} ] },
2054           ],
2055         ],
2056         [ { unit => 'day' } ],
2057         [ '_unit_variant' ],
2058         { truncate_to => [q(day)] },
2059       ],
2060       [
2061         { 0 => qr/^(next)$/i, 1 => 'day' },
2062         [],
2063         [],
2064         [
2065           [
2066             { 0 => [ $flag{last_this_next} ] },
2067           ],
2068         ],
2069         [ { unit => 'day' } ],
2070         [ '_unit_variant' ],
2071         { truncate_to => [q(day)] },
2072       ],
2073       [
2074         { 0 => qr/^(last)$/i, 1 => 'month' },
2075         [],
2076         [],
2077         [
2078           [
2079             { 0 => [ $flag{last_this_next} ] },
2080           ],
2081         ],
2082         [ { unit => 'month' } ],
2083         [ '_unit_variant' ],
2084         { truncate_to => [q(month)] },
2085       ],
2086       [
2087         { 0 => qr/^(this)$/i, 1 => 'month' },
2088         [],
2089         [],
2090         [
2091           [
2092             { 0 => [ $flag{last_this_next} ] },
2093           ],
2094         ],
2095         [ { unit => 'month' } ],
2096         [ '_unit_variant' ],
2097         { truncate_to => [q(month)] },
2098       ],
2099       [
2100         { 0 => qr/^(next)$/i, 1 => 'month' },
2101         [],
2102         [],
2103         [
2104           [
2105             { 0 => [ $flag{last_this_next} ] },
2106           ],
2107         ],
2108         [ { unit => 'month' } ],
2109         [ '_unit_variant' ],
2110         { truncate_to => [q(month)] },
2111       ],
2112    ],
2113    at => [
2114       [ 'REGEXP' ],
2115       [
2116         { 0 => $RE{time_am} },
2117         [ [ 0 ] ],
2118         [ $extended_checks{meridiem} ],
2119         [
2120           [
2121             { 0 => [ $flag{time_am} ] },
2122           ],
2123         ],
2124         [ {} ],
2125         [ '_at' ],
2126         {
2127           advance_future => true,
2128           truncate_to    => [q(hour_minute)],
2129         },
2130       ],
2131       [
2132         { 0 => $RE{time_pm} },
2133         [ [ 0 ] ],
2134         [ $extended_checks{meridiem} ],
2135         [
2136           [
2137             { 0 => [ $flag{time_pm} ] },
2138           ],
2139         ],
2140         [ {} ],
2141         [ '_at' ],
2142         {
2143           advance_future => true,
2144           truncate_to    => [q(hour_minute)],
2145         },
2146       ],
2147    ],
2148    weekday_time => [
2149       [ 'REGEXP', 'REGEXP' ],
2150       [
2151         { 0 => $RE{weekday}, 1 => $RE{time} },
2152         [],
2153         [],
2154         [
2155           [
2156             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2157           ],
2158           [ 1 ],
2159         ],
2160         [ {}, {} ],
2161         [ '_weekday', '_time' ],
2162         {
2163           advance_future => true,
2164           truncate_to    => [undef, q(hour_minute)],
2165         },
2166       ],
2167       [
2168         { 0 => $RE{weekday}, 1 => $RE{time_am} },
2169         [ [ 1 ] ],
2170         [ $extended_checks{meridiem} ],
2171         [
2172           [
2173             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2174           ],
2175           [
2176             { 1 => [ $flag{time_am} ] },
2177           ],
2178         ],
2179         [ {}, {} ],
2180         [ '_weekday', '_at' ],
2181         {
2182           advance_future => true,
2183           truncate_to    => [undef, q(hour_minute)],
2184         },
2185       ],
2186       [
2187         { 0 => $RE{weekday}, 1 => $RE{time_pm} },
2188         [ [ 1 ] ],
2189         [ $extended_checks{meridiem} ],
2190         [
2191           [
2192             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2193           ],
2194           [
2195             { 1 => [ $flag{time_pm} ] },
2196           ],
2197         ],
2198         [ {}, {} ],
2199         [ '_weekday', '_at' ],
2200         {
2201           advance_future => true,
2202           truncate_to    => [undef, q(hour_minute)],
2203         },
2204       ],
2205       [
2206         { 0 => $RE{time}, 1 => $RE{weekday} },
2207         [],
2208         [],
2209         [
2210           [ 0 ],
2211           [
2212             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2213           ],
2214         ],
2215         [ {}, {} ],
2216         [ '_time', '_weekday' ],
2217         {
2218           advance_future => true,
2219           truncate_to    => [undef, q(hour_minute)],
2220         },
2221       ],
2222       [
2223         { 0 => $RE{time_am}, 1 => $RE{weekday} },
2224         [ [ 0 ] ],
2225         [ $extended_checks{meridiem} ],
2226         [
2227           [
2228             { 0 => [ $flag{time_am} ] },
2229           ],
2230           [
2231             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2232           ],
2233         ],
2234         [ {}, {} ],
2235         [ '_at', '_weekday' ],
2236         {
2237           advance_future => true,
2238           truncate_to    => [undef, q(hour_minute)],
2239         },
2240       ],
2241       [
2242         { 0 => $RE{time_pm}, 1 => $RE{weekday} },
2243         [ [ 0 ] ],
2244         [ $extended_checks{meridiem} ],
2245         [
2246           [
2247             { 0 => [ $flag{time_pm} ] },
2248           ],
2249           [
2250             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2251           ],
2252         ],
2253         [ {}, {} ],
2254         [ '_at', '_weekday' ],
2255         {
2256           advance_future => true,
2257           truncate_to    => [undef, q(hour_minute)],
2258         },
2259       ],
2260    ],
2261    time => [
2262       [ 'REGEXP' ],
2263       [
2264         { 0 => $RE{time} },
2265         [],
2266         [],
2267         [ [ 0 ] ],
2268         [ {} ],
2269         [ '_time' ],
2270         {
2271           advance_future => true,
2272           truncate_to    => [q(hour_minute)],
2273         },
2274       ],
2275    ],
2276    month_year => [
2277       [ 'REGEXP', 'REGEXP' ],
2278       [
2279         { 0 => $RE{month}, 1 => $RE{year} },
2280         [],
2281         [],
2282         [
2283           [
2284             { 0 => [ $flag{month_name}, $flag{month_num} ] },
2285           ],
2286           [ 1 ],
2287         ],
2288         [ { unit => 'month' }, { unit => 'year' } ],
2289         [ '_unit_date', '_unit_date' ],
2290         { truncate_to => [undef, q(month)] },
2291       ],
2292    ],
2293    year => [
2294       [ 'REGEXP' ],
2295       [
2296         { 0 => $RE{year} },
2297         [],
2298         [],
2299         [ [ 0 ] ],
2300         [ { unit => 'year' } ],
2301         [ '_unit_date' ],
2302         { truncate_to => [q(year)] },
2303       ],
2304    ],
2305    count_weekday => [
2306       [ 'REGEXP', 'REGEXP' ],
2307       [
2308         { 0 => $RE{day}, 1 => $RE{weekday} },
2309         [ [ 0 ] ],
2310         [ $extended_checks{ordinal} ],
2311         [
2312           [
2313               0,
2314             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2315           ],
2316         ],
2317         [ {} ],
2318         [ '_count_weekday' ],
2319         { truncate_to => [q(day)] },
2320       ],
2321    ],
2322    count_yearday => [
2323       [ 'REGEXP', 'SCALAR' ],
2324       [
2325         { 0 => $RE{day}, 1 => 'day' },
2326         [ [ 0 ] ],
2327         [ $extended_checks{ordinal} ],
2328         [
2329           [
2330             0,
2331             { VALUE => 0 }
2332           ],
2333         ],
2334         [ {} ],
2335         [ '_count_yearday_variant_year' ],
2336         { truncate_to => [q(day)] },
2337       ],
2338    ],
2339    count_yearday_variant_year => [
2340        [ 'REGEXP', 'SCALAR', 'REGEXP', 'SCALAR' ],
2341        [
2342          { 0 => $RE{day}, 1 => 'day', 2 => qr/^(next)$/i, 3 => 'year' },
2343          [ [ 0 ] ],
2344          [ $extended_checks{ordinal} ],
2345          [
2346            [
2347                0,
2348              { 2 => [ $flag{last_this_next} ] },
2349            ],
2350          ],
2351          [ {} ],
2352          [ '_count_yearday_variant_year' ],
2353          { truncate_to => [q(day)] },
2354        ],
2355        [
2356          { 0 => $RE{day}, 1 => 'day', 2 => qr/^(this)$/i, 3 => 'year' },
2357          [ [ 0 ] ],
2358          [ $extended_checks{ordinal} ],
2359          [
2360            [
2361                0,
2362              { 2 => [ $flag{last_this_next} ] },
2363            ],
2364          ],
2365          [ {} ],
2366          [ '_count_yearday_variant_year' ],
2367          { truncate_to => [q(day)] },
2368        ],
2369        [
2370          { 0 => $RE{day}, 1 => 'day', 2 => qr/^(last)$/i, 3 => 'year' },
2371          [ [ 0 ] ],
2372          [ $extended_checks{ordinal} ],
2373          [
2374            [
2375                0,
2376              { 2 => [ $flag{last_this_next} ] },
2377            ],
2378          ],
2379          [ {} ],
2380          [ '_count_yearday_variant_year' ],
2381          { truncate_to => [q(day)] },
2382        ],
2383    ],
2384    daytime_in_the_variant => [
2385       [ 'REGEXP', 'SCALAR', 'SCALAR', 'SCALAR' ],
2386       [
2387         { 0 => $RE{number}, 1 => 'in', 2 => 'the', 3 => 'morning' },
2388         [],
2389         [],
2390         [ [ 0 ] ],
2391         [ {} ],
2392         [ '_daytime' ],
2393         { truncate_to => [q(hour)] },
2394       ],
2395       [
2396         { 0 => $RE{number}, 1 => 'in', 2 => 'the', 3 => 'afternoon' },
2397         [],
2398         [],
2399         [ [ 0 ] ],
2400         [ { hours => 12 } ],
2401         [ '_daytime' ],
2402         { truncate_to => [q(hour)] },
2403       ],
2404       [
2405         { 0 => $RE{number}, 1 => 'in', 2 => 'the', 3 => 'evening' },
2406         [],
2407         [],
2408         [ [ 0 ] ],
2409         [ { hours => 12 } ],
2410         [ '_daytime' ],
2411         { truncate_to => [q(hour)] },
2412       ],
2413    ],
2414    ago => [
2415       [ 'REGEXP', 'REGEXP', 'SCALAR' ],
2416       [
2417         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => 'ago' },
2418         [ [ 0, 1 ] ],
2419         [ $extended_checks{suffix} ],
2420         [ [ 0 ] ],
2421         [ { unit => 'second' } ],
2422         [ '_ago_variant' ],
2423         {},
2424       ],
2425       [
2426         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => 'ago' },
2427         [ [ 0, 1 ] ],
2428         [ $extended_checks{suffix} ],
2429         [ [ 0 ] ],
2430         [ { unit => 'minute' } ],
2431         [ '_ago_variant' ],
2432         {},
2433       ],
2434       [
2435         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => 'ago' },
2436         [ [ 0, 1 ] ],
2437         [ $extended_checks{suffix} ],
2438         [ [ 0 ] ],
2439         [ { unit => 'hour' } ],
2440         [ '_ago_variant' ],
2441         {},
2442       ],
2443       [
2444         { 0 => $RE{number}, 1 => qr/^(days?)$/i, 2 => 'ago' },
2445         [ [ 0, 1 ] ],
2446         [ $extended_checks{suffix} ],
2447         [ [ 0 ] ],
2448         [ { unit => 'day' } ],
2449         [ '_ago_variant' ],
2450         {},
2451       ],
2452       [
2453         { 0 => $RE{number}, 1 => qr/^(weeks?)$/i, 2 => 'ago' },
2454         [ [ 0, 1 ] ],
2455         [ $extended_checks{suffix} ],
2456         [ [ 0 ] ],
2457         [ { unit => 'week' } ],
2458         [ '_ago_variant' ],
2459         {},
2460       ],
2461       [
2462         { 0 => $RE{number}, 1 => qr/^(months?)$/i, 2 => 'ago' },
2463         [ [ 0, 1 ] ],
2464         [ $extended_checks{suffix} ],
2465         [ [ 0 ] ],
2466         [ { unit => 'month' } ],
2467         [ '_ago_variant' ],
2468         {},
2469       ],
2470       [
2471         { 0 => $RE{number}, 1 => qr/^(years?)$/i, 2 => 'ago' },
2472         [ [ 0, 1 ] ],
2473         [ $extended_checks{suffix} ],
2474         [ [ 0 ] ],
2475         [ { unit => 'year' } ],
2476         [ '_ago_variant' ],
2477         {},
2478       ],
2479    ],
2480    ago_tomorrow => [
2481       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
2482       [
2483         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(seconds?)$/i, 3 => 'ago' },
2484         [ [ 1, 2 ] ],
2485         [ $extended_checks{suffix} ],
2486         [
2487           [
2488             { 0 => [ $flag{yes_today_tom} ] },
2489           ],
2490           [ 1 ],
2491         ],
2492         [ { unit => 'day' }, { unit => 'second' } ],
2493         [ '_unit_variant', '_ago_variant' ],
2494         {},
2495       ],
2496       [
2497         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(minutes?)$/i, 3 => 'ago' },
2498         [ [ 1, 2 ] ],
2499         [ $extended_checks{suffix} ],
2500         [
2501           [
2502             { 0 => [ $flag{yes_today_tom} ] },
2503           ],
2504           [ 1 ],
2505         ],
2506         [ { unit => 'day' }, { unit => 'minute' } ],
2507         [ '_unit_variant', '_ago_variant' ],
2508         {},
2509       ],
2510       [
2511         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(hours?)$/i, 3 => 'ago' },
2512         [ [ 1, 2 ] ],
2513         [ $extended_checks{suffix} ],
2514         [
2515           [
2516             { 0 => [ $flag{yes_today_tom} ] },
2517           ],
2518           [ 1 ],
2519         ],
2520         [ { unit => 'day' }, { unit => 'hour' } ],
2521         [ '_unit_variant', '_ago_variant' ],
2522         {},
2523       ],
2524       [
2525         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(days?)$/i, 3 => 'ago' },
2526         [ [ 1, 2 ] ],
2527         [ $extended_checks{suffix} ],
2528         [
2529           [
2530             { 0 => [ $flag{yes_today_tom} ] },
2531           ],
2532           [ 1 ],
2533         ],
2534         [ { unit => 'day' }, { unit => 'day' } ],
2535         [ '_unit_variant', '_ago_variant' ],
2536         { truncate_to => [undef, q(day)] },
2537       ],
2538       [
2539         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(weeks?)$/i, 3 => 'ago' },
2540         [ [ 1, 2 ] ],
2541         [ $extended_checks{suffix} ],
2542         [
2543           [
2544             { 0 => [ $flag{yes_today_tom} ] },
2545           ],
2546           [ 1 ],
2547         ],
2548         [ { unit => 'day' }, { unit => 'week' } ],
2549         [ '_unit_variant', '_ago_variant' ],
2550         { truncate_to => [undef, q(day)] },
2551       ],
2552       [
2553         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(months?)$/i, 3 => 'ago' },
2554         [ [ 1, 2 ] ],
2555         [ $extended_checks{suffix} ],
2556         [
2557           [
2558             { 0 => [ $flag{yes_today_tom} ] },
2559           ],
2560           [ 1 ],
2561         ],
2562         [ { unit => 'day' }, { unit => 'month' } ],
2563         [ '_unit_variant', '_ago_variant' ],
2564         { truncate_to => [undef, q(day)] },
2565       ],
2566       [
2567         { 0 => qr/^(tomorrow)$/i, 1 => $RE{number}, 2 => qr/^(years?)$/i, 3 => 'ago' },
2568         [ [ 1, 2 ] ],
2569         [ $extended_checks{suffix} ],
2570         [
2571           [
2572             { 0 => [ $flag{yes_today_tom} ] },
2573           ],
2574           [ 1 ],
2575         ],
2576         [ { unit => 'day' }, { unit => 'year' } ],
2577         [ '_unit_variant', '_ago_variant' ],
2578         { truncate_to => [undef, q(day)] },
2579       ],
2580    ],
2581    ago_today => [
2582       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
2583       [
2584         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(seconds?)$/i, 3 => 'ago' },
2585         [ [ 1, 2 ] ],
2586         [ $extended_checks{suffix} ],
2587         [
2588           [
2589             { 0 => [ $flag{yes_today_tom} ] },
2590           ],
2591           [ 1 ],
2592         ],
2593         [ { unit => 'day' }, { unit => 'second' } ],
2594         [ '_unit_variant', '_ago_variant' ],
2595         {},
2596       ],
2597       [
2598         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(minutes?)$/i, 3 => 'ago' },
2599         [ [ 1, 2 ] ],
2600         [ $extended_checks{suffix} ],
2601         [
2602           [
2603             { 0 => [ $flag{yes_today_tom} ] },
2604           ],
2605           [ 1 ],
2606         ],
2607         [ { unit => 'day' }, { unit => 'minute' } ],
2608         [ '_unit_variant', '_ago_variant' ],
2609         {},
2610       ],
2611       [
2612         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(hours?)$/i, 3 => 'ago' },
2613         [ [ 1, 2 ] ],
2614         [ $extended_checks{suffix} ],
2615         [
2616           [
2617             { 0 => [ $flag{yes_today_tom} ] },
2618           ],
2619           [ 1 ],
2620         ],
2621         [ { unit => 'day' }, { unit => 'hour' } ],
2622         [ '_unit_variant', '_ago_variant' ],
2623         {},
2624       ],
2625       [
2626         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(days?)$/i, 3 => 'ago' },
2627         [ [ 1, 2 ] ],
2628         [ $extended_checks{suffix} ],
2629         [
2630           [
2631             { 0 => [ $flag{yes_today_tom} ] },
2632           ],
2633           [ 1 ],
2634         ],
2635         [ { unit => 'day' }, { unit => 'day' } ],
2636         [ '_unit_variant', '_ago_variant' ],
2637         { truncate_to => [undef, q(day)] },
2638       ],
2639       [
2640         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(weeks?)$/i, 3 => 'ago' },
2641         [ [ 1, 2 ] ],
2642         [ $extended_checks{suffix} ],
2643         [
2644           [
2645             { 0 => [ $flag{yes_today_tom} ] },
2646           ],
2647           [ 1 ],
2648         ],
2649         [ { unit => 'day' }, { unit => 'week' } ],
2650         [ '_unit_variant', '_ago_variant' ],
2651         { truncate_to => [undef, q(day)] },
2652       ],
2653       [
2654         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(months?)$/i, 3 => 'ago' },
2655         [ [ 1, 2 ] ],
2656         [ $extended_checks{suffix} ],
2657         [
2658           [
2659             { 0 => [ $flag{yes_today_tom} ] },
2660           ],
2661           [ 1 ],
2662         ],
2663         [ { unit => 'day' }, { unit => 'month' } ],
2664         [ '_unit_variant', '_ago_variant' ],
2665         { truncate_to => [undef, q(day)] },
2666       ],
2667       [
2668         { 0 => qr/^(today)$/i, 1 => $RE{number}, 2 => qr/^(years?)$/i, 3 => 'ago' },
2669         [ [ 1, 2 ] ],
2670         [ $extended_checks{suffix} ],
2671         [
2672           [
2673             { 0 => [ $flag{yes_today_tom} ] },
2674           ],
2675           [ 1 ],
2676         ],
2677         [ { unit => 'day' }, { unit => 'year' } ],
2678         [ '_unit_variant', '_ago_variant' ],
2679         { truncate_to => [undef, q(day)] },
2680       ],
2681    ],
2682    ago_yesterday => [
2683       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
2684       [
2685         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(seconds?)$/i, 3 => 'ago' },
2686         [ [ 1, 2 ] ],
2687         [ $extended_checks{suffix} ],
2688         [
2689           [
2690             { 0 => [ $flag{yes_today_tom} ] },
2691           ],
2692           [ 1 ],
2693         ],
2694         [ { unit => 'day' }, { unit => 'second' } ],
2695         [ '_unit_variant', '_ago_variant' ],
2696         {},
2697       ],
2698       [
2699         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(minutes?)$/i, 3 => 'ago' },
2700         [ [ 1, 2 ] ],
2701         [ $extended_checks{suffix} ],
2702         [
2703           [
2704             { 0 => [ $flag{yes_today_tom} ] },
2705           ],
2706           [ 1 ],
2707         ],
2708         [ { unit => 'day' }, { unit => 'minute' } ],
2709         [ '_unit_variant', '_ago_variant' ],
2710         {},
2711       ],
2712       [
2713         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(hours?)$/i, 3 => 'ago' },
2714         [ [ 1, 2 ] ],
2715         [ $extended_checks{suffix} ],
2716         [
2717           [
2718             { 0 => [ $flag{yes_today_tom} ] },
2719           ],
2720           [ 1 ],
2721         ],
2722         [ { unit => 'day' }, { unit => 'hour' } ],
2723         [ '_unit_variant', '_ago_variant' ],
2724         {},
2725       ],
2726       [
2727         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(days?)$/i, 3 => 'ago' },
2728         [ [ 1, 2 ] ],
2729         [ $extended_checks{suffix} ],
2730         [
2731           [
2732             { 0 => [ $flag{yes_today_tom} ] },
2733           ],
2734           [ 1 ],
2735         ],
2736         [ { unit => 'day' }, { unit => 'day' } ],
2737         [ '_unit_variant', '_ago_variant' ],
2738         { truncate_to => [undef, q(day)] },
2739       ],
2740       [
2741         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(weeks?)$/i, 3 => 'ago' },
2742         [ [ 1, 2 ] ],
2743         [ $extended_checks{suffix} ],
2744         [
2745           [
2746             { 0 => [ $flag{yes_today_tom} ] },
2747           ],
2748           [ 1 ],
2749         ],
2750         [ { unit => 'day' }, { unit => 'week' } ],
2751         [ '_unit_variant', '_ago_variant' ],
2752         { truncate_to => [undef, q(day)] },
2753       ],
2754       [
2755         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(months?)$/i, 3 => 'ago' },
2756         [ [ 1, 2 ] ],
2757         [ $extended_checks{suffix} ],
2758         [
2759           [
2760             { 0 => [ $flag{yes_today_tom} ] },
2761           ],
2762           [ 1 ],
2763         ],
2764         [ { unit => 'day' }, { unit => 'month' } ],
2765         [ '_unit_variant', '_ago_variant' ],
2766         { truncate_to => [undef, q(day)] },
2767       ],
2768       [
2769         { 0 => qr/^(yesterday)$/i, 1 => $RE{number}, 2 => qr/^(years?)$/i, 3 => 'ago' },
2770         [ [ 1, 2 ] ],
2771         [ $extended_checks{suffix} ],
2772         [
2773           [
2774             { 0 => [ $flag{yes_today_tom} ] },
2775           ],
2776           [ 1 ],
2777         ],
2778         [ { unit => 'day' }, { unit => 'year' } ],
2779         [ '_unit_variant', '_ago_variant' ],
2780         { truncate_to => [undef, q(day)] },
2781       ],
2782    ],
2783    weekday_ago_at_time => [
2784       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR', 'REGEXP' ],
2785       [
2786         { 0 => $RE{weekday}, 1 => $RE{number}, 2 => qr/^(months?)$/i, 3 => 'ago', 4 => $RE{time_min} },
2787         [ [ 1, 2 ] ],
2788         [ $extended_checks{suffix} ],
2789         [
2790           [ 1 ],
2791           [
2792             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2793           ],
2794           [ 4 ],
2795         ],
2796         [ { unit => 'month' }, {}, {} ],
2797         [ '_ago_variant', '_weekday', '_time' ],
2798         { truncate_to => [undef, undef, q(minute)] },
2799       ],
2800       [
2801         { 0 => $RE{weekday}, 1 => $RE{number}, 2 => qr/^(months?)$/i, 3 => 'ago', 4 => $RE{time_am} },
2802         [ [ 1, 2 ], [ 4 ] ],
2803         [ $extended_checks{suffix}, $extended_checks{meridiem} ],
2804         [
2805           [ 1 ],
2806           [
2807             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2808           ],
2809           [
2810             { 4 => [ $flag{time_am} ] },
2811           ],
2812         ],
2813         [ { unit => 'month' }, {}, {} ],
2814         [ '_ago_variant', '_weekday', '_at' ],
2815         { truncate_to => [undef, undef, q(hour_minute)] },
2816       ],
2817       [
2818         { 0 => $RE{weekday}, 1 => $RE{number}, 2 => qr/^(months?)$/i, 3 => 'ago', 4 => $RE{time_pm} },
2819         [ [ 1, 2 ], [ 4 ] ],
2820         [ $extended_checks{suffix}, $extended_checks{meridiem} ],
2821         [
2822           [ 1 ],
2823           [
2824             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
2825           ],
2826           [
2827             { 4 => [ $flag{time_pm} ] },
2828           ],
2829         ],
2830         [ { unit => 'month' }, {}, {} ],
2831         [ '_ago_variant', '_weekday', '_at' ],
2832         { truncate_to => [undef, undef, q(hour_minute)] },
2833       ],
2834    ],
2835    now_variant_before => [
2836       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
2837       [
2838         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(before)$/i, 3 => 'now' },
2839         [ [ 0, 1 ] ],
2840         [ $extended_checks{suffix} ],
2841         [
2842           [
2843               0,
2844             { 2 => [ $flag{before_after_from} ] },
2845           ],
2846         ],
2847         [ { unit => 'second' } ],
2848         [ '_now_variant' ],
2849         {},
2850       ],
2851       [
2852         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(before)$/i, 3 => 'now' },
2853         [ [ 0, 1 ] ],
2854         [ $extended_checks{suffix} ],
2855         [
2856           [
2857               0,
2858             { 2 => [ $flag{before_after_from} ] },
2859           ],
2860         ],
2861         [ { unit => 'minute' } ],
2862         [ '_now_variant' ],
2863         {},
2864       ],
2865       [
2866         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(before)$/i, 3 => 'now' },
2867         [ [ 0, 1 ] ],
2868         [ $extended_checks{suffix} ],
2869         [
2870           [
2871               0,
2872             { 2 => [ $flag{before_after_from} ] },
2873           ],
2874         ],
2875         [ { unit => 'hour' } ],
2876         [ '_now_variant' ],
2877         {},
2878       ],
2879       [
2880         { 0 => $RE{number}, 1 => qr/^(days?)$/i,  2 => qr/^(before)$/i, 3 => 'now' },
2881         [ [ 0, 1 ] ],
2882         [ $extended_checks{suffix} ],
2883         [
2884           [
2885               0,
2886             { 2 => [ $flag{before_after_from} ] },
2887           ],
2888         ],
2889         [ { unit => 'day' } ],
2890         [ '_now_variant' ],
2891         {},
2892       ],
2893       [
2894         { 0 => $RE{number}, 1 => qr/^(weeks?)$/i, 2 => qr/^(before)$/i, 3 => 'now' },
2895         [ [ 0, 1 ] ],
2896         [ $extended_checks{suffix} ],
2897         [
2898           [
2899               0,
2900             { 2 => [ $flag{before_after_from} ] },
2901           ],
2902         ],
2903         [ { unit => 'week' } ],
2904         [ '_now_variant' ],
2905         {},
2906       ],
2907       [
2908         { 0 => $RE{number}, 1 => qr/^(months?)$/i, 2 => qr/^(before)$/i, 3 => 'now' },
2909         [ [ 0, 1 ] ],
2910         [ $extended_checks{suffix} ],
2911         [
2912           [
2913               0,
2914             { 2 => [ $flag{before_after_from} ] },
2915           ]
2916         ],
2917         [ { unit => 'month' } ],
2918         [ '_now_variant' ],
2919         {},
2920       ],
2921       [
2922         { 0 => $RE{number}, 1 => qr/^(years?)$/i, 2 => qr/^(before)$/i, 3 => 'now' },
2923         [ [ 0, 1 ] ],
2924         [ $extended_checks{suffix} ],
2925         [
2926           [
2927               0,
2928             { 2 => [ $flag{before_after_from} ] },
2929           ],
2930         ],
2931         [ { unit => 'year' } ],
2932         [ '_now_variant' ],
2933         {},
2934       ],
2935    ],
2936    now_variant_from => [
2937       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
2938       [
2939         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
2940         [ [ 0, 1 ] ],
2941         [ $extended_checks{suffix} ],
2942         [
2943           [
2944               0,
2945             { 2 => [ $flag{before_after_from} ] },
2946           ],
2947         ],
2948         [ { unit => 'second' } ],
2949         [ '_now_variant' ],
2950         {},
2951       ],
2952       [
2953         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
2954         [ [ 0, 1 ] ],
2955         [ $extended_checks{suffix} ],
2956         [
2957           [
2958               0,
2959             { 2 => [ $flag{before_after_from} ] },
2960           ],
2961         ],
2962         [ { unit => 'minute' } ],
2963         [ '_now_variant' ],
2964         {},
2965       ],
2966       [
2967         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
2968         [ [ 0, 1 ] ],
2969         [ $extended_checks{suffix} ],
2970         [
2971           [
2972               0,
2973             { 2 => [ $flag{before_after_from} ] },
2974           ],
2975         ],
2976         [ { unit => 'hour' } ],
2977         [ '_now_variant' ],
2978         {},
2979       ],
2980       [
2981         { 0 => $RE{number}, 1 => qr/^(days?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
2982         [ [ 0, 1 ] ],
2983         [ $extended_checks{suffix} ],
2984         [
2985           [
2986               0,
2987             { 2 => [ $flag{before_after_from} ] },
2988           ],
2989         ],
2990         [ { unit => 'day' } ],
2991         [ '_now_variant' ],
2992         {},
2993       ],
2994       [
2995         { 0 => $RE{number}, 1 => qr/^(weeks?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
2996         [ [ 0, 1 ] ],
2997         [ $extended_checks{suffix} ],
2998         [
2999           [
3000               0,
3001             { 2 => [ $flag{before_after_from} ] },
3002           ],
3003         ],
3004         [ { unit => 'week' } ],
3005         [ '_now_variant' ],
3006         {},
3007       ],
3008       [
3009         { 0 => $RE{number}, 1 => qr/^(months?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
3010         [ [ 0, 1 ] ],
3011         [ $extended_checks{suffix} ],
3012         [
3013           [
3014               0,
3015             { 2 => [ $flag{before_after_from} ] },
3016           ],
3017         ],
3018         [ { unit => 'month' } ],
3019         [ '_now_variant' ],
3020         {},
3021       ],
3022       [
3023         { 0 => $RE{number}, 1 => qr/^(years?)$/i, 2 => qr/^(from)$/i, 3 => 'now' },
3024         [ [ 0, 1 ] ],
3025         [ $extended_checks{suffix} ],
3026         [
3027           [
3028               0,
3029             { 2 => [ $flag{before_after_from} ] },
3030           ],
3031         ],
3032         [ { unit => 'year' } ],
3033         [ '_now_variant' ],
3034         {},
3035       ],
3036    ],
3037    day_daytime => [
3038       [ 'REGEXP', 'REGEXP', 'SCALAR', 'SCALAR', 'SCALAR' ],
3039       [
3040         { 0 => $RE{weekday}, 1 => $RE{number}, 2 => 'in', 3 => 'the', 4 => 'morning' },
3041         [],
3042         [],
3043         [
3044           [
3045             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3046           ],
3047           [ 1 ],
3048         ],
3049         [ {}, {} ],
3050         [ '_weekday', '_daytime' ],
3051         { truncate_to => [undef, q(hour)] },
3052       ],
3053       [
3054         { 0 => $RE{weekday}, 1 => $RE{number}, 2 => 'in', 3 => 'the', 4 => 'afternoon' },
3055         [],
3056         [],
3057         [
3058           [
3059             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3060           ],
3061           [ 1 ],
3062         ],
3063         [ {}, { hours => 12 } ],
3064         [ '_weekday', '_daytime' ],
3065         { truncate_to => [undef, q(hour)] },
3066       ],
3067       [
3068         { 0 => $RE{weekday}, 1 => $RE{number}, 2 => 'in', 3 => 'the', 4 => 'evening' },
3069         [],
3070         [],
3071         [
3072           [
3073             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3074           ],
3075           [ 1 ],
3076         ],
3077         [ {}, { hours => 12 } ],
3078         [ '_weekday', '_daytime' ],
3079         { truncate_to => [undef, q(hour)] },
3080       ],
3081    ],
3082    variant_weekday_at_time => [
3083       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
3084       [
3085         { 0 => qr/^(next)$/i, 1 => $RE{weekday}, 2 => $RE{time} },
3086         [],
3087         [],
3088         [
3089           [
3090             { 0 => [ $flag{last_this_next} ] },
3091             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3092           ],
3093           [ 2 ],
3094         ],
3095         [ {}, {} ],
3096         [ '_count_day_variant_week', '_time' ],
3097         { truncate_to => [undef, q(hour_minute)] },
3098       ],
3099       [
3100         { 0 => qr/^(this)$/i, 1 => $RE{weekday}, 2 => $RE{time} },
3101         [],
3102         [],
3103         [
3104           [
3105             { 0 => [ $flag{last_this_next} ] },
3106             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3107           ],
3108           [ 2 ],
3109         ],
3110         [ {}, {} ],
3111         [ '_count_day_variant_week', '_time' ],
3112         { truncate_to => [undef, q(hour_minute)] },
3113       ],
3114       [
3115         { 0 => qr/^(last)$/i, 1 => $RE{weekday}, 2 => $RE{time} },
3116         [],
3117         [],
3118         [
3119           [
3120             { 0 => [ $flag{last_this_next} ] },
3121             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3122           ],
3123           [ 2 ],
3124         ],
3125         [ {}, {} ],
3126         [ '_count_day_variant_week', '_time' ],
3127         { truncate_to => [undef, q(hour_minute)] },
3128       ],
3129    ],
3130    count_day_variant_week => [
3131       [ 'REGEXP', 'SCALAR', 'REGEXP', 'SCALAR' ],
3132       [
3133         { 0 => $RE{day}, 1 => 'day', 2 => qr/^(next)$/i, 3 => 'week' },
3134         [ [ 0 ] ],
3135         [ $extended_checks{ordinal} ],
3136         [
3137           [
3138             { 2 => [ $flag{last_this_next} ] },
3139               0,
3140           ],
3141         ],
3142         [ {} ],
3143         [ '_count_day_variant_week' ],
3144         { truncate_to => [q(day)] },
3145       ],
3146       [
3147         { 0 => $RE{day}, 1 => 'day', 2 => qr/^(this)$/i, 3 => 'week' },
3148         [ [ 0 ] ],
3149         [ $extended_checks{ordinal} ],
3150         [
3151           [
3152             { 2 => [ $flag{last_this_next} ] },
3153               0,
3154           ],
3155         ],
3156         [ {} ],
3157         [ '_count_day_variant_week' ],
3158         { truncate_to => [q(day)] },
3159       ],
3160       [
3161         { 0 => $RE{day}, 1 => 'day', 2 => qr/^(last)$/i, 3 => 'week' },
3162         [ [ 0 ] ],
3163         [ $extended_checks{ordinal} ],
3164         [
3165           [
3166             { 2 => [ $flag{last_this_next} ] },
3167               0,
3168           ],
3169         ],
3170         [ {} ],
3171         [ '_count_day_variant_week' ],
3172         { truncate_to => [q(day)] },
3173       ],
3174    ],
3175    count_day_variant_month => [
3176       [ 'REGEXP', 'SCALAR', 'REGEXP', 'SCALAR' ],
3177       [
3178         { 0 => $RE{day}, 1 => 'day', 2 => qr/^(next)$/i, 3 => 'month' },
3179         [ [ 0 ] ],
3180         [ $extended_checks{ordinal} ],
3181         [
3182           [
3183             { 2 => [ $flag{last_this_next} ] },
3184               0,
3185           ],
3186         ],
3187         [ {} ],
3188         [ '_count_day_variant_month' ],
3189         { truncate_to => [q(day)] },
3190       ],
3191       [
3192         { 0 => $RE{day}, 1 => 'day', 2 => qr/^(this)$/i, 3 => 'month' },
3193         [ [ 0 ] ],
3194         [ $extended_checks{ordinal} ],
3195         [
3196           [
3197             { 2 => [ $flag{last_this_next} ] },
3198               0,
3199           ],
3200         ],
3201         [ {} ],
3202         [ '_count_day_variant_month' ],
3203         { truncate_to => [q(day)] },
3204       ],
3205       [
3206         { 0 => $RE{day}, 1 => 'day', 2 => qr/^(last)$/i, 3 => 'month' },
3207         [ [ 0 ] ],
3208         [ $extended_checks{ordinal} ],
3209         [
3210           [
3211             { 2 => [ $flag{last_this_next} ] },
3212               0,
3213           ],
3214         ],
3215         [ {} ],
3216         [ '_count_day_variant_month' ],
3217         { truncate_to => [q(day)] },
3218       ],
3219    ],
3220    weekday_variant_week => [
3221       [ 'REGEXP', 'REGEXP', 'SCALAR' ],
3222       [
3223         { 0 => $RE{weekday}, 1 => qr/^(next)$/i, 2 => 'week' },
3224         [],
3225         [],
3226         [
3227           [
3228             { 1 => [ $flag{last_this_next} ] },
3229             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3230           ],
3231         ],
3232         [ {} ],
3233         [ '_count_day_variant_week' ],
3234         { truncate_to => [q(day)] },
3235       ],
3236       [
3237         { 0 => $RE{weekday}, 1 => qr/^(this)$/i, 2 => 'week' },
3238         [],
3239         [],
3240         [
3241           [
3242             { 1 => [ $flag{last_this_next} ] },
3243             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3244           ],
3245         ],
3246         [ {} ],
3247         [ '_count_day_variant_week' ],
3248         { truncate_to => [q(day)] },
3249       ],
3250       [
3251         { 0 => $RE{weekday}, 1 => qr/^(last)$/i, 2 => 'week' },
3252         [],
3253         [],
3254         [
3255           [
3256             { 1 => [ $flag{last_this_next} ] },
3257             { 0 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3258           ]
3259         ],
3260         [ {} ],
3261         [ '_count_day_variant_week' ],
3262         { truncate_to => [q(day)] },
3263       ],
3264    ],
3265    variant_week_weekday => [
3266       [ 'REGEXP', 'SCALAR', 'REGEXP' ],
3267       [
3268         { 0 => qr/^(next)$/i, 1 => 'week', 2 => $RE{weekday} },
3269         [],
3270         [],
3271         [
3272           [
3273             { 0 => [ $flag{last_this_next} ] },
3274             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3275           ],
3276         ],
3277         [ {} ],
3278         [ '_count_day_variant_week' ],
3279         { truncate_to => [q(day)] },
3280       ],
3281       [
3282         { 0 => qr/^(this)$/i, 1 => 'week', 2 => $RE{weekday} },
3283         [],
3284         [],
3285         [
3286           [
3287             { 0 => [ $flag{last_this_next} ] },
3288             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3289           ],
3290         ],
3291         [ {} ],
3292         [ '_count_day_variant_week' ],
3293         { truncate_to => [q(day)] },
3294       ],
3295       [
3296         { 0 => qr/^(last)$/i, 1 => 'week', 2 => $RE{weekday} },
3297         [],
3298         [],
3299         [
3300           [
3301             { 0 => [ $flag{last_this_next} ] },
3302             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3303           ],
3304         ],
3305         [ {} ],
3306         [ '_count_day_variant_week' ],
3307         { truncate_to => [q(day)] },
3308       ],
3309    ],
3310    count_month_variant_year => [
3311       [ 'REGEXP', 'SCALAR', 'REGEXP', 'SCALAR' ],
3312       [
3313         { 0 => $RE{day}, 1 => 'month', 2 => qr/^(next)$/i, 3 => 'year' },
3314         [ [ 0 ] ],
3315         [ $extended_checks{ordinal} ],
3316         [
3317           [
3318             { 2 => [ $flag{last_this_next} ] },
3319               0,
3320           ],
3321         ],
3322         [ {} ],
3323         [ '_count_month_variant_year' ],
3324         { truncate_to => [q(month)] },
3325       ],
3326       [
3327         { 0 => $RE{day}, 1 => 'month', 2 => qr/^(this)$/i, 3 => 'year' },
3328         [ [ 0 ] ],
3329         [ $extended_checks{ordinal} ],
3330         [
3331           [
3332             { 2 => [ $flag{last_this_next} ] },
3333               0,
3334           ],
3335         ],
3336         [ {} ],
3337         [ '_count_month_variant_year' ],
3338         { truncate_to => [q(month)] },
3339       ],
3340       [
3341         { 0 => $RE{day}, 1 => 'month', 2 => qr/^(last)$/i, 3 => 'year' },
3342         [ [ 0 ] ],
3343         [ $extended_checks{ordinal} ],
3344         [
3345           [
3346             { 2 => [ $flag{last_this_next} ] },
3347               0,
3348           ],
3349         ],
3350         [ {} ],
3351         [ '_count_month_variant_year' ],
3352         { truncate_to => [q(month)] },
3353       ],
3354    ],
3355    in_count_unit => [
3356       [ 'SCALAR', 'REGEXP', 'REGEXP' ],
3357       [
3358         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(seconds?)$/i },
3359         [ [ 1, 2 ] ],
3360         [ $extended_checks{suffix} ],
3361         [ [ 1 ] ],
3362         [ { unit => 'second' } ],
3363         [ '_in_count_variant' ],
3364         {},
3365       ],
3366       [
3367         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(minutes?)$/i },
3368         [ [ 1, 2 ] ],
3369         [ $extended_checks{suffix} ],
3370         [ [ 1 ] ],
3371         [ { unit => 'minute' } ],
3372         [ '_in_count_variant' ],
3373         {},
3374       ],
3375       [
3376         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(hours?)$/i },
3377         [ [ 1, 2 ] ],
3378         [ $extended_checks{suffix} ],
3379         [ [ 1 ] ],
3380         [ { unit => 'hour' } ],
3381         [ '_in_count_variant' ],
3382         {},
3383       ],
3384       [
3385         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(days?)$/i },
3386         [ [ 1, 2 ] ],
3387         [ $extended_checks{suffix} ],
3388         [ [ 1 ] ],
3389         [ { unit => 'day' } ],
3390         [ '_in_count_variant' ],
3391         {},
3392       ],
3393       [
3394         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(weeks?)$/i },
3395         [ [ 1, 2 ] ],
3396         [ $extended_checks{suffix} ],
3397         [ [ 1 ] ],
3398         [ { unit => 'week' } ],
3399         [ '_in_count_variant' ],
3400         {},
3401       ],
3402       [
3403         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(months?)$/i },
3404         [ [ 1, 2 ] ],
3405         [ $extended_checks{suffix} ],
3406         [ [ 1 ] ],
3407         [ { unit => 'month' } ],
3408         [ '_in_count_variant' ],
3409         {},
3410       ],
3411       [
3412         { 0 => 'in', 1 => $RE{number}, 2 => qr/^(years?)$/i },
3413         [ [ 1, 2 ] ],
3414         [ $extended_checks{suffix} ],
3415         [ [ 1 ] ],
3416         [ { unit => 'year' } ],
3417         [ '_in_count_variant' ],
3418         {},
3419       ],
3420    ],
3421    count_weekday_variant_month => [
3422       [ 'REGEXP', 'REGEXP', 'REGEXP', 'REGEXP' ],
3423       [
3424         { 0 => $RE{day}, 1 => $RE{weekday}, 2 => qr/^(next)$/i, 3 => $RE{month} },
3425         [ [ 0 ] ],
3426         [ $extended_checks{ordinal} ],
3427         [
3428           [
3429             { 2 => [ $flag{last_this_next} ] },
3430               0,
3431             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3432             { 3 => [ $flag{month_name}, $flag{month_num} ] },
3433           ],
3434         ],
3435         [ {} ],
3436         [ '_count_weekday_variant_month' ],
3437         { truncate_to => [q(day)] },
3438       ],
3439       [
3440         { 0 => $RE{day}, 1 => $RE{weekday}, 2 => qr/^(this)$/i, 3 => $RE{month} },
3441         [ [ 0 ] ],
3442         [ $extended_checks{ordinal} ],
3443         [
3444           [
3445             { 2 => [ $flag{last_this_next} ] },
3446               0,
3447             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3448             { 3 => [ $flag{month_name}, $flag{month_num} ] },
3449           ],
3450         ],
3451         [ {} ],
3452         [ '_count_weekday_variant_month' ],
3453         { truncate_to => [q(day)] },
3454       ],
3455       [
3456         { 0 => $RE{day}, 1 => $RE{weekday}, 2 => qr/^(last)$/i, 3 => $RE{month} },
3457         [ [ 0 ] ],
3458         [ $extended_checks{ordinal} ],
3459         [
3460           [
3461             { 2 => [ $flag{last_this_next} ] },
3462               0,
3463             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
3464             { 3 => [ $flag{month_name}, $flag{month_num} ] },
3465           ],
3466         ],
3467         [ {} ],
3468         [ '_count_weekday_variant_month' ],
3469         { truncate_to => [q(day)] },
3470       ],
3471    ],
3472    daytime_hours_variant => [
3473       [ 'REGEXP', 'REGEXP', 'REGEXP', 'REGEXP' ],
3474       [
3475         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(yesterday)$/i },
3476         [ [ 0, 1 ] ],
3477         [ $extended_checks{suffix} ],
3478         [
3479           [
3480               0,
3481             { 2 => [ $flag{before_after_from} ] },
3482             { 3 => [ $flag{yes_today_tom} ] },
3483           ],
3484         ],
3485         [ { unit => 'second' } ],
3486         [ '_daytime_unit_variant' ],
3487         {},
3488       ],
3489       [
3490         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(yesterday)$/i },
3491         [ [ 0, 1 ] ],
3492         [ $extended_checks{suffix} ],
3493         [
3494           [
3495               0,
3496             { 2 => [ $flag{before_after_from} ] },
3497             { 3 => [ $flag{yes_today_tom} ] },
3498           ],
3499         ],
3500         [ { unit => 'minute' } ],
3501         [ '_daytime_unit_variant' ],
3502         {},
3503       ],
3504       [
3505         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(yesterday)$/i },
3506         [ [ 0, 1 ] ],
3507         [ $extended_checks{suffix} ],
3508         [
3509           [
3510               0,
3511             { 2 => [ $flag{before_after_from} ] },
3512             { 3 => [ $flag{yes_today_tom} ] },
3513           ],
3514         ],
3515         [ { unit => 'hour' } ],
3516         [ '_daytime_unit_variant' ],
3517         {},
3518       ],
3519       [
3520         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(today)$/i },
3521         [ [ 0, 1 ] ],
3522         [ $extended_checks{suffix} ],
3523         [
3524           [
3525               0,
3526             { 2 => [ $flag{before_after_from} ] },
3527             { 3 => [ $flag{yes_today_tom} ] },
3528           ],
3529         ],
3530         [ { unit => 'second' } ],
3531         [ '_daytime_unit_variant' ],
3532         {},
3533       ],
3534       [
3535         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(today)$/i },
3536         [ [ 0, 1 ] ],
3537         [ $extended_checks{suffix} ],
3538         [
3539           [
3540               0,
3541             { 2 => [ $flag{before_after_from} ] },
3542             { 3 => [ $flag{yes_today_tom} ] },
3543           ],
3544         ],
3545         [ { unit => 'minute' } ],
3546         [ '_daytime_unit_variant' ],
3547         {},
3548       ],
3549       [
3550         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(today)$/i },
3551         [ [ 0, 1 ] ],
3552         [ $extended_checks{suffix} ],
3553         [
3554           [
3555               0,
3556             { 2 => [ $flag{before_after_from} ] },
3557             { 3 => [ $flag{yes_today_tom} ] },
3558           ],
3559         ],
3560         [ { unit => 'hour' } ],
3561         [ '_daytime_unit_variant' ],
3562         {},
3563       ],
3564       [
3565         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(tomorrow)$/i },
3566         [ [ 0, 1 ] ],
3567         [ $extended_checks{suffix} ],
3568         [
3569           [
3570               0,
3571             { 2 => [ $flag{before_after_from} ] },
3572             { 3 => [ $flag{yes_today_tom} ] },
3573           ],
3574         ],
3575         [ { unit => 'second' } ],
3576         [ '_daytime_unit_variant' ],
3577         {},
3578       ],
3579       [
3580         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(tomorrow)$/i },
3581         [ [ 0, 1 ] ],
3582         [ $extended_checks{suffix} ],
3583         [
3584           [
3585               0,
3586             { 2 => [ $flag{before_after_from} ] },
3587             { 3 => [ $flag{yes_today_tom} ] },
3588           ],
3589         ],
3590         [ { unit => 'minute' } ],
3591         [ '_daytime_unit_variant' ],
3592         {},
3593       ],
3594       [
3595         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(before)$/i, 3 => qr/^(tomorrow)$/i },
3596         [ [ 0, 1 ] ],
3597         [ $extended_checks{suffix} ],
3598         [
3599           [
3600               0,
3601             { 2 => [ $flag{before_after_from} ] },
3602             { 3 => [ $flag{yes_today_tom} ] },
3603           ],
3604         ],
3605         [ { unit => 'hour' } ],
3606         [ '_daytime_unit_variant' ],
3607         {},
3608       ],
3609       [
3610         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(yesterday)$/i },
3611         [ [ 0, 1 ] ],
3612         [ $extended_checks{suffix} ],
3613         [
3614           [
3615               0,
3616             { 2 => [ $flag{before_after_from} ] },
3617             { 3 => [ $flag{yes_today_tom} ] },
3618           ],
3619         ],
3620         [ { unit => 'second' } ],
3621         [ '_daytime_unit_variant' ],
3622         {},
3623       ],
3624       [
3625         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(yesterday)$/i },
3626         [ [ 0, 1 ] ],
3627         [ $extended_checks{suffix} ],
3628         [
3629           [
3630               0,
3631             { 2 => [ $flag{before_after_from} ] },
3632             { 3 => [ $flag{yes_today_tom} ] },
3633           ],
3634         ],
3635         [ { unit => 'minute' } ],
3636         [ '_daytime_unit_variant' ],
3637         {},
3638       ],
3639       [
3640         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(yesterday)$/i },
3641         [ [ 0, 1 ] ],
3642         [ $extended_checks{suffix} ],
3643         [
3644           [
3645               0,
3646             { 2 => [ $flag{before_after_from} ] },
3647             { 3 => [ $flag{yes_today_tom} ] },
3648           ],
3649         ],
3650         [ { unit => 'hour' } ],
3651         [ '_daytime_unit_variant' ],
3652         {},
3653       ],
3654       [
3655         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(today)$/i },
3656         [ [ 0, 1 ] ],
3657         [ $extended_checks{suffix} ],
3658         [
3659           [
3660               0,
3661             { 2 => [ $flag{before_after_from} ] },
3662             { 3 => [ $flag{yes_today_tom} ] },
3663           ],
3664         ],
3665         [ { unit => 'second' } ],
3666         [ '_daytime_unit_variant' ],
3667         {},
3668       ],
3669       [
3670         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(today)$/i },
3671         [ [ 0, 1 ] ],
3672         [ $extended_checks{suffix} ],
3673         [
3674           [
3675               0,
3676             { 2 => [ $flag{before_after_from} ] },
3677             { 3 => [ $flag{yes_today_tom} ] },
3678           ],
3679         ],
3680         [ { unit => 'minute' } ],
3681         [ '_daytime_unit_variant' ],
3682         {},
3683       ],
3684       [
3685         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(today)$/i },
3686         [ [ 0, 1 ] ],
3687         [ $extended_checks{suffix} ],
3688         [
3689           [
3690               0,
3691             { 2 => [ $flag{before_after_from} ] },
3692             { 3 => [ $flag{yes_today_tom} ] },
3693           ],
3694         ],
3695         [ { unit => 'hour' } ],
3696         [ '_daytime_unit_variant' ],
3697         {},
3698       ],
3699       [
3700         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(tomorrow)$/i },
3701         [ [ 0, 1 ] ],
3702         [ $extended_checks{suffix} ],
3703         [
3704           [
3705               0,
3706             { 2 => [ $flag{before_after_from} ] },
3707             { 3 => [ $flag{yes_today_tom} ] },
3708           ],
3709         ],
3710         [ { unit => 'second' } ],
3711         [ '_daytime_unit_variant' ],
3712         {},
3713       ],
3714       [
3715         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(tomorrow)$/i },
3716         [ [ 0, 1 ] ],
3717         [ $extended_checks{suffix} ],
3718         [
3719           [
3720               0,
3721             { 2 => [ $flag{before_after_from} ] },
3722             { 3 => [ $flag{yes_today_tom} ] },
3723           ],
3724         ],
3725         [ { unit => 'minute' } ],
3726         [ '_daytime_unit_variant' ],
3727         {},
3728       ],
3729       [
3730         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(after)$/i, 3 => qr/^(tomorrow)$/i },
3731         [ [ 0, 1 ] ],
3732         [ $extended_checks{suffix} ],
3733         [
3734           [
3735               0,
3736             { 2 => [ $flag{before_after_from} ] },
3737             { 3 => [ $flag{yes_today_tom} ] },
3738           ],
3739         ],
3740         [ { unit => 'hour' } ],
3741         [ '_daytime_unit_variant' ],
3742         {},
3743       ],
3744    ],
3745    hourtime_before_after_variant => [
3746       [ 'REGEXP', 'REGEXP', 'REGEXP', 'SCALAR' ],
3747       [
3748         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(before)$/i, 3 => 'noon' },
3749         [ [ 0, 1 ] ],
3750         [ $extended_checks{suffix} ],
3751         [
3752           [
3753               0,
3754             { 2 => [ $flag{before_after_from} ] },
3755           ],
3756         ],
3757         [ { hours => 12, unit => 'second' } ],
3758         [ '_hourtime_variant' ],
3759         {},
3760       ],
3761       [
3762         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(before)$/i, 3 => 'noon' },
3763         [ [ 0, 1 ] ],
3764         [ $extended_checks{suffix} ],
3765         [
3766           [
3767               0,
3768             { 2 => [ $flag{before_after_from} ] },
3769           ],
3770         ],
3771         [ { hours => 12, unit => 'minute' } ],
3772         [ '_hourtime_variant' ],
3773         {},
3774       ],
3775       [
3776         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(before)$/i, 3 => 'noon' },
3777         [ [ 0, 1 ] ],
3778         [ $extended_checks{suffix} ],
3779         [
3780           [
3781               0,
3782             { 2 => [ $flag{before_after_from} ] },
3783           ],
3784         ],
3785         [ { hours => 12, unit => 'hour' } ],
3786         [ '_hourtime_variant' ],
3787         {},
3788       ],
3789       [
3790         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(before)$/i, 3 => 'midnight' },
3791         [ [ 0, 1 ] ],
3792         [ $extended_checks{suffix} ],
3793         [
3794           [
3795               0,
3796             { 2 => [ $flag{before_after_from} ] },
3797           ],
3798         ],
3799         [ { unit => 'second' } ],
3800         [ '_hourtime_variant' ],
3801         {},
3802       ],
3803       [
3804         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(before)$/i, 3 => 'midnight' },
3805         [ [ 0, 1 ] ],
3806         [ $extended_checks{suffix} ],
3807         [
3808           [
3809               0,
3810             { 2 => [ $flag{before_after_from} ] },
3811           ],
3812         ],
3813         [ { unit => 'minute' } ],
3814         [ '_hourtime_variant' ],
3815         {},
3816       ],
3817       [
3818         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(before)$/i, 3 => 'midnight' },
3819         [ [ 0, 1 ] ],
3820         [ $extended_checks{suffix} ],
3821         [
3822           [
3823               0,
3824             { 2 => [ $flag{before_after_from} ] },
3825           ],
3826         ],
3827         [ { unit => 'hour' } ],
3828         [ '_hourtime_variant' ],
3829         {},
3830       ],
3831       [
3832         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(after)$/i, 3 => 'noon' },
3833         [ [ 0, 1 ] ],
3834         [ $extended_checks{suffix} ],
3835         [
3836           [
3837               0,
3838             { 2 => [ $flag{before_after_from} ] },
3839           ],
3840         ],
3841         [ { hours => 12, unit => 'second' } ],
3842         [ '_hourtime_variant' ],
3843         {},
3844       ],
3845       [
3846         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(after)$/i, 3 => 'noon' },
3847         [ [ 0, 1 ] ],
3848         [ $extended_checks{suffix} ],
3849         [
3850           [
3851               0,
3852             { 2 => [ $flag{before_after_from} ] },
3853           ],
3854         ],
3855         [ { hours => 12, unit => 'minute' } ],
3856         [ '_hourtime_variant' ],
3857         {},
3858       ],
3859       [
3860         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(after)$/i, 3 => 'noon' },
3861         [ [ 0, 1 ] ],
3862         [ $extended_checks{suffix} ],
3863         [
3864           [
3865               0,
3866             { 2 => [ $flag{before_after_from} ] },
3867           ],
3868         ],
3869         [ { hours => 12, unit => 'hour' } ],
3870         [ '_hourtime_variant' ],
3871         {},
3872       ],
3873       [
3874         { 0 => $RE{number}, 1 => qr/^(seconds?)$/i, 2 => qr/^(after)$/i, 3 => 'midnight' },
3875         [ [ 0, 1 ] ],
3876         [ $extended_checks{suffix} ],
3877         [
3878           [
3879               0,
3880             { 2 => [ $flag{before_after_from} ] },
3881           ],
3882         ],
3883         [ { unit => 'second' } ],
3884         [ '_hourtime_variant' ],
3885         {},
3886       ],
3887       [
3888         { 0 => $RE{number}, 1 => qr/^(minutes?)$/i, 2 => qr/^(after)$/i, 3 => 'midnight' },
3889         [ [ 0, 1 ] ],
3890         [ $extended_checks{suffix} ],
3891         [
3892           [
3893               0,
3894             { 2 => [ $flag{before_after_from} ] },
3895           ],
3896         ],
3897         [ { unit => 'minute' } ],
3898         [ '_hourtime_variant' ],
3899         {},
3900       ],
3901       [
3902         { 0 => $RE{number}, 1 => qr/^(hours?)$/i, 2 => qr/^(after)$/i, 3 => 'midnight' },
3903         [ [ 0, 1 ] ],
3904         [ $extended_checks{suffix} ],
3905         [
3906           [
3907               0,
3908             { 2 => [ $flag{before_after_from} ] },
3909           ],
3910         ],
3911         [ { unit => 'hour' } ],
3912         [ '_hourtime_variant' ],
3913         {},
3914       ],
3915    ],
3916    day_at => [
3917       [ 'REGEXP', 'REGEXP' ],
3918       [
3919         { 0 => qr/^(yesterday)$/i, 1 => $RE{time} },
3920         [],
3921         [],
3922         [
3923           [
3924             { 0 => [ $flag{yes_today_tom} ] },
3925           ],
3926           [ 1 ],
3927         ],
3928         [ { unit => 'day' }, {} ],
3929         [ '_unit_variant', '_time' ],
3930         { truncate_to => [undef, q(hour_minute)] },
3931       ],
3932       [
3933         { 0 => qr/^(today)$/i, 1 => $RE{time} },
3934         [],
3935         [],
3936         [
3937           [
3938             { 0 => [ $flag{yes_today_tom} ] },
3939           ],
3940           [ 1 ],
3941         ],
3942         [ { unit => 'day' }, {} ],
3943         [ '_unit_variant', '_time' ],
3944         { truncate_to => [undef, q(hour_minute)] },
3945       ],
3946       [
3947         { 0 => qr/^(tomorrow)$/i, 1 => $RE{time} },
3948         [],
3949         [],
3950         [
3951           [
3952             { 0 => [ $flag{yes_today_tom} ] },
3953           ],
3954           [ 1 ],
3955         ],
3956         [ { unit => 'day' }, {} ],
3957         [ '_unit_variant', '_time' ],
3958         { truncate_to => [undef, q(hour_minute)] },
3959       ],
3960       [
3961         { 0 => qr/^(yesterday)$/i, 1 => $RE{time_am} },
3962         [ [ 1 ] ],
3963         [ $extended_checks{meridiem} ],
3964         [
3965           [
3966             { 0 => [ $flag{yes_today_tom} ] },
3967           ],
3968           [
3969             { 1 => [ $flag{time_am} ] },
3970           ],
3971         ],
3972         [ { unit => 'day' }, {} ],
3973         [ '_unit_variant', '_at' ],
3974         { truncate_to => [undef, q(hour_minute)] },
3975       ],
3976       [
3977         { 0 => qr/^(today)$/i, 1 => $RE{time_am} },
3978         [ [ 1 ] ],
3979         [ $extended_checks{meridiem} ],
3980         [
3981           [
3982             { 0 => [ $flag{yes_today_tom} ] },
3983           ],
3984           [
3985             { 1 => [ $flag{time_am} ] },
3986           ],
3987         ],
3988         [ { unit => 'day' }, {} ],
3989         [ '_unit_variant', '_at' ],
3990         { truncate_to => [undef, q(hour_minute)] },
3991       ],
3992       [
3993         { 0 => qr/^(tomorrow)$/i, 1 => $RE{time_am} },
3994         [ [ 1 ] ],
3995         [ $extended_checks{meridiem} ],
3996         [
3997           [
3998             { 0 => [ $flag{yes_today_tom} ] },
3999           ],
4000           [
4001             { 1 => [ $flag{time_am} ] },
4002           ],
4003         ],
4004         [ { unit => 'day' }, {} ],
4005         [ '_unit_variant', '_at' ],
4006         { truncate_to => [undef, q(hour_minute)] },
4007       ],
4008       [
4009         { 0 => qr/^(yesterday)$/i, 1 => $RE{time_pm} },
4010         [ [ 1 ] ],
4011         [ $extended_checks{meridiem} ],
4012         [
4013           [
4014             { 0 => [ $flag{yes_today_tom} ] },
4015           ],
4016           [
4017             { 1 => [ $flag{time_pm} ] },
4018           ],
4019         ],
4020         [ { unit => 'day' }, {} ],
4021         [ '_unit_variant', '_at' ],
4022         { truncate_to => [undef, q(hour_minute)] },
4023       ],
4024       [
4025         { 0 => qr/^(today)$/i, 1 => $RE{time_pm} },
4026         [ [ 1 ] ],
4027         [ $extended_checks{meridiem} ],
4028         [
4029           [
4030             { 0 => [ $flag{yes_today_tom} ] },
4031           ],
4032           [
4033             { 1 => [ $flag{time_pm} ] },
4034           ],
4035         ],
4036         [ { unit => 'day' }, {} ],
4037         [ '_unit_variant', '_at' ],
4038         { truncate_to => [undef, q(hour_minute)] },
4039       ],
4040       [
4041         { 0 => qr/^(tomorrow)$/i, 1 => $RE{time_pm} },
4042         [ [ 1 ] ],
4043         [ $extended_checks{meridiem} ],
4044         [
4045           [
4046             { 0 => [ $flag{yes_today_tom} ] },
4047           ],
4048           [
4049             { 1 => [ $flag{time_pm} ] },
4050           ],
4051         ],
4052         [ { unit => 'day' }, {} ],
4053         [ '_unit_variant', '_at' ],
4054         { truncate_to => [undef, q(hour_minute)] },
4055       ],
4056    ],
4057    time_on_weekday => [
4058       [ 'REGEXP', 'SCALAR', 'REGEXP' ],
4059       [
4060         { 0 => $RE{time}, 1 => 'on', 2 => $RE{weekday} },
4061         [],
4062         [],
4063         [
4064           [ 0 ],
4065           [
4066             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4067           ],
4068         ],
4069         [ {}, {} ],
4070         [ '_time', '_weekday' ],
4071         {
4072           advance_future => true,
4073           truncate_to    => [undef, q(hour_minute)],
4074         },
4075       ],
4076       [
4077         { 0 => $RE{time_am}, 1 => 'on', 2 => $RE{weekday} },
4078         [ [ 0 ] ],
4079         [ $extended_checks{meridiem} ],
4080         [
4081           [
4082             { 0 => [ $flag{time_am} ] },
4083           ],
4084           [
4085             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4086           ],
4087         ],
4088         [ {}, {} ],
4089         [ '_at', '_weekday' ],
4090         {
4091           advance_future => true,
4092           truncate_to    => [undef, q(hour_minute)],
4093         },
4094       ],
4095       [
4096         { 0 => $RE{time_pm}, 1 => 'on', 2 => $RE{weekday} },
4097         [ [ 0 ] ],
4098         [ $extended_checks{meridiem} ],
4099         [
4100           [
4101             { 0 => [ $flag{time_pm} ] },
4102           ],
4103           [
4104             { 2 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4105           ],
4106         ],
4107         [ {}, {} ],
4108         [ '_at', '_weekday' ],
4109         {
4110           advance_future => true,
4111           truncate_to    => [undef, q(hour_minute)],
4112         },
4113       ],
4114    ],
4115    day_month_year => [
4116       [ 'REGEXP', 'REGEXP', 'REGEXP' ],
4117       [
4118         { 0 => $RE{monthday}, 1 => $RE{month}, 2 => $RE{year} },
4119         [ [ 0 ] ],
4120         [ $extended_checks{ordinal} ],
4121         [
4122           [
4123               0,
4124             { 1 => [ $flag{month_name}, $flag{month_num} ] },
4125               2,
4126           ],
4127         ],
4128         [ {} ],
4129         [ '_day_month_year' ],
4130         { truncate_to => [q(day)] },
4131       ],
4132       [
4133         { 0 => $RE{month}, 1 => $RE{monthday}, 2 => $RE{year} },
4134         [ [ 1 ] ],
4135         [ $extended_checks{ordinal} ],
4136         [
4137           [
4138               1,
4139             { 0 => [ $flag{month_name}, $flag{month_num} ] },
4140               2,
4141           ],
4142         ],
4143         [ {} ],
4144         [ '_day_month_year' ],
4145         { truncate_to => [q(day)] },
4146       ],
4147    ],
4148    count_weekday_in_month => [
4149       [ 'REGEXP', 'REGEXP', 'SCALAR', 'REGEXP' ],
4150       [
4151         { 0 => $RE{day}, 1 => $RE{weekday}, 2 => 'in', 3 => $RE{month} },
4152         [ [ 0 ] ],
4153         [ $extended_checks{ordinal} ],
4154         [
4155           [
4156             { VALUE => 0 },
4157               0,
4158             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4159             { 3 => [ $flag{month_name}, $flag{month_num} ] },
4160           ],
4161         ],
4162         [ {} ],
4163         [ '_count_weekday_variant_month' ],
4164         { truncate_to => [q(day)] },
4165       ],
4166    ],
4167    count_weekday_from_now => [
4168       [ 'REGEXP', 'REGEXP', 'SCALAR', 'SCALAR' ],
4169       [
4170         { 0 => $RE{number}, 1 => $RE{weekdays}, 2 => 'from', 3 => 'now' },
4171         [ [ 0, 1 ] ],
4172         [ $extended_checks{suffix} ],
4173         [
4174           [
4175               0,
4176             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4177           ],
4178         ],
4179         [ {} ],
4180         [ '_count_weekday_from_now' ],
4181         { truncate_to => [q(day)] },
4182       ],
4183    ],
4184    final_weekday_in_month => [
4185       [ 'SCALAR', 'REGEXP', 'SCALAR', 'REGEXP' ],
4186       [
4187         { 0 => 'final', 1 => $RE{weekday}, 2 => 'in', 3 => $RE{month} },
4188         [],
4189         [],
4190         [
4191           [
4192             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4193             { 3 => [ $flag{month_name}, $flag{month_num} ] },
4194           ],
4195         ],
4196         [ {} ],
4197         [ '_final_weekday_in_month' ],
4198         { truncate_to => [q(day)] },
4199       ],
4200       [
4201         { 0 => 'last', 1 => $RE{weekday}, 2 => 'in', 3 => $RE{month} },
4202         [],
4203         [],
4204         [
4205           [
4206             { 1 => [ $flag{weekday_name}, $flag{weekday_num} ] },
4207             { 3 => [ $flag{month_name}, $flag{month_num} ] },
4208           ],
4209         ],
4210         [ {} ],
4211         [ '_final_weekday_in_month' ],
4212         { truncate_to => [q(day)] },
4213       ],
4214    ],
4215    for_count_unit => [
4216       [ 'SCALAR', 'REGEXP', 'REGEXP' ],
4217       [
4218         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(seconds?)$/i },
4219         [ [ 1, 2 ] ],
4220         [ $extended_checks{suffix} ],
4221         [
4222           [ 1 ],
4223         ],
4224         [ { unit => 'second' } ],
4225         [ '_in_count_variant' ],
4226         {},
4227       ],
4228       [
4229         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(minutes?)$/i },
4230         [ [ 1, 2 ] ],
4231         [ $extended_checks{suffix} ],
4232         [
4233           [ 1 ],
4234         ],
4235         [ { unit => 'minute' } ],
4236         [ '_in_count_variant' ],
4237         {},
4238       ],
4239       [
4240         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(hours?)$/i },
4241         [ [ 1, 2 ] ],
4242         [ $extended_checks{suffix} ],
4243         [
4244           [ 1 ],
4245         ],
4246         [ { unit => 'hour' } ],
4247         [ '_in_count_variant' ],
4248         {},
4249       ],
4250       [
4251         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(days?)$/i },
4252         [ [ 1, 2 ] ],
4253         [ $extended_checks{suffix} ],
4254         [
4255           [ 1 ],
4256         ],
4257         [ { unit => 'day' } ],
4258         [ '_in_count_variant' ],
4259         {},
4260       ],
4261       [
4262         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(weeks?)$/i },
4263         [ [ 1, 2 ] ],
4264         [ $extended_checks{suffix} ],
4265         [
4266           [ 1 ],
4267         ],
4268         [ { unit => 'week' } ],
4269         [ '_in_count_variant' ],
4270         {},
4271       ],
4272       [
4273         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(months?)$/i },
4274         [ [ 1, 2 ] ],
4275         [ $extended_checks{suffix} ],
4276         [
4277           [ 1 ],
4278         ],
4279         [ { unit => 'month' } ],
4280         [ '_in_count_variant' ],
4281         {},
4282       ],
4283       [
4284         { 0 => 'for', 1 => $RE{number}, 2 => qr/^(years?)$/i },
4285         [ [ 1, 2 ] ],
4286         [ $extended_checks{suffix} ],
4287         [
4288           [ 1 ],
4289         ],
4290         [ { unit => 'year' } ],
4291         [ '_in_count_variant' ],
4292         {},
4293       ],
4294    ],
4295    first_last_day_unit => [
4296       [ 'SCALAR', 'SCALAR', 'SCALAR', 'REGEXP' ],
4297       [
4298         { 0 => 'first', 1 => 'day', 2 => 'of', 3 => $RE{month} },
4299         [],
4300         [],
4301         [
4302           [
4303             { 3 => [ $flag{month_name}, $flag{month_num} ] },
4304             { VALUE => 1 },
4305           ],
4306         ],
4307         [ {} ],
4308         [ '_first_last_day_unit' ],
4309         { truncate_to => [q(day)] },
4310       ],
4311       [
4312         { 0 => 'first', 1 => 'day', 2 => 'of', 3 => $RE{year} },
4313         [],
4314         [],
4315         [
4316           [
4317               3,
4318             { VALUE => 1 },
4319             { VALUE => 1 },
4320           ],
4321         ],
4322         [ {} ],
4323         [ '_first_last_day_unit' ],
4324         { truncate_to => [q(day)] },
4325       ],
4326       [
4327         { 0 => 'last', 1 => 'day', 2 => 'of', 3 => $RE{month} },
4328         [],
4329         [],
4330         [
4331           [
4332             { 3 => [ $flag{month_name}, $flag{month_num} ] },
4333             { VALUE => undef },
4334           ],
4335         ],
4336         [ {} ],
4337         [ '_first_last_day_unit' ],
4338         { truncate_to => [q(day)] },
4339       ],
4340       [
4341         { 0 => 'last', 1 => 'day', 2 => 'of', 3 => $RE{year} },
4342         [],
4343         [],
4344         [
4345           [
4346                3,
4347              { VALUE => 12 },
4348              { VALUE => undef },
4349            ],
4350         ],
4351         [ {} ],
4352         [ '_first_last_day_unit' ],
4353         { truncate_to => [q(day)] },
4354       ],
4355    ],
4356    variant_last_month => [
4357       [ 'SCALAR', 'SCALAR', 'SCALAR', 'SCALAR' ],
4358       [
4359         { 0 => 'beginning', 1 => 'of', 2 => 'last', 3 => 'month' },
4360         [],
4361         [],
4362         [
4363           [
4364             { VALUE => 1 },
4365           ],
4366         ],
4367         [ {} ],
4368         [ '_variant_last_month' ],
4369         { truncate_to => [q(day)] },
4370       ],
4371       [
4372         { 0 => 'end', 1 => 'of', 2 => 'last', 3 => 'month' },
4373         [],
4374         [],
4375         [
4376           [
4377             { VALUE => undef },
4378           ],
4379         ],
4380         [ {} ],
4381         [ '_variant_last_month' ],
4382         { truncate_to => [q(day)] },
4383       ],
4384    ],
4385    variant_quarter => [
4386       [ 'REGEXP', 'SCALAR' ],
4387       [
4388         { 0 => qr/^(last)$/i, 1 => 'quarter' },
4389         [],
4390         [],
4391         [
4392           [
4393             { 0 => [ $flag{last_this_next} ] },
4394           ],
4395         ],
4396         [ { unit => 'month' } ],
4397         [ '_variant_quarter' ],
4398         { truncate_to => [q(day)] },
4399       ],
4400       [
4401         { 0 => qr/^(this)$/i, 1 => 'quarter' },
4402         [],
4403         [],
4404         [
4405           [
4406             { 0 => [ $flag{last_this_next} ] },
4407           ],
4408         ],
4409         [ { unit => 'month' } ],
4410         [ '_variant_quarter' ],
4411         { truncate_to => [q(day)] },
4412       ],
4413       [
4414         { 0 => qr/^(next)$/i, 1 => 'quarter' },
4415         [],
4416         [],
4417         [
4418           [
4419             { 0 => [ $flag{last_this_next} ] },
4420           ],
4421         ],
4422         [ { unit => 'month' } ],
4423         [ '_variant_quarter' ],
4424         { truncate_to => [q(day)] },
4425       ],
4426    ],
4427);
4428
44291;
4430__END__
4431
4432=head1 NAME
4433
4434DateTime::Format::Natural::Lang::EN - English language metadata
4435
4436=head1 DESCRIPTION
4437
4438C<DateTime::Format::Natural::Lang::EN> provides the english specific grammar
4439and variables. This class is loaded if the user either specifies the english
4440language or implicitly.
4441
4442=head1 EXAMPLES
4443
4444Below are some examples of natural language date/time input in english (be aware
4445that the parser does usually not distinguish between lower/upper case; furthermore,
4446many expressions allow for additional leading/trailing time and all times are
4447also parsable with precision in seconds):
4448
4449=head2 Simple
4450
4451 now
4452 yesterday
4453 today
4454 tomorrow
4455 morning
4456 afternoon
4457 evening
4458 noon
4459 midnight
4460 yesterday at noon
4461 yesterday at midnight
4462 today at noon
4463 today at midnight
4464 tomorrow at noon
4465 tomorrow at midnight
4466 this morning
4467 this afternoon
4468 this evening
4469 yesterday morning
4470 yesterday afternoon
4471 yesterday evening
4472 today morning
4473 today afternoon
4474 today evening
4475 tomorrow morning
4476 tomorrow afternoon
4477 tomorrow evening
4478 thursday morning
4479 thursday afternoon
4480 thursday evening
4481 6:00 yesterday
4482 6:00 today
4483 6:00 tomorrow
4484 5am yesterday
4485 5am today
4486 5am tomorrow
4487 4pm yesterday
4488 4pm today
4489 4pm tomorrow
4490 last second
4491 this second
4492 next second
4493 last minute
4494 this minute
4495 next minute
4496 last hour
4497 this hour
4498 next hour
4499 last day
4500 this day
4501 next day
4502 last week
4503 this week
4504 next week
4505 last month
4506 this month
4507 next month
4508 last quarter
4509 this quarter
4510 next quarter
4511 last year
4512 this year
4513 next year
4514 last friday
4515 this friday
4516 next friday
4517 tuesday last week
4518 tuesday this week
4519 tuesday next week
4520 last week wednesday
4521 this week wednesday
4522 next week wednesday
4523 10 seconds ago
4524 10 minutes ago
4525 10 hours ago
4526 10 days ago
4527 10 weeks ago
4528 10 months ago
4529 10 years ago
4530 in 5 seconds
4531 in 5 minutes
4532 in 5 hours
4533 in 5 days
4534 in 5 weeks
4535 in 5 months
4536 in 5 years
4537 saturday
4538 sunday 11:00
4539 yesterday at 4:00
4540 today at 4:00
4541 tomorrow at 4:00
4542 yesterday at 6:45am
4543 today at 6:45am
4544 tomorrow at 6:45am
4545 yesterday at 6:45pm
4546 today at 6:45pm
4547 tomorrow at 6:45pm
4548 yesterday at 2:32 AM
4549 today at 2:32 AM
4550 tomorrow at 2:32 AM
4551 yesterday at 2:32 PM
4552 today at 2:32 PM
4553 tomorrow at 2:32 PM
4554 yesterday 02:32
4555 today 02:32
4556 tomorrow 02:32
4557 yesterday 2:32am
4558 today 2:32am
4559 tomorrow 2:32am
4560 yesterday 2:32pm
4561 today 2:32pm
4562 tomorrow 2:32pm
4563 wednesday at 14:30
4564 wednesday at 02:30am
4565 wednesday at 02:30pm
4566 wednesday 14:30
4567 wednesday 02:30am
4568 wednesday 02:30pm
4569 friday 03:00 am
4570 friday 03:00 pm
4571 sunday at 05:00 am
4572 sunday at 05:00 pm
4573 2nd monday
4574 100th day
4575 4th february
4576 november 3rd
4577 last june
4578 next october
4579 6 am
4580 5am
4581 5:30am
4582 8 pm
4583 4pm
4584 4:20pm
4585 06:56:06 am
4586 06:56:06 pm
4587 mon 2:35
4588 1:00 sun
4589 1am sun
4590 1pm sun
4591 1:00 on sun
4592 1am on sun
4593 1pm on sun
4594 12:14 PM
4595 12:14 AM
4596
4597=head2 Complex
4598
4599 yesterday 7 seconds ago
4600 yesterday 7 minutes ago
4601 yesterday 7 hours ago
4602 yesterday 7 days ago
4603 yesterday 7 weeks ago
4604 yesterday 7 months ago
4605 yesterday 7 years ago
4606 today 5 seconds ago
4607 today 5 minutes ago
4608 today 5 hours ago
4609 today 5 days ago
4610 today 5 weeks ago
4611 today 5 months ago
4612 today 5 years ago
4613 tomorrow 3 seconds ago
4614 tomorrow 3 minutes ago
4615 tomorrow 3 hours ago
4616 tomorrow 3 days ago
4617 tomorrow 3 weeks ago
4618 tomorrow 3 months ago
4619 tomorrow 3 years ago
4620 2 seconds before now
4621 2 minutes before now
4622 2 hours before now
4623 2 days before now
4624 2 weeks before now
4625 2 months before now
4626 2 years before now
4627 4 seconds from now
4628 4 minutes from now
4629 4 hours from now
4630 4 days from now
4631 4 weeks from now
4632 4 months from now
4633 4 years from now
4634 6 in the morning
4635 4 in the afternoon
4636 9 in the evening
4637 monday 6 in the morning
4638 monday 4 in the afternoon
4639 monday 9 in the evening
4640 last sunday at 21:45
4641 monday last week
4642 6th day last week
4643 6th day this week
4644 6th day next week
4645 12th day last month
4646 12th day this month
4647 12th day next month
4648 1st day last year
4649 1st day this year
4650 1st day next year
4651 1st tuesday last november
4652 1st tuesday this november
4653 1st tuesday next november
4654 11 january next year
4655 11 january this year
4656 11 january last year
4657 6 seconds before yesterday
4658 6 minutes before yesterday
4659 6 hours before yesterday
4660 6 seconds before today
4661 6 minutes before today
4662 6 hours before today
4663 6 seconds before tomorrow
4664 6 minutes before tomorrow
4665 6 hours before tomorrow
4666 3 seconds after yesterday
4667 3 minutes after yesterday
4668 3 hours after yesterday
4669 3 seconds after today
4670 3 minutes after today
4671 3 hours after today
4672 3 seconds after tomorrow
4673 3 minutes after tomorrow
4674 3 hours after tomorrow
4675 10 seconds before noon
4676 10 minutes before noon
4677 10 hours before noon
4678 10 seconds before midnight
4679 10 minutes before midnight
4680 10 hours before midnight
4681 5 seconds after noon
4682 5 minutes after noon
4683 5 hours after noon
4684 5 seconds after midnight
4685 5 minutes after midnight
4686 5 hours after midnight
4687 noon last friday
4688 midnight last friday
4689 noon this friday
4690 midnight this friday
4691 noon next friday
4692 midnight next friday
4693 last friday at 20:00
4694 this friday at 20:00
4695 next friday at 20:00
4696 1:00 last friday
4697 1:00 this friday
4698 1:00 next friday
4699 1am last friday
4700 1am this friday
4701 1am next friday
4702 1pm last friday
4703 1pm this friday
4704 1pm next friday
4705 5 am last monday
4706 5 am this monday
4707 5 am next monday
4708 5 pm last monday
4709 5 pm this monday
4710 5 pm next monday
4711 last wednesday 7am
4712 this wednesday 7am
4713 next wednesday 7am
4714 last wednesday 7pm
4715 this wednesday 7pm
4716 next wednesday 7pm
4717 last tuesday 11 am
4718 this tuesday 11 am
4719 next tuesday 11 am
4720 last tuesday 11 pm
4721 this tuesday 11 pm
4722 next tuesday 11 pm
4723 yesterday at 13:00
4724 today at 13:00
4725 tomorrow at 13
4726 2nd friday in august
4727 3rd wednesday in november
4728 tomorrow 1 year ago
4729 saturday 3 months ago at 17:00
4730 saturday 3 months ago at 5:00am
4731 saturday 3 months ago at 5:00pm
4732 11 january 2 years ago
4733 4th day last week
4734 8th month last year
4735 8th month this year
4736 8th month next year
4737 6 mondays from now
4738 fri 3 months ago at 5am
4739 wednesday 1 month ago at 8pm
4740 final thursday in april
4741 last thursday in april
4742 beginning of last month
4743 end of last month
4744
4745=head2 Timespans
4746
4747 monday to friday
4748 1 April to 31 August
4749 1999-12-31 to tomorrow
4750 now to 2010-01-01
4751 2009-03-10 9:00 to 11:00
4752 26 oct 10:00 am to 11:00 am
4753 jan 1 to 2
4754 16:00 nov 6 to 17:00
4755 may 2nd to 5th
4756 100th day to 200th
4757 6am dec 5 to 7am
4758 30th to 31st dec
4759 30th to dec 31st
4760 21:00 to mar 3 22:00
4761 21:00 to 22:00 mar 3
4762 10th to 20th day
4763 1/3 to 2/3
4764 2/3 to in 1 week
4765 3/3 21:00 to in 5 days
4766 first day of 2009 to last day of 2009
4767 first day of may to last day of may
4768 first to last day of 2008
4769 first to last day of september
4770 for 4 seconds
4771 for 4 minutes
4772 for 4 hours
4773 for 4 days
4774 for 4 weeks
4775 for 4 months
4776 for 4 years
4777
4778=head2 Specific
4779
4780 march
4781 january 11
4782 11 january
4783 18 oct 17:00
4784 18 oct 5am
4785 18 oct 5pm
4786 18 oct 5 am
4787 18 oct 5 pm
4788 dec 25
4789 feb 28 3:00
4790 feb 28 3am
4791 feb 28 3pm
4792 feb 28 3 am
4793 feb 28 3 pm
4794 19:00 jul 1
4795 7am jul 1
4796 7pm jul 1
4797 7 am jul 1
4798 7 pm jul 1
4799 jan 24, 2011 12:00
4800 jan 24, 2011 12am
4801 jan 24, 2011 12pm
4802 may 27th
4803 2005
4804 march 1st 2009
4805 October 2006
4806 february 14, 2004
4807 jan 3 2010
4808 3 jan 2000
4809 2010 october 28
4810 2011-jan-04
4811 27/5/1979
4812 1/3
4813 1/3 16:00
4814 3/1
4815 3/1 16:00
4816 4:00
4817 17:00
4818 3:20:00
4819 -5min
4820 +2d
4821 20111018000000
4822 2016-06-19T12:12:11
4823
4824=head2 Aliases
4825
4826 1 sec ago
4827 10 secs ago
4828 1 min ago
4829 5 mins ago
4830 1 hr ago
4831 3 hrs ago
4832 1 yr ago
4833 7 yrs ago
4834 yesterday @ noon
4835 tues this week
4836 final thurs in sep
4837 tues
4838 thurs
4839 thur
4840
4841=head1 SEE ALSO
4842
4843L<DateTime::Format::Natural>
4844
4845=head1 AUTHOR
4846
4847Steven Schubiger <schubiger@cpan.org>
4848
4849=head1 LICENSE
4850
4851This program is free software; you may redistribute it and/or
4852modify it under the same terms as Perl itself.
4853
4854See L<http://dev.perl.org/licenses/>
4855
4856=cut
4857