This commit is contained in:
John Alanbrook 2023-12-10 04:09:15 +00:00
parent cb0fa34743
commit 5ad3219379
5 changed files with 303 additions and 12 deletions

View file

@ -23,6 +23,243 @@ Promise = undefined;
Set = undefined; Set = undefined;
WeakSet = undefined; WeakSet = undefined;
var fmt = {};
var timeparse = {
yyyy: "year",
mm: "month",
m: "month",
eee: "yday",
dd: "day",
d: "day",
v: "weekday",
hh: "hour",
h: "hour",
nn: "minute",
n: "minute",
ss: "second",
s: "second",
};
String.parse = function(str, p)
{
var rec = {};
var fmts = Object.keys(p).sort(function(a,b) { return a.length > b.length; });
}
/* Time values are always expressed in terms of real earth-seconds */
var time = {
get hour2minute() { return this.hour/this.minute; },
get day2hour() { return this.day/this.hour; },
get minute2second() { return this.minute/this.second; },
get week2day() { return this.week/this.day; },
};
time.second = 1; /* earth-seconds in a second */
time.minute = 60; /* seconds in a minute */
time.hour = 3_600; /* seconds in an hour */
time.day = 86_400; /* seconds in a day */
time.week = 604_800; /* seconds in a week */
time.weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
time.monthstr = ["January", "February", "March", 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
time.epoch = 1970; /* Times are expressed in terms of day 0 at hms 0 of this year */
time.now = function() { return cmd(210);}
time.computer_zone = function() { return cmd(211)/this.hour; }
time.computer_dst = function() { return cmd(212); }
time.isleap = function(year) { return this.yearsize(year) === 366; }
time.isleap.doc = "Return true if the given year is a leapyear.";
time.yearsize = function(y) {
if (y%4 === 0 && (y%100 != 0 || y%400 === 0))
return 366;
return 365;
}
time.yearsize.doc = "Given a year, return the number of days in that year.";
time.monthdays = [31,28,31,30,31,30,31,31,30,31,30,31];
time.zones = {};
time.zones['-12'] = 'IDLW';
time.record = function(num, zone)
{
if (typeof num === 'object') return num;
else if (typeof num === 'number') {
zone ??= this.computer_zone();
var monthdays = this.monthdays.slice();
var rec = {
second: 0,
minute: 0,
hour: 0,
yday: 0,
year: 0,
zone: 0
};
rec.zone = zone;
num += zone*this.hour;
var hms = num % this.day;
var day = parseInt(num/this.day);
if (hms < 0) {
hms += this.day;
day--;
}
rec.second = hms%this.minute;
var d1 = Math.floor(hms/this.minute);
rec.minute = d1 % this.minute;
rec.hour = Math.floor(d1/this.minute);
/* addend%7 is 4 */
rec.weekday = (day + 4503599627370496+2)%7;
var d1 = this.epoch;
if (day >= 0)
for (d1= this.epoch; day >= this.yearsize(d1); d1++)
day -= this.yearsize(d1);
else
for (d1 = this.epoch; day < 0; d1--)
day += this.yearsize(d1-1);
rec.year = d1;
if (rec.year <= 0)
rec.ce = 'BC';
else
rec.ce = 'AD';
rec.yday = day;
if (this.yearsize(d1) === 366)
monthdays[1] = 29;
var d0 = day;
for (d1 = 0; d0 >= monthdays[d1]; d1++)
d0 -= monthdays[d1];
monthdays[1] = 28;
rec.day = d0 + 1;
rec.month = d1;
return rec;
}
}
time.number = function(rec)
{
if (typeof rec === 'number')
return rec;
else if (typeof rec === 'object') {
var c = 0;
var year = rec.year ? rec.year : 0;
var hour = rec.hour ? rec.hour : 0;
var minute = rec.minute ? rec.minute : 0;
var second = rec.second ? rec.second : 0;
var zone = rec.zone ? rec.zone : 0;
if (year > this.epoch)
for (var i = this.epoch; i < year; i++)
c += this.day*this.yearsize(i);
else if (year < this.epoch) {
for (var i = this.epoch-1; i > year; i--)
c += this.day*this.yearsize(i);
c += (this.yearsize(year)-yday-1)*this.day;
c += (this.day2hour-hour-1)*this.hour;
c += (this.hour2minute-minute-1)*this.minute;
c += (this.minute2second-second);
c += zone*this.hour;
c *= -1;
return c;
}
c += second;
c += minute * this.minute;
c += hour * this.hour;
c += yday * this.day;
c -= zone * this.hour;
return c;
}
}
/* Time formatting
yyyy - year in a 4 digit field
y - as many digits as necessary
mm - month (1-12)
mB - month name
mb - abbreviated month name
dd - day (1-31)
d
c - if the year is <= 0, BC. Otherwise, AD.
hh - hour
h
nn - minutes
n
ss - seconds
s
v - day of the week (0-6)
vB - weekday name
vb - abbreviated weekday name
a - am/pm
z - zone, -12 to +11
*/
time.fmt = "vB mB d h:nn:ss TZz a y c";
/* If num is a number, converts to a rec first. */
time.text = function(num, fmt, zone)
{
fmt ??= this.fmt;
var rec = num;
if (typeof rec === 'number')
rec = time.record(num, zone);
zone = rec.zone;
if (fmt.match('a')) {
if (rec.hour >= 13) {
rec.hour -= 12;
fmt = fmt.replaceAll('a', 'PM');
} else if (rec.hour === 12)
fmt = fmt.replaceAll('a', 'PM');
else if (rec.hour === 0) {
rec.hour = 12;
fmt = fmt.replaceAll('a', 'AM');
} else
fmt = fmt.replaceAll('a', 'AM');
}
var year = rec.year > 0 ? rec.year : rec.year - 1;
if (fmt.match('c')) {
if (year < 0) {
year = Math.abs(year);
fmt = fmt.replaceAll('c', 'BC');
} else
fmt = fmt.replaceAll('c', 'AD');
}
fmt = fmt.replaceAll('yyyy', year.toString().padStart(4,'0'));
fmt = fmt.replaceAll('y', year);
fmt = fmt.replaceAll('eee', rec.yday+1);
fmt = fmt.replaceAll('dd', rec.day.toString().padStart(2,'0'));
fmt = fmt.replaceAll('d', rec.day);
fmt = fmt.replaceAll('hh', rec.hour.toString().padStart(2,'0'));
fmt = fmt.replaceAll('h', rec.hour);
fmt = fmt.replaceAll('nn', rec.minute.toString().padStart(2,'0'));
fmt = fmt.replaceAll('n', rec.minute);
fmt = fmt.replaceAll('ss', rec.second.toString().padStart(2, '0'));
fmt = fmt.replaceAll('s', rec.second);
fmt = fmt.replaceAll('z', zone >= 0 ? "+" + zone : zone);
fmt = fmt.replaceAll(/mm[^bB]/g, rec.month+1);
fmt = fmt.replaceAll(/m[^bB]/g, rec.month+1);
fmt = fmt.replaceAll(/v[^bB]/g, rec.weekday);
fmt = fmt.replaceAll('mb', this.monthstr[rec.month].slice(0,3));
fmt = fmt.replaceAll('mB', this.monthstr[rec.month]);
fmt = fmt.replaceAll('vB', this.weekdays[rec.weekday]);
fmt = fmt.replaceAll('vb', this.weekdays[rec.weekday].slice(0,3));
return fmt;
}
var json = {}; var json = {};
json.encode = function(value, space, replacer, whitelist) json.encode = function(value, space, replacer, whitelist)
{ {
@ -940,6 +1177,8 @@ Object.defineProperty(Array.prototype, 'lerp', {
}); });
Math.lerp = function(s,f,t) { return (f-s)*t + s; }; Math.lerp = function(s,f,t) { return (f-s)*t + s; };
Math.gcd = function(a,b) { return b === 0 ? a : gcd(b,a%b); }
Math.lcm = function(a,b) { return (a*b)/gcd(a,b); }
Math.grab_from_points = function(pos, points, slop) { Math.grab_from_points = function(pos, points, slop) {
var shortest = slop; var shortest = slop;

View file

@ -267,6 +267,10 @@ Player.players[0].control(DebugControls);
Register.gui.register(Debug.draw, Debug); Register.gui.register(Debug.draw, Debug);
var console = Object.create(Log); var console = Object.create(Log);
console.log = function(str)
{
console.say(time.text(time.now(), 'yyyy-m-dd hh:nn:ss') + " " + str);
}
console.clear = function() console.clear = function()
{ {
cmd(146); cmd(146);

View file

@ -1591,7 +1591,7 @@ replpanel.inputs.tab = function() {
}); });
if (keys.length > 1) if (keys.length > 1)
Log.console(keys.join(', ')); Log.repl(keys.join(', '));
}; };
replpanel.inputs['C-p'] = function() replpanel.inputs['C-p'] = function()
{ {

View file

@ -66,11 +66,10 @@ var Log = {
}, },
say(msg) { say(msg) {
Log.write(msg); Log.write(msg + '\n');
Log.write('\n');
}, },
console(msg) { repl(msg) {
cmd(142, msg + '\n'); cmd(142, msg + '\n');
}, },

View file

@ -78,6 +78,51 @@ void js_setprop_str(JSValue obj, const char *prop, JSValue v)
JS_SetPropertyStr(js, obj, prop, v); JS_SetPropertyStr(js, obj, prop, v);
} }
JSValue unix2time(time_t unix)
{
struct tm *t = localtime(&unix);
JSValue o = JS_NewObject(js);
js_setprop_str(o, "sec", JS_NewFloat64(js, t->tm_sec));
js_setprop_str(o, "min", JS_NewFloat64(js, t->tm_min));
js_setprop_str(o, "hour", JS_NewFloat64(js, t->tm_hour));
js_setprop_str(o, "day", JS_NewFloat64(js, t->tm_mday));
js_setprop_str(o, "mon", JS_NewFloat64(js, t->tm_mon));
js_setprop_str(o, "year", JS_NewFloat64(js, t->tm_year+1900));
js_setprop_str(o, "weekday", JS_NewFloat64(js, t->tm_wday));
js_setprop_str(o, "yday", JS_NewFloat64(js, t->tm_yday));
js_setprop_str(o, "dst", JS_NewBool(js, t->tm_isdst));
js_setprop_str(o, "unix", JS_NewFloat64(js, unix));
return o;
}
JSValue jstzone()
{
time_t t = time(NULL);
struct tm lt = {0};
localtime_r(&t, &lt);
return num2js(lt.tm_gmtoff);
}
int js2bool(JSValue v) { return JS_ToBool(js, v); }
JSValue bool2js(int b) { return JS_NewBool(js,b); }
JSValue jsdst()
{
time_t t = time(NULL);
struct tm lt = {};
localtime_r(&t,&lt);
return bool2js(lt.tm_isdst);
}
JSValue jscurtime()
{
time_t t;
time(&t);
JSValue jst = num2js(t);
return jst;
}
void js_setprop_num(JSValue obj, uint32_t i, JSValue v) void js_setprop_num(JSValue obj, uint32_t i, JSValue v)
{ {
JS_SetPropertyUint32(js, obj, i, v); JS_SetPropertyUint32(js, obj, i, v);
@ -153,14 +198,6 @@ double js2number(JSValue v) {
return g; return g;
} }
int js2bool(JSValue v) {
return JS_ToBool(js, v);
}
JSValue bool2js(int b)
{
return JS_NewBool(js,b);
}
JSValue float2js(double g) { JSValue float2js(double g) {
return JS_NewFloat64(js, g); return JS_NewFloat64(js, g);
@ -1338,6 +1375,18 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 208: case 208:
dag_set(js2go(argv[1]), js2go(argv[2])); dag_set(js2go(argv[1]), js2go(argv[2]));
break; break;
case 209:
ret = unix2time(js2number(argv[1]));
break;
case 210:
ret = jscurtime();
break;
case 211:
ret = jstzone();
break;
case 212:
ret = jsdst();
break;
} }
if (str) if (str)