All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 local strformat = string.format
2 local floor = math.floor
3 local function idiv(n, d)
8 abday = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
9 day = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
10 abmon = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
11 mon = {"January", "February", "March", "April", "May", "June",
12 "July", "August", "September", "October", "November", "December"};
16 --- ISO-8601 week logic
17 -- ISO 8601 weekday as number with Monday as 1 (1-7)
18 local function iso_8601_weekday(wday)
25 local iso_8601_week do
26 -- Years that have 53 weeks according to ISO-8601
29 4, 9, 15, 20, 26, 32, 37, 43, 48, 54, 60, 65, 71, 76, 82,
30 88, 93, 99, 105, 111, 116, 122, 128, 133, 139, 144, 150, 156, 161, 167,
31 172, 178, 184, 189, 195, 201, 207, 212, 218, 224, 229, 235, 240, 246, 252,
32 257, 263, 268, 274, 280, 285, 291, 296, 303, 308, 314, 320, 325, 331, 336,
33 342, 348, 353, 359, 364, 370, 376, 381, 387, 392, 398
37 local function is_long_year(year)
38 return long_years[year % 400]
40 function iso_8601_week(self)
41 local wday = iso_8601_weekday(self.wday)
42 local n = self.yday - wday
43 local year = self.year
46 if is_long_year(year) then
51 elseif n >= 361 and not is_long_year(year) then
52 return year + 1, 1, wday
54 return year, idiv(n + 10, 7), wday
62 return "%s", locale.abday[self.wday]
65 return "%s", locale.day[self.wday]
68 return "%s", locale.abmon[self.month]
71 return "%s", locale.mon[self.month]
74 return "%.3s %.3s%3d %.2d:%.2d:%.2d %d",
75 locale.abday[self.wday], locale.abmon[self.month],
76 self.day, self.hour, self.min, self.sec, self.year
80 return "%02d", idiv(self.year, 100)
83 return "%02d", self.day
85 -- Short MM/DD/YY date, equivalent to %m/%d/%y
87 return "%02d/%02d/%02d", self.month, self.day, self.year % 100
90 return "%2d", self.day
92 -- Short YYYY-MM-DD date, equivalent to %Y-%m-%d
94 return "%d-%02d-%02d", self.year, self.month, self.day
96 -- Week-based year, last two digits (00-99)
98 return "%02d", iso_8601_week(self) % 100
102 return "%d", iso_8601_week(self)
106 return "%02d", self.hour
109 return "%02d", (self.hour-1) % 12 + 1
112 return "%03d", self.yday
115 return "%02d", self.month
118 return "%02d", self.min
120 -- New-line character ('\n')
121 function t:n() -- luacheck: ignore 212
125 return self.hour < 12 and locale.am_pm[1] or locale.am_pm[2]
127 -- TODO: should respect locale
129 return "%02d:%02d:%02d %s",
130 (self.hour-1) % 12 + 1, self.min, self.sec,
131 self.hour < 12 and locale.am_pm[1] or locale.am_pm[2]
133 -- 24-hour HH:MM time, equivalent to %H:%M
135 return "%02d:%02d", self.hour, self.min
138 return "%d", self:timestamp()
141 return "%02d", self.sec
143 -- Horizontal-tab character ('\t')
144 function t:t() -- luacheck: ignore 212
147 -- ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S
149 return "%02d:%02d:%02d", self.hour, self.min, self.sec
152 return "%d", iso_8601_weekday(self.wday)
154 -- Week number with the first Sunday as the first day of week one (00-53)
156 return "%02d", idiv(self.yday - self.wday + 7, 7)
158 -- ISO 8601 week number (00-53)
160 return "%02d", select(2, iso_8601_week(self))
162 -- Weekday as a decimal number with Sunday as 0 (0-6)
164 return "%d", self.wday - 1
166 -- Week number with the first Monday as the first day of week one (00-53)
168 return "%02d", idiv(self.yday - iso_8601_weekday(self.wday) + 7, 7)
170 -- TODO make t.x and t.X respect locale
174 return "%02d", self.year % 100
177 return "%d", self.year
180 function t:z() -- luacheck: ignore 212
183 function t:Z() -- luacheck: ignore 212
186 -- A literal '%' character.
187 t["%"] = function(self) -- luacheck: ignore 212
191 local function strftime(format_string, timetable)
192 return (string.gsub(format_string, "%%([EO]?)(.)", function(locale_modifier, specifier)
193 local func = t[specifier]
195 return strformat(func(timetable, c_locale))
197 error("invalid conversation specifier '%"..locale_modifier..specifier.."'", 3)
202 local function asctime(timetable)
203 -- Equivalent to the format string "%c\n"
204 return strformat(t.c(timetable, c_locale)) .. "\n"