Some checks failed
Build and Deploy / build-linux (push) Failing after 1m42s
Build and Deploy / build-windows (CLANG64) (push) Failing after 6m13s
Build and Deploy / package-dist (push) Has been skipped
Build and Deploy / deploy-itch (push) Has been skipped
Build and Deploy / deploy-gitea (push) Has been skipped
233 lines
7.6 KiB
JavaScript
233 lines
7.6 KiB
JavaScript
var time = this;
|
|
|
|
time.second = 1;
|
|
time.minute = 60;
|
|
time.hour = 3600;
|
|
time.day = 86400;
|
|
time.week = 604800;
|
|
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;
|
|
|
|
time.hour2minute = function() {
|
|
return this.hour / this.minute;
|
|
};
|
|
|
|
time.day2hour = function() {
|
|
return this.day / this.hour;
|
|
};
|
|
|
|
time.minute2second = function() {
|
|
return this.minute / this.second;
|
|
};
|
|
|
|
time.week2day = function() {
|
|
return this.week / this.day;
|
|
};
|
|
|
|
time.strparse = {
|
|
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",
|
|
};
|
|
|
|
time.isleap = function(year) {
|
|
return this.yearsize(year) === 366;
|
|
};
|
|
|
|
time.yearsize = function(y) {
|
|
if (y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0)) return 366;
|
|
return 365;
|
|
};
|
|
|
|
time.timecode = function(t, fps = 24) {
|
|
var s = Math.trunc(t);
|
|
t -= s;
|
|
return `${s}:${Math.trunc(fps * s)}`;
|
|
};
|
|
|
|
time.monthdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
time.zones = { "-12": "IDLW" };
|
|
|
|
time.record = function(num, zone = this.computer_zone()) {
|
|
if (typeof num === "object") {
|
|
return num;
|
|
} else if (typeof num === "number") {
|
|
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 = Math.floor(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);
|
|
rec.weekday = (day + 4503599627370496 + 2) % 7;
|
|
var yIter = this.epoch;
|
|
if (day >= 0) {
|
|
for (yIter = this.epoch; day >= this.yearsize(yIter); yIter++) {
|
|
day -= this.yearsize(yIter);
|
|
}
|
|
} else {
|
|
for (yIter = this.epoch; day < 0; yIter--) {
|
|
day += this.yearsize(yIter - 1);
|
|
}
|
|
}
|
|
rec.year = yIter;
|
|
rec.ce = (rec.year <= 0) ? "BC" : "AD";
|
|
rec.yday = day;
|
|
if (this.yearsize(yIter) === 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 || 0;
|
|
var hour = rec.hour || 0;
|
|
var minute = rec.minute || 0;
|
|
var second = rec.second || 0;
|
|
var zone = rec.zone || 0;
|
|
var yday = rec.yday || 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.fmt = "vB mB d h:nn:ss TZz a y c";
|
|
|
|
time.text = function(num, fmt = this.fmt, zone) {
|
|
var rec = (typeof num === "number") ? time.record(num, zone) : num;
|
|
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.toFixed(2).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;
|
|
};
|
|
|
|
time[prosperon.DOC] = {
|
|
doc: `The main time object, handling date/time utilities in earth-seconds.`,
|
|
second: `Number of seconds in a (real) second (always 1).`,
|
|
minute: `Number of seconds in a minute (60).`,
|
|
hour: `Number of seconds in an hour (3600).`,
|
|
day: `Number of seconds in a day (86400).`,
|
|
week: `Number of seconds in a week (604800).`,
|
|
weekdays: `Names of the days of the week, Sunday through Saturday.`,
|
|
monthstr: `Full names of the months of the year, January through December.`,
|
|
epoch: `Base epoch year, from which day 0 is calculated (default 1970).`,
|
|
hour2minute: `Return the ratio of hour to minute in seconds, e.g. 3600 / 60 => 60.`,
|
|
day2hour: `Return the ratio of day to hour in seconds, e.g. 86400 / 3600 => 24.`,
|
|
minute2second: `Return the ratio of minute to second in seconds, e.g. 60 / 1 => 60.`,
|
|
week2day: `Return the ratio of week to day in seconds, e.g. 604800 / 86400 => 7.`,
|
|
strparse: `Mapping of format tokens (yyyy, mm, dd, etc.) to time fields (year, month, day...).`,
|
|
isleap: `Return true if a given year is leap, based on whether it has 366 days.`,
|
|
yearsize: `Given a year, return 365 or 366 depending on leap-year rules.`,
|
|
timecode: `Convert seconds into a "S:frames" timecode string, with optional FPS (default 24).`,
|
|
monthdays: `An array of days in each month for a non-leap year.`,
|
|
zones: `Table of recognized time zone abbreviations, with offsets (e.g., "-12" -> "IDLW").`,
|
|
record: `Convert a timestamp (in seconds) into a record with fields like day, month, year, etc.`,
|
|
number: `Convert a record back into a numeric timestamp (seconds).`,
|
|
fmt: `Default format string for time.text(), containing tokens like 'yyyy', 'dd', 'hh', etc.`,
|
|
text: `Format a numeric or record time into a string using a format pattern, e.g. 'hh:nn:ss'.`,
|
|
now: `Return the current system time in seconds (implemented in C extension).`,
|
|
computer_dst: `Return true if local system time is currently in DST (implemented in C extension).`,
|
|
computer_zone: `Return local time zone offset from UTC in hours (implemented in C extension).`
|
|
};
|
|
|
|
return time;
|