Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting DateTime format to another DateTime Format in Lua

I have an issue where a date value is used to send to an application for some processing that needs to first be formatted to a different DateTime format.

What I have

I start with a DateTime value in the format of:

  • MM/DD/YYYY hh:mm:ss [AM/PM]

What I need

Somehow with Lua I need to transform this into the DateTime format of:

  • YYYY-MM-DD hh:mm:ss

I've had no luck with many various things I've tried; I'll post the thing I tried I feel may be most appropriate but maybe this is way off too and there's an easier or more simple LUA method.

What I tried

print(os.date("%Y-%m-%d %H:%M:%S","05/17/2017 05:17:00 PM"))

Error

stdin:1: bad argument #2 to 'date'(number expected, got string)

What I'm assuming

I think this means the data type is a string rather than a datetime type and it'll need to convert it before os.date can use it. I'm also assuming I can pass the value of the datetime string I have to os.date and it will output this same datetime value wise but in the new format I need instead.

I've read various posts about needing to parse out the parts of the datetime value and then using those parsed out portions to build the format you need. I'm posting in hopes someone can help steer me in the proper direction with this task so I don't have to go thru a ton more trial and error runs and do a ton more reading but I'll be doing that until I hear back or give up for the day.

Simple Recap

  • I start with a value of: 05/17/2017 05:17:00 PM

  • I would like to get this value to 2017-05-17 17:17:00

With the newly formatted datetime, I can then do something with it for the application to process.

Other

Any level of Lua logic to resolve this will be explored whether it be a custom function, different built-in functions to get the datetime formatted, etc. I'm open to all ideas and just showed the print() and os.date() functions in my example to keep it simple but I'm open to something more complex.

like image 341
Bitcoin Murderous Maniac Avatar asked May 17 '17 22:05

Bitcoin Murderous Maniac


2 Answers

Unlike other languages, Lua doesn't have a DateTime type; dates and times are represented in Lua through strings, numbers, and tables of strings and numbers. A consequence of this is that there are many ways of working with dates in Lua, and the best one to use depends on your situation.

The error you got from os.date is because the second argument should be a number in Unix time (the number of seconds since 1 January 1970). For this to work in your case, you need to convert your timestamp to Unix time using the os.time function. However, os.time needs a table of numbers as input, so it is up to you to do the actual date parsing and find the numbers from your date string.

However, in your case, your input is a string, and your desired output is a similar string, so you can get by with just doing the date parsing and not converting the result with os.date and os.time. This is what @tonypdmtr does with string.gsub in his answer. Here is how to do something very similar, using string.match and string.format:

local date = '05/17/2017 05:17:00 PM'
local month, day, year, hours, minutes, seconds, amPm = date:match('^(%d%d)/(%d%d)/(%d%d%d%d) (%d%d):(%d%d):(%d%d) ([AP]M)$')
if not month then
    -- Our entire match failed, and no captures were made
    error('could not parse date "' .. date .. '"')
end
if amPm == 'PM' then
    hours = string.format('%2d', tonumber(hours) + 12)
end
local newDate = string.format(
    '%s-%s-%s %s:%s:%s',
    year, month, day, hours, minutes, seconds
)
print(newDate) -- 2017-05-17 17:17:00
like image 67
Jack Taylor Avatar answered Sep 30 '22 09:09

Jack Taylor


You can always use :gsub to do whatever transformation you want.

a ='05/17/2017 05:17:00 PM'

b = a:gsub('(%d%d)/(%d%d)/(%d%d%d%d) (%d%d)(:%d%d:%d%d) ([AP]M)',
      function(a,b,c,d,e,am_pm)
        return c .. '-' .. a .. '-' .. b .. ' ' ..
               (am_pm == 'AM' and d or ('%2d'):format(d+12)) .. e
      end)

print(a)
print(b)
like image 31
tonypdmtr Avatar answered Sep 30 '22 10:09

tonypdmtr