These lines give the date and time in UTC:
t:timedate(absolute_real_time() - (10*3600));
t0:substring(t,1,20);
t1:concat(substring(t,12,17), " ", substring(t,9,11), "/", substring(t,6,8), "/", substring(t,1,5));
t2:concat(substring(t,1,5), substring(t,6,8), substring(t,9,11), substring(t,12,14), substring(t,15,17), substring(t,18,20));
I know that '?\*autoconf\-version\*;' can give the Maxima version number, so maybe there is some undocumented way to get the local time.
Otherwise are there any ready-made functions that can convert UTC time to local time given conditions for start/end of daylight saving time e.g. UTC time to UK time (which is GMT/BST depending on the time of year)?
To clarify the problem, before revealing the solution: these are the steps that I take in Maxima v5.30 to get the time in UTC, in a readable format:
Note: When I use Maxima v5.30 (in the UK), for some unknown reason, the time is always UTC adjusted by 10 hours, and does not adjust for DST.
/* 1st Jan 2017 12 noon: */
timedate(3692260800); /* "2017-01-01 22:00:00+10:00" */
timedate(3692260800-10*3600); /* "2017-01-01 12:00:00+10:00" */
substring(timedate(3692260800-10*3600),1,20); /* "2017-01-01 12:00:00" */
Note: timedate works better/differently in later versions of Maxima, but some institutions recommend installing a specific version of Maxima.
Sometimes I want the date in the form: 'yyyyMMddHHmmss'. A function for this is:
SecUTCToDate(vSec,vHour):=
block([d1,d2],
d1:timedate(vSec+vHour*3600),
d2:concat(substring(d1,1,5), substring(d1,6,8), substring(d1,9,11), substring(d1,12,14), substring(d1,15,17), substring(d1,18,20)),
parse_string(d2)
);
Note: [d1,d2]
keeps those variables local to within the block, and not global.
To get the local time I have to add on hours based on my time zone (0 in the UK), and DST. To calculate whether a time is within the DST period requires an individual function per time zone: in the UK, and many European countries, one such function is:
/* correct for the years 1900-2200 inclusive */
SecUTCIsDSTUK(vSec):=
block([vLeap,vDaysMar25,vDaysOct25,vWDayMar25,vWDayOct25,vRange1,vRange2],
vYear : parse_string(substring(timedate(vSec),1,5)),
vLeap : floor((vYear-1900)/4), if (vYear>=2100) then vLeap : vLeap-1,
vDaysMar25 : (vYear-1900)*365 + vLeap + 83,
vDaysOct25 : vDaysMar25 + 214,
vWDayMar25 : mod(vDaysMar25+1,7),
vWDayOct25 : mod(vDaysOct25+1,7),
vRange1 : (vDaysMar25+mod(-vWDayMar25,7))*86400 + 3600,
vRange2 : (vDaysOct25+mod(-vWDayOct25,7))*86400 + 3600,
if ((vSec >= vRange1) and (vSec < vRange2)) then 1 else 0);
You can create a mac file with such a function, and call up the the function when needed, e.g.:
load("C:\\MyFolder\\MyFile.mac");
SecUTCIsDSTUK(absolute_real_time());
SecUTCIsDSTUK(absolute_real_time()+86400*180);