Lua秒格式问题

我有这个函数:

  function SecondsFormat(X)
   if X <= 0 then return "" end
   local t ={}
   local ndays = string.format("%02.f",math.floor(X / 86400))
   if tonumber(ndays) > 0 then table.insert(t,ndays.."d ") end
   local nHours = string.format("%02.f",math.floor((X/3600) -(ndays*24)))
   if tonumber(nHours) > 0 then table.insert(t,nHours.."h ") end
   local nMins = string.format("%02.f",math.floor((X/60) - (ndays * 1440) - (nHours*60)))
   if tonumber(nMins) > 0 then table.insert(t,nMins.."m ") end
   local nSecs = string.format("%02.f", math.fmod(X, 60));
   if tonumber(nSecs) > 0 then table.insert(t,nSecs.."s") end
   return table.concat(t)
  end

我想添加周和月,但无法理解月份的部分,因为月份中的天数并不总是相同的,所以是否有人能提供一些帮助?

第二个问题是,使用表存储结果是处理此项任务的最有效方法,因为该函数将每隔3秒被调用100次(在网格中为100个项目)?

编辑:

  function ADownload.ETA(Size,Done,Tranrate) --all in bytes
   if Size == nil then return "--" end
   if Done == nil then return "--" end
   if Tranrate == nil then return "--" end
   local RemS = (Size - Done) / Tranrate
   local RemS = tonumber(RemS)
   if RemS <= 0 or RemS == nil or RemS > 63072000 then return "--" end
   local date = os.date("%c",RemS)
   if date == nil then return "--" end
   local month, day, year, hour, minute, second = date:match("(%d+)/(%d+)/(%d+) (%d+): (%d+):(%d+)")
   month = month - 1
   day = day - 1
   year = year - 70
   if tonumber(year) > 0 then
   return string.format("%dy %dm %dd %dh %dm %ds", year, month, day, hour, minute, second)
   elseif tonumber(month) > 0 then
    return string.format("%dm %dd %dh %dm %ds",month, day, hour, minute, second)
   elseif tonumber(day) > 0 then
    return string.format("%dd %dh %dm %ds",day, hour, minute, second)
   elseif tonumber(hour) > 0 then
    return string.format("%dh %dm %ds",hour, minute, second)
   elseif tonumber(minute) > 0 then
    return string.format("%dm %ds",minute, second)
   else
    return string.format("%ds",second)
   end
  end

我将该函数合并到主函数中,因为我认为这可能会更快,但现在我有两个问题:

1:我必须添加

  if date == nil then return "--" end

因为它偶尔会出现与“nil”比较的日期:match错误,但是os.date在文献中没有提到返回nil,因为它是字符串或表,因此尽管额外的一行代码可以解决问题,但我想知道为什么会出现这种行为,因为我确定在之前返回中抓住了所有的非事件?

2:有时我会看到像myfunction(...)这样的函数,我确定它只是舍去了参数,如果是这样,是否有一行代码可以消除前三个“if”语句?

点赞
用户1633117
用户1633117

为什么不让 Lua 的 os 库为你做繁重的工作呢?

可能有一种更简单(更好)的方法来计算与 01/01/70 的差异,但是下面是一个快速的想法:

function SecondsFormat(X)
    if X <= 0 then return "" end
    local date = os.date("%c", X) -- 将会给出类似 "01/03/70 03:40:00" 的东西
    local inPattern = "(%d+)/(%d+)/(%d+) (%d+):(%d+):(%d+)"
    local outPattern = "%dy %dm %dd %dh %dm %ds"
    local month, day, year, hour, minute, second = date:match(inPattern)
    month = month - 1
    day = day - 1
    year = year - 70
    return string.format(outPattern, year, month, day, hour, minute, second)
end

我认为这也比构造表格并多次调用 string.format 要快得多,但你需要进行分析以确认。

编辑: 我进行了一个快速测试,使用两个函数分别使用上述两种方法连接 "abc""def""ghi"。将这些字符串插入表格并连接需要 14 秒(当然是进行了数百万次运行),而使用单个 string.format() 需要 6 秒。这并未考虑到你的代码已经调用了多次 string.format() 的差异 - 以及我通过模式匹配计算值和你通过除法计算值之间的区别。模式匹配的速度肯定会慢一些,但我怀疑这并不会超过没有表格带来的收益 - 而能够利用 os.time() 显然很方便。最快的方法可能是手动确定月份和日期,然后使用单个 string.format()。但是,你需要进行分析以确认。

编辑2: missingno 已经提到可以使用 os.date"*t" 选项将值分别给出。这再次取决于是否想要通过表格的便利性,还是出于存储或其他原因而使用字符串。结合 "*t" 和单个 string.format

function SecondsFormat(X)
    if X <= 0 then return "" end
    local date = os.date("*t", X) -- 将会给你一个表
    local outPattern = "%dy %dm %dd %dh %dm %ds"
    date.month = date.month - 1
    date.day = date.day - 1
    date.year = date.year - 70
    return string.format(outPattern, date.year, date.month, date.day, date.hour, date.min, date.sec)
end
2013-03-11 01:45:30
用户90511
用户90511

你可以使用 os.date 函数获取可用格式的日期值。'*t' 格式化参数将返回的日期转换成表格而不是字符串。

local t = os.date('*t')
print(t.year, t.month, t.day, t.hour, t.min, t.sec)
print(t.wday, t.yday)

os.date 默认使用当前时间,如果你想要,你可以传递一个显式时间(请查看 os.date 的文档以获取更多信息)

local t = os.date('*t', x)

至于表格性能,我不会担心。不仅你的函数不经常被调用,而且表格处理比你可能正在做的其他事情(调用 os.date,大量字符串格式化等)更便宜。

2013-03-11 01:54:04