# CmpDay.pm compare weekday names, find name order 24jul22waw package CmpDay; use strict; use warnings; # use Data::Dump qw(dd); # for debug # prepare weekdays string for weekday substring indexing. # # this trick depends on the fact that each "short" day name # is a left-anchored substring of the corresponding "long" name. # this allows recognition of some wider variations in day names, # e.g., tu/tue/tues for tuesday and th/thu/thur/thurs for thursday. # # unfortunately, it also allows some false positives like 'm' or 'mond' # for monday (which may or may not be a false positive in your # application - YMMV). # # this trick also works for month names, e.g., jan/january, etc. # long day names in canonical form (e.g., case) and in week-order # per the C tm struct. my @long_names = qw(sunday monday tuesday wednesday thursday friday saturday); # this character or multi-character sequence is used as the left-anchor # of day names for searching via the index() built-in. # this character or multi-character sequence must not appear in any name. my $left_anchor = "\n"; # must not appear in any name sub canonicalize_name { return "$left_anchor\L$_[0]"; } # string for short/long name substring indexing my $wd = join '', map canonicalize_name($_), '', @long_names; # ^ # | # extra empty string in first position -+ # allows day_to_i() to evaluate to + # undef for an empty string 'name' -+ # dd '$wd', $wd; # for debug # per struct tm: tm_wday, days since Sunday, 0-6 my %day_indices = map { index($wd, canonicalize_name($long_names[$_])) => $_ } 0 .. $#long_names ; # dd '%day_indices', \%day_indices; # for debug sub day_to_i { return $day_indices{index $wd, canonicalize_name($_[0])}; } sub i_to_day { return $long_names[$_[0]]; } 1;