...such things get me going... from a private (messages) conversation:
Some food for thought... you will also see some typical dynamic Javascript constructs in this code.
In some contexts one likes to separate the data from the presentation... two classes are used: The first one is - obviously - the Javascript built-in Date class, and the second one is the related ...Formatter class. This allows a mix and match with different formatters and to include the formatter only when needed.
new DateFormatter().format(); // string w/ today in default format
var tsFrmttr = new DateFormatter("yyyyMMddHHmmssSSS");
tsFrmttr.format(); // now timestamp in human readable format
Since this may look like a bit cumbersome, short and very short form have been introduced:
var d = new Date((new Date().getTime()) - 24*60*60*1000); // an day ago
DateFormatter.format(); // today in default format
DateFormatter.format(null,"yyyyMMdd"); // today in sortable format
DateFormatter.format(d); // yesterday in default format
DateFormatter(null,null); // today in default format
DateFormatter(d,"D, N d, y h:mx"); // yesterday same time
The code would look like something below.
var DateFormatter = (function(){ // for in-line use
// DateFormatter.js module
//
// allObjects 20160507
//
// yMdHmsSZhxXND are date and time pattern chars, escapable by ^ (default)
// y-year, M-month, d-day, H-hour24, m-minute, s-second, S-milliSecond, Z-zone,
// h-hour12, x/X-am|pm/AM|PM, N-Name of month, D-Name of Day, with consecutive
// same chars defining length (1 char: variable length, numbers never truncated)
// var DF = require("DateFormatter"); DF.updateDefaults({pattern:"d.M.y", ...});
// var df = new DF("optionalPattern"); log(df.format(optDate,optPattern));
// log(DF.format(optDate,optPattern)); log(DF(dateOrFalsy,patternOrFalsy));
// Absent|undefined|null|0|false,"" (=falsy) enforce default (date: now, pattern:
// defaults.pattern). NOTE: DF() direct use requires ALWAYS both parms present.
//
// use: regular: constructor new F(optPatt) | direct: F(dateOrFalsy,pattOrFalsy)
var F = function() { // F(pattern) | F(date,pattern) - falsy = default
var a = arguments; if (a.length > 1) { return new F().format(a[0],a[1]); }
this.pattern = ((a.length > 0) && a[0]) ? a[0] : this.__proto__.defaults.pattern;
}, p = F.prototype;
// regular use: f = new F(optPattern); f.format(optDateOrNull,optPattern);
p.defaults = { pattern: "M/d/y", esc: "^", year: "yyyy", zone: "ESP"
, dayLen:3, days: "SunMonTueWedThuFriSat"
, monLen:3, mons: "JanFebMarAprMayJunJulAugSepOctNovDec" };
p.getDefaults = function() { return p.defaults; };
p.updateDefaults = function(defaults) {
for (var d in defaults) p.defaults[d] = defaults[d]; return this; };
p.format = function(date, pattern) {
var d = (date) ? date : new Date(), pt = (pattern) ? pattern : this.pattern,
s = "", e = p.defaults.esc, pl = pt.length, i = 0, c, f, l;
while (i < pl) { c = pt.charAt(i); i++;
if (c === e) { if (i < pl) { s += pt.charAt(i); i++; }
} else if ((f = this[c])) {
l = 1; while ((i < pl) && (pt.charAt(i) === c)) { l++; i++; }
s += f.apply(this,[c,d,l]);
} else { s += c; } }
return s;
};
// short format ~class|static methods: F.format(optDateOrNull,optPattern);
F.getDefaults = function() { return p.getDefaults(); };
F.updateDefaults = function(defaults) { p.updateDefaults(defaults); return F; };
F.format = function(date,pattern) { return (new F(pattern)).format(date); };
// core formatters
p.y = function(c,d,l) { return this._fn(d.getFullYear(),c,l); };
p.M = function(c,d,l) { return (l < 3) ? this._fn(d.getMonth() + 1,c,l) : this.N(c,d,l); };
p.N = function(c,d,l) { return this._ft(d.getMonth(),c,l,p.defaults.mons,p.defaults.monLen); };
p.d = function(c,d,l) { return this._fn(d.getDate(),c,l); };
p.H = function(c,d,l) { return this._fn(d.getHours(),c,l); };
p.h = function(c,d,l) { return this._fn(d.getHours() % 12,c,l); };
p.m = function(c,d,l) { return this._fn(d.getMinutes(),c,l); };
p.s = function(c,d,l) { return this._fn(d.getSeconds(),c,l); };
p.S = function(c,d,l) { return this._fn(d.getMilliseconds(),c,l); };
p.x = function(c,d,l) { return ((d.getHours() < 12) ? "am" : "pm"); };
p.X = function(c,d,l) { return ((d.getHours() < 12) ? "AM" : "PM"); };
p.D = function(c,d,l) { return this._ft(d.getDay(),c,l,p.defaults.days,p.defaults.dayLen); };
p.Z = function(c,d,l) { return this._ft(0,c,l,p.defaults.zone,p.defaults.zone.length); };
p._ft = function(val,c,len,t,tLen) { // log(c + ": " + val + " as " + len + " max " + tLen + " @ " + val * tLen);
var r = t.substr(val * tLen,tLen), l; return (len === 1)
? (((l = r.indexOf(" ")) < 0) ? r : r.substring(0,l) ): r.substr(0,len); };
p._fn = function(val,c,len) { // log(c + ": " + val + " in " + len);
var r = "" + val; return ((c === "y")
? (len === 1) ? r.substr(0 - p.defaults.year.length) : r
: (r.length < len) ? ("000" + r).substr(0 - len) : r ); };
// function log(v) { console.log(v); }
// exports = F; // for module use
return F; // for in-line use
})(); // for in-line use
// DateFormatter = require("DateFormatter"); // for module use
Attachment: DateFormatter.js and DateFormatter.min.js as modules to be placed in project sandbox modules folder.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
...such things get me going... from a private (messages) conversation:
Some food for thought... you will also see some typical dynamic Javascript constructs in this code.
In some contexts one likes to separate the data from the presentation... two classes are used: The first one is - obviously - the Javascript built-in
Date
class, and the second one is the related...Formatter
class. This allows a mix and match with different formatters and to include the formatter only when needed.Since this may look like a bit cumbersome, short and very short form have been introduced:
The code would look like something below.
Attachment: DateFormatter.js and DateFormatter.min.js as modules to be placed in project sandbox modules folder.
To be continued in next post...
2 Attachments