2015-02-16 5 views
3

У меня есть переменный с датой таблицей, которая выглядит, как этотСравнение дат в Lua

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

Как получить дни между текущей датой и указанной датой? Большое спасибо!

+1

что вы имеете в виду под " дни между "? количество дней или таблиц, представляющих даты? – ryanpattison

+0

привет, количество дней, спасибо. – LFS

ответ

4

Вы можете использовать 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 отметил, может быть смещено на один день в течение нескольких секунд, так что он не идеален, но это может быть достаточно для ваших нужд.

+0

Это не особенно вероятно, но я считаю, что API-интерфейс C, используемый Lua, действительно может быть точным (например, правильно подсчитать секунды прыжка), что может привести к тому, что этот метод дает неправильные ответы в редких случаях. – bames53

1

Вы можете использовать алгоритмы собраны здесь:

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)) 
+0

Благодарю вас за помощь! – LFS

0

os.time (под Windows, по крайней мере) ограничен года с 1970 и до. Если, например, вам нужно общее решение, чтобы найти возраст в возрасте для людей, родившихся до 1970 года, это не сработает. Вы можете использовать julian date conversion и вычесть между двумя номерами (сегодня и вашей целевой датой).

Образец Функция даты юлианский, который будет работать на практически любой даты 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 
+0

спасибо! Я хочу сравнить даты с этого года. Я посмотрю на это. – LFS