Home > OS >  get all os.date tags as table in lua
get all os.date tags as table in lua

Time:10-22

os.date("!*t") in lua return a table like this:

year    a full year
month   01-12
day 01-31
hour    00-23
min 00-59
sec 00-59
isdst   a boolean, true if daylight saving

But we have some variable that not present in this table like timezone, start week etc... We can get them by os.date(%z %p), but is there any way to get a more complete version of the above table with os.date or any other internal library?

I want just run one time os.date() inside my code, and avoid running that for second time to get ‍‍‍‍os.date(%z %p) is there any way to get a complete table of all available tags?

Base of lua document avilabel tag is

%a  abbreviated weekday name (e.g., Wed)
%A  full weekday name (e.g., Wednesday)
%b  abbreviated month name (e.g., Sep)
%B  full month name (e.g., September)
%c  date and time (e.g., 09/16/98 23:48:10)
%d  day of the month (16) [01-31]
%H  hour, using a 24-hour clock (23) [00-23]
%I  hour, using a 12-hour clock (11) [01-12]
%M  minute (48) [00-59]
%m  month (09) [01-12]
%p  either "am" or "pm" (pm)
%S  second (10) [00-61]
%w  weekday (3) [0-6 = Sunday-Saturday]
%x  date (e.g., 09/16/98)
%X  time (e.g., 23:48:10)
%Y  full year (1998)
%y  two-digit year (98) [00-99]
%%  the character `%´

CodePudding user response:

From Lua 5.4 Reference Manual: os.date:

If format starts with '!', then the date is formatted in Coordinated Universal Time. After this optional character, if format is the string "*t", then date returns a table with the following fields: year, month (1–12), day (1–31), hour (0–23), min (0–59), sec (0–61, due to leap seconds), wday (weekday, 1–7, Sunday is 1), yday (day of the year, 1–366), and isdst (daylight saving flag, a boolean). This last field may be absent if the information is not available.

If you want the table to contain more fields, you need to implement this yourself.

CodePudding user response:

Lua is ANSI C compatible.

That means Lua does not provide access to extra struct tm fields from glibc in it's standard lib (see https://man7.org/linux/man-pages/man3/ctime.3.html#NOTES)

If you want to utilize these extra struct tm glibc fields:

long tm_gmtoff;           /* Seconds east of UTC */
const char *tm_zone;      /* Timezone abbreviation */

Then, as @Piglet already mentioned, You'll need to implement it yourself.

You can either patch an original Lua source here: https://github.com/lua/lua/blob/master/loslib.c#L230 (which is a bad decision in general), or you can write your own glibc-dependent lua c module, which is way better.

CodePudding user response:

As mentioned before 'If you want the table to contain more fields, you need to implement this yourself.'

And i love Lua for that.
Its so easy...

> dtable = setmetatable(os.date('!*t'), {__call = function(self) self.tz=os.date('%z') self.ampam = os.date('%p') return self end})
> dir = function(tab) for k, v in pairs(tab) do print(k, '=>', v) end end
> dir(dtable)
wday    =>  6
yday    =>  294
hour    =>  19
isdst   =>  false
day =>  21
sec =>  22
month   =>  10
min =>  3
year    =>  2022
> dir(dtable())
wday    =>  6
ampam   =>  PM
tz  =>   0200
yday    =>  294
hour    =>  19
isdst   =>  false
day =>  21
sec =>  22
month   =>  10
min =>  3
year    =>  2022

So after above check/control a simple...

dtable = setmetatable(os.date('!*t'), {__call = function(self) self.tz=os.date('%z') self.ampam = os.date('%p') return self end})
dtable = dtable()

...extend the table.

Tip: Ever tried os.setlocale()?

> os.setlocale('de_DE.utf8','time')
de_DE.utf8
> dir(dtable())
wday    =>  6
ampam   =>  
tz  =>   0200
yday    =>  294
hour    =>  19
isdst   =>  false
day =>  21
sec =>  22
month   =>  10
min =>  3
year    =>  2022
> os.setlocale('ja_JP.utf8','time')
ja_JP.utf8
> dir(dtable())
wday    =>  6
ampam   =>  午後
tz  =>   0200
yday    =>  294
hour    =>  19
isdst   =>  false
day =>  21
sec =>  22
month   =>  10
min =>  3
year    =>  2022

...it is worth as argument for the __call metamethod...

__call = function(self, locale)
local locale = locale or 'en_US.utf8'
os.setlocale(locale, 'time')
self.tz = os.date('%z')
self.ampam = os.date('%p')
return self
end

And with a more extended dtable.lua and dir.lua you can do like...

dir(dtable('de_DE.utf8'))
1   z (string) =>  0200 (string) 5 byte
2   B (string) => Oktober (string) 7 byte
3   b (string) => Okt (string) 3 byte
4   hour (string) => 20 (number) integer
5   A (string) => Freitag (string) 7 byte
6   month (string) => 10 (number) integer
7   isdst (string) => false (boolean)
8   min (string) => 29 (number) integer
9   p (string) =>  (string) 0 byte
10  sec (string) => 52 (number) integer
11  a (string) => Fr (string) 2 byte
12  day (string) => 21 (number) integer
13  year (string) => 2022 (number) integer
14  yday (string) => 294 (number) integer
15  wday (string) => 6 (number) integer
> dir(dtable('ja_JP.utf8'))
1   z (string) =>  0200 (string) 5 byte
2   B (string) => 10月 (string) 5 byte
3   b (string) => 10月 (string) 5 byte
4   hour (string) => 20 (number) integer
5   A (string) => 金曜日 (string) 9 byte
6   month (string) => 10 (number) integer
7   isdst (string) => false (boolean)
8   min (string) => 29 (number) integer
9   p (string) => 午後 (string) 6 byte
10  sec (string) => 52 (number) integer
11  a (string) => 金 (string) 3 byte
12  day (string) => 21 (number) integer
13  year (string) => 2022 (number) integer
14  yday (string) => 294 (number) integer
15  wday (string) => 6 (number) integer
  • Related