【问题标题】:Compare dates in Lua比较 Lua 中的日期
【发布时间】:2015-04-17 11:51:54
【问题描述】:

我有一个带有如下日期表的变量

* table:
 [day]
  * number: 15
 [year]
  * number: 2015
 [month]
  * number: 2

如何获取当前日期与上述日期之间的天数?非常感谢!

【问题讨论】:

  • 您所说的“间隔天数”是什么意思?天数还是代表日期的表格?
  • 嗨,天数,谢谢。

标签: date lua comparison


【解决方案1】:

您可以使用os.time() 将表格转换为秒并获取当前时间,然后使用os.difftime() 计算差异。有关详细信息,请参阅Lua Wiki

reference = os.time{day=15, year=2015, month=2}
daysfrom = os.difftime(os.time(), reference) / (24 * 60 * 60) -- seconds in a day
wholedays = math.floor(daysfrom)
print(wholedays) -- today it prints "1"

正如@barnes53 指出的那样,可能会关闭一天几秒钟,所以这并不理想,但它可能足以满足您的需求。

【讨论】:

  • 这不是特别可能,但我相信 Lua 使用的 C 时间 API 可能实际上是准确的(例如,正确计算闰秒),这可能会导致此方法在极少数情况下给出错误答案.
【解决方案2】:

您可以使用此处收集的算法:

chrono-Compatible Low-Level Date Algorithms

这些算法使用 C++ 显示,但如果您愿意,可以在 Lua 中轻松实现它们,或者您可以在 C 或 C++ 中实现它们,然后提供 Lua 绑定。

使用这些算法的基本思想是计算两个日期的天数,然后将它们相减得到天数。


--[[
 http://howardhinnant.github.io/date_algorithms.html

 Returns number of days since civil 1970-01-01.  Negative values indicate
    days prior to 1970-01-01.
 Preconditions:  y-m-d represents a date in the civil (Gregorian) calendar
                 m is in [1, 12]
                 d is in [1, last_day_of_month(y, m)]
                 y is "approximately" in
                   [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
                 Exact range of validity is:
                 [civil_from_days(numeric_limits<Int>::min()),
                  civil_from_days(numeric_limits<Int>::max()-719468)]
]]
function days_from_civil(y, m, d)
    if m <= 2 then
      y = y - 1
      m = m + 9
    else
      m = m - 3
    end
    local era = math.floor(y/400)
    local yoe = y - era * 400                                           -- [0, 399]
    local doy = math.modf((153*m + 2)/5) + d-1                          -- [0, 365]
    local doe = yoe * 365 + math.modf(yoe/4) - math.modf(yoe/100) + doy -- [0, 146096]
    return era * 146097 + doe - 719468
end

local reference_date = {year=2001, month = 1, day = 1}
local date = os.date("*t")

local reference_days = days_from_civil(reference_date.year, reference_date.month, reference_date.day)
local days = days_from_civil(date.year, date.month, date.day)

print(string.format("Today is %d days into the 21st century.",days-reference_days))

【讨论】:

    【解决方案3】:

    os.time(至少在 Windows 下)仅限于 1970 年及以后的年份。例如,如果您需要一个通用解决方案来查找 1970 年之前出生的人的年龄(天数),这将不起作用。您可以使用儒略日期转换并减去两个数字(今天和您的目标日期)。

    下面给出了一个示例 julian 日期函数,它几乎适用于任何日期 AD(Lua v5.3 因为 // 但你可以适应早期版本):

    local
    function div(n,d)
      local a, b = 1, 1
      if n < 0 then a = -1 end
      if d < 0 then b = -1 end
      return a * b * (math.abs(n) // math.abs(d))
    end
    
    --------------------------------------------------------------------------------
    -- Convert a YYMMDD date to Julian since 1/1/1900 (negative answer possible)
    --------------------------------------------------------------------------------
    
    function julian(year, month, day)
      local temp
    
      if (year < 0) or (month < 1) or (month > 12)
                    or (day < 1) or (day > 31) then
        return
      end
      temp = div(month - 14, 12)
      return (
             day - 32075 +
             div(1461 * (year + 4800 + temp), 4) +
             div(367 * (month - 2 - temp * 12), 12) -
             div(3 * div(year + 4900 + temp, 100), 4)
             ) - 2415021
    end
    

    【讨论】:

    • 谢谢!我希望比较从今年开始的日期。我会看看这个。
    猜你喜欢
    • 1970-01-01
    • 2011-12-31
    • 2018-11-24
    • 2022-11-18
    • 1970-01-01
    • 2017-01-19
    • 2011-06-27
    • 2012-12-13
    • 2012-01-03
    相关资源
    最近更新 更多