os.date and %# not working

Posted by Balana on Sun 22 Apr 2007 09:57 PM — 7 posts, 23,904 views.

#0
I'm attempting to create an alias I can type that automatically creates a logfile and starts logging. (I want to be able to start logging when I start a RP without it logging everything.) Logging starts okay, the problem is just in the header (which I'm setting as the variable 'worldinfo')

<aliases>
  <alias
   match="start log"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>local worldinfo = GetInfo(2).." - "..os.date('%#x, %#I:%M %p')
local linelength
OpenLog(GetInfo(58)..[[Nabana\]]..os.date("%Y")..[[\]]..os.date("%m %d".."-r.txt"),true)
WriteLog(worldinfo)
linelength = string.len(worldinfo)
WriteLog(string.rep("-",linelength))
WriteLog()</send>
  </alias>
</aliases>


Here's what that header comes out as:

TLK Nabana - x, I:45 PM
-----------------------

I know I could also use '%A, %B %d, %Y' in place of %#x, and that works alright, but to my knowledge there's not an alternative for %#I (the hour without the leading 0). Am I doing something wrong, or is there a problem somewhere? (I'm using v 4.05 of MUSHclient.)
Amended on Sun 22 Apr 2007 10:19 PM by Balana
Australia Forum Administrator #1
Inside "send to script" the %x already has a meaning, which is wildcard x, e.g.

%1 --> wildcard 1

So, if you want to use % inside something like os.date you have to double it, so that MUSHclient replaces %% by %, which should then work as you expect.

eg.



os.date('%%#x, %%#I:%%M %%p')

#2
I changed all of the % to %% just in case, but I was having no trouble with it saving to the correct place and coming up with the correct header for everything else. (%M and %p and such were printing as expected.)

At any rate, I gave os.date('%%#x, %%#I:%%M %%p') a try--same problem. Anything without a # works fine, but %%#x and %%#I don't seem to be evaluating.
Australia Forum Administrator #3
It appears that the documentation is wrong about the effect of the "#" modifier. I think that used to be correct but the behaviour of the underlying runtime library has changed, or possibly, I was wrong all along. :)

You will need to work around it a different way. Here is one possibility:


t = os.date ("*t")

print (t.hour)  --> 9
print (t.min)   --> 20 
print (t.sec)   --> 22


You can incorporate the various parts of the date into your filename (eg. by concatenating, or using string.format).
#4
Ah, okay. :) The only problem with using os.date as a table is that it gives the hour in 24-hour format. Ultimately I found a workaround:

local hourz
if string.byte (os.date('%%I'), 1)==49 then hourz = os.date('%%I') else hourz = string.gsub(os.date('%%I'),"0",'',1) end

Basically it looks at the first number of the hour and if it's 1 it takes it, and otherwise it strips out the leading 0. I had to check for the first number so it didn't strip out the 0 in 10. When I want to use it, I just use the variable hourz. Thanks a lot for the clarification!
Australia Forum Administrator #5
Quote:

The only problem with using os.date as a table is that it gives the hour in 24-hour format.


You could always do this:


if t.hour > 12 then
  t.hour = t.hour - 12  -- 13:00 becomes 01:00 (p.m.)
elseif t.hour < 1 then
  t.hour = t.hour + 12  -- 00:00 becomes 12:00 (a.m.)
end 


Quote:

local hourz
if string.byte (os.date('%%I'), 1)==49 then hourz = os.date('%%I') else hourz = string.gsub(os.date('%%I'),"0",'',1) end


This looks too complicated for me. How about:


local hour = tonumber (os.date('%%I'))


Now, if the hour was "09" it gets converted into a number which, if you print it, comes out just as "9".




I think I have found why the function is not working as documented. The documentation for os.date says it works "like the C function strftime" - so I looked that up in the MSDN (Microsoft) documentation.

However it seems that the "%#I" feature is a Microsoft extension. Later on I recompiled the DLL under Cygwin, which gave a faster result (testing a big computation). However the runtime library that comes with Cygwin doesn't support the "#" option it seems.

On top of that, Lua 5.1.2 changed the way os.date worked internally so it would not process any modifying option. Thus it didn't recognise any 3-character sequences at all.

I have raised this issue with the Lua developers.
Amended on Mon 23 Apr 2007 04:02 AM by Nick Gammon
Australia Forum Administrator #6
The Lua developers have responded that they are only supporting the C89 specifiers. A quick search reveals that these seem to be:


%a  Abbreviated weekday name    
%A  Full weekday name   
%b  Abbreviated name of the month   
%B  Full name of the month  
%c  Standard date and time string   
%d  Day of the month as a number  [01-31]
%H  24 hour clock   [00-23]
%I  12 hour clock   [01-12]
%j  Day of the year as a number   [001-366]
%m  Month of the year as a number   [01-12]
%M  Minute of an hour as a number   [00-59]
%p  AM or PM  
%S  Second of a minute as a number  [00-61]
%U  Week of the year as a number (Sunday being the first day of week 1)   [00-53]
%w  Weekday as a number (Sunday being the first day)  [0-6]
%W  Week of the year as a number (Monday being the first day of week 1)   [00-53]
%x  Standard date string ( locale date)   
%X  Standard time string ( locale date)   
%y  Year in numbers (excluding century)   [00-99]
%Y  Year in numbers (including century)   [1900-1999]
%Z  Name of Time zone (if one exists)   
%%  The percent sign


I have updated the documentation which will be shipped in the next version to reflect this.