local strftime = require "luatz.strftime".strftime
local strformat = string.format
local floor = math.floor
-local function idiv ( n , d )
- return floor ( n / d )
+local idiv do
+ -- Try and use actual integer division when available (Lua 5.3+)
+ local idiv_loader = (loadstring or load)([[return function(n,d) return n//d end]], "idiv") -- luacheck: ignore 113
+ if idiv_loader then
+ idiv = idiv_loader()
+ else
+ idiv = function(n, d)
+ return floor(n/d)
+ end
+ end
end
end
end
-local function year_length ( y )
- return is_leap ( y ) and 366 or 365
-end
-
local function month_length ( m , y )
if m == 2 then
return is_leap ( y ) and 29 or 28
tens = tens + idiv ( units , base )
units = units % base
elseif units < 0 then
- tens = tens - 1 + idiv ( -units , base )
- units = base - ( -units % base )
+ tens = tens + idiv ( units , base )
+ units = ( base + units ) % base
end
return tens , units
end
-- Add a whole year of days at a time, this is later resolved by adding months
-- TODO[OPTIMIZE]: This could be slow if `day` is far out of range
while day < 0 do
- year = year - 1
- day = day + year_length ( year )
+ month = month - 1
+ if month < 0 then
+ year = year - 1
+ month = 11
+ end
+ day = day + month_length ( month + 1 , year )
end
year , month = carry ( year , month , 12 )
end
function timetable_methods:rfc_3339 ( )
- -- %06.3f gives 3 (=6-3) digits after decimal
- return strformat ( "%04u-%02u-%02uT%02u:%02u:%06.3f" , self:unpack ( ) )
+ local year, month, day, hour, min, fsec = self:unpack()
+ local sec, msec = borrow(fsec, 0, 1000)
+ msec = math.floor(msec)
+ return strformat ( "%04u-%02u-%02uT%02u:%02u:%02d.%03d" , year , month , day , hour , min , sec , msec )
end
function timetable_methods:strftime ( format_string )