Search code examples
lua

add days to given timestamp (YYYY-mm-dd HH:MM:SS.sss) in lua script


Summary

I would like to add 1 day to given timestamp in lua script.

My try

local creation_date = "2016-01-01 00:00:00.000" 

local y, m, d, Hr, Min, Sec, Milli = creation_date:match '(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+).(%d+)'

local dt = y .. '-' .. m .. '-'..d.. ' '..Hr..':'..Min..'-'..Sec..'.'..Milli
print(dt)

local new_ts = os.time
    { year = y, month = m, day = d,
      hour = Hr, min = Min, sec = Sec, mill=Milli } + 1*24*60*60
  
print(new_ts)

I am getting new_ts = 1452470400

Expected result

2016-01-01 00:01:00.000 (in this format only)


Solution

  • The closest you may be able to get is something like this:

    local creation_date = "2016-01-01 00:00:00.000"
    
    local y, m, d, Hr, Min, Sec, Milli = creation_date:match '(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+).(%d+)'
    
    local dt = y .. '-' .. m .. '-'..d.. ' '..Hr..':'..Min..'-'..Sec..'.'..Milli
    print(dt)
    
    local new_ts = os.time { year = y, month = m, day = d, hour = Hr, min = Min, sec = Sec } + 1*24*60*60
    
    print(string.format("%s.%03d", os.date("%Y-%m-%d %H:%M:%S", new_ts), Milli))
    

    The Mill entry in the table that you pass on to os.time() is being ignored, and the resulting value doesn't provide millisecond precision, so there's no point in including it. To get the format you desire, you need os.date() with an appropriate format, and then you can append the milliseconds to that again, manually.

    With that, it looks like this:

    $ lua script.lua
    2016-01-01 00:00-00.000
    2016-01-02 00:00:00.000
    

    With the suggestion from @Nifim it can be simplified further, confirmed by the documentation

    When the function is called, the values in these fields do not need to be inside their valid ranges. For instance, if sec is -10, it means 10 seconds before the time specified by the other fields; if hour is 1000, it means 1000 hours after the time specified by the other fields. - Lua 5.4 Reference Manual: os.time

    local creation_date = "2016-01-31 00:00:00.000"
    
    local y, m, d, Hr, Min, Sec, Milli = creation_date:match '(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+).(%d+)'
    
    local dt = y .. '-' .. m .. '-'..d.. ' '..Hr..':'..Min..'-'..Sec..'.'..Milli
    print(dt)
    
    local new_ts = os.time { year = y, month = m, day = d + 1, hour = Hr, min = Min, sec = Sec }
    
    print(string.format("%s.%03d", os.date("%Y-%m-%d %H:%M:%S", new_ts), Milli))
    

    Output:

    $ lua script.lua
    2016-01-31 00:00-00.000
    2016-02-01 00:00:00.000