node.js require()奇怪的行为(node.js require() weird behavior)

编程入门 行业动态 更新时间:2024-10-21 05:40:18
node.js require()奇怪的行为(node.js require() weird behavior)

更新 - 我添加了更多信息。 问题似乎取决于require语句的顺序。 不幸的是,修复一个打破另一个,请帮助!

我无法弄清楚这里发生了什么。 我有5个文件如下所示,我使用index.js只是为了演示这个问题。 如果首先需要HDate,那么HDate.make在HDateTime类中失败。 如果首先需要HDateTime,则HDateTime.make在HDate类中失败。 看来它可能是循环引用问题,但我无法弄清楚如何纠正问题。

index.js - 在DATETIME上失败

var HDate = require('./HDate'); var HDateTime = require('./HDateTime'); var HTimeZone = require('./HTimeZone'); var utc = HTimeZone.UTC; console.log('DATE: ' + HDate.make(2011, 1, 2)); console.log('MIDNIGHT: ' + HDate.make(2011, 1, 2).midnight(utc)); console.log('DATETIME: ' + HDateTime.make(2011, 1, 2, 3, 4, 5, utc, 0)); ERROR OUTPUT: C:\Users\Shawn\nodehaystack>node index.js DATE: 2011-01-02 MIDNIGHT: 2011-01-02T00:00:00Z UTC C:\Users\Shawn\nodehaystack\HDateTime.js:95 return HDateTime.make(HDate.make(arg1, arg2, arg3), HTime.make(arg4, arg5, ^ TypeError: undefined is not a function at Function.HDateTime.make (C:\Users\Shawn\nodehaystack\HDateTime.js:95:33) at Object.<anonymous> (C:\Users\Shawn\nodehaystack\index.js:8:38) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3

index.js - MIDNIGHT失败

var HDateTime = require('./HDateTime'); var HDate = require('./HDate'); var HTimeZone = require('./HTimeZone'); var utc = HTimeZone.UTC; console.log('DATE: ' + HDate.make(2011, 1, 2)); console.log('DATETIME: ' + HDateTime.make(2011, 1, 2, 3, 4, 5, utc, 0)); console.log('MIDNIGHT: ' + HDate.make(2011, 1, 2).midnight(utc)); ERROR OUTPUT: C:\Users\Shawn\nodehaystack>node index.js DATE: 2011-01-02 DATETIME: 2011-01-02T03:04:05Z UTC C:\Users\Shawn\nodehaystack\HDate.js:46 HDate.prototype.midnight = function(tz) { return HDateTime.make(this, HTime.MI ^ TypeError: undefined is not a function at HVal.HDate.midnight (C:\Users\Shawn\nodehaystack\HDate.js:46:60) at Object.<anonymous> (C:\Users\Shawn\nodehaystack\index.js:8:51) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3

HDate.js

var HVal = require('./HVal'); var HDateTime = require('./HDateTime'); var HTime = require('./HTime'); /** Private constructor */ function HDate(year, month, day) { /** Four digit year such as 2011 */ this.year = year; /** Month as 1-12 (Jan is 1, Dec is 12) */ this.month = month; /** Day of month as 1-31 */ this.day = day; }; HDate.prototype = Object.create(HVal.prototype); /** int - Hash is based on year, month, day */ HDate.prototype.hashCode = function() { return (this.year << 16) ^ (this.month << 8) ^ this.day; }; /** String - Encode as "YYYY-MM-DD" */ HDate.prototype.toZinc = function() { var s = this.year + "-"; if (this.month < 10) s += "0"; s += this.month + "-"; if (this.day < 10) s += "0"; s += this.day; return s; }; /** boolean - Equals is based on year, month, day */ HDate.prototype.equals = function(that) { return that instanceof HDate && this.year === that.year && this.month === that.month && this.day === that.day; }; /** int - Return sort order as negative, 0, or positive */ HDate.prototype.compareTo = function(that) { if (this.year < that.year) return -1; else if (this.year > that.year) return 1; if (this.month < that.month) return -1; else if (this.month > that.month) return 1; if (this.day < that.day) return -1; else if (this.day > that.day) return 1; return 0; }; /** Convert this date into HDateTime for midnight in given timezone. */ HDate.prototype.midnight = function(tz) { return HDateTime.make(this, HTime.MIDNIGHT, tz); }; /** Return date in future given number of days */ HDate.prototype.plusDays = function(numDays) { if (numDays == 0) return this; if (numDays < 0) return this.minusDays(-numDays); var year = this.year; var month = this.month; var day = this.day; for (; numDays > 0; --numDays) { day++; if (day > HDate.daysInMonth(year, month)) { day = 1; month++; if (month > 12) { month = 1; year++; } } } return HDate.make(year, month, day); }; /** Return date in past given number of days */ HDate.prototype.minusDays = function(numDays) { if (numDays == 0) return this; if (numDays < 0) return this.plusDays(-numDays); var year = this.year; var month = this.month; var day = this.day; for (; numDays > 0; --numDays) { day--; if (day <= 0) { month--; if (month < 1) { month = 12; year--; } day = HDate.daysInMonth(year, month); } } return HDate.make(year, month, day); }; /** Return day of week: Sunday is 1, Saturday is 7 */ HDate.prototype.weekday = function() { return new Date(this.year, this.month-1, this.day).getDay() + 1; }; /** Export for use in testing */ module.exports = HDate; /** Construct from basic fields, javascript Date instance, or String in format "YYYY-MM-DD" */ HDate.make = function(arg, month, day) { if (arg instanceof Date) { return new HDate(arg.getFullYear(), arg.getMonth() + 1, arg.getDate()); } else if (HVal.typeis(arg, 'string', String)) { try { var s = arg.split('-'); return new HDate(parseInt(s[0]), parseInt(s[1]), parseInt(s[2])); } catch(err) { throw err; } } else { if (arg < 1900) throw new Error("Invalid year"); if (month < 1 || month > 12) throw new Error("Invalid month"); if (day < 1 || day > 31) throw new Error("Invalid day"); return new HDate(arg, month, day); } }; /** Get HDate for current time in default timezone */ HDate.today = function() { return HDateTime.now().date; }; /** Return if given year a leap year */ HDate.isLeapYear = function(year) { if ((year & 3) != 0) return false; return (year % 100 != 0) || (year % 400 == 0); }; /** Return number of days in given year (xxxx) and month (1-12) */ var daysInMon = [ -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; var daysInMonLeap = [ -1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; HDate.daysInMonth = function(year, mon) { return HDate.isLeapYear(year) ? daysInMonLeap[mon] : daysInMon[mon]; };

HDateTime.js

var moment = require('moment-timezone'); var HVal = require('./HVal'); var HDate = require('./HDate'); var HTime = require('./HTime'); var HTimeZone = require('./HTimeZone'); // require('./io/HZincReader'); /** Private constructor */ function HDateTime(date, time, tz, tzOffset) { /** HDate - Date component of the timestamp */ this.date = date; /** HTime - Time component of the timestamp */ this.time = time; /** int - Offset in seconds from UTC including DST offset */ this.tz = tz; /** HTimeZone - Timezone as Olson database city name */ this.tzOffset = (typeof(tzOffset) == 'undefined' ? 0 : tzOffset); /** long - millis since Epoch */ this.millis; } HDateTime.prototype = Object.create(HVal.prototype); /** long - Get this date time as Java milliseconds since epoch */ HDateTime.prototype.millis = function() { if (this.millis <= 0) { var d = new Date(this.date.year, this.date.month-1, this.date.day, this.time.hour, this.time.min, this.time.sec, this.time.ms); //TODO: implement UTC timezone this.millis = d.getTime(); } return this.millis; }; /** int - Hash code is based on date, time, tzOffset, and tz */ HDateTime.prototype.hashCode = function() { return this.date.hashCode() ^ this.time.hashCode() ^ tzOffset ^ this.tz.hashCode(); }; /** String - Encode as "YYYY-MM-DD'T'hh:mm:ss.FFFz zzzz" */ HDateTime.prototype.toZinc = function() { var s = this.date.toZinc() + "T" + this.time.toZinc(); if (this.tzOffset == 0) s += "Z"; else { var offset = this.tzOffset; if (offset < 0) { s += "-"; offset = -offset; } else { s += "+"; } var zh = offset / 3600; var zm = (offset % 3600) / 60; if (zh < 10) s += "0"; s += zh + ":"; if (zm < 10) s += "0"; s += zm; } s += " " + this.tz; return s; }; /** boolean - Equals is based on date, time, tzOffset, and tz */ HDateTime.prototype.equals = function(that) { return that instanceof HDateTime && this.date === that.date && this.time === that.time && this.tzOffset === that.tzOffset && this.tz === that.tz; }; /** int - Comparison based on millis. */ HDateTime.prototype.compareTo = function(that) { var thisMillis = this.millis(); var thatMillis = that.millis(); if (thisMillis < thatMillis) return -1; else if (thisMillis > thatMillis) return 1; return 0; }; /** Export for use in testing */ module.exports = HDateTime; function utcDate(year, month, day, hour, min, sec, ms) { var d = new Date(); d.setUTCFullYear(year); d.setUTCMonth(month-1); d.setUTCDate(day); d.setUTCHours(hour); d.setUTCMinutes(min); d.setUTCSeconds(sec); d.setUTCMilliseconds(ms); return d; } /** Construct from various values */ HDateTime.make = function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) { if (arg7 instanceof HTimeZone) { return HDateTime.make(HDate.make(arg1, arg2, arg3), HTime.make(arg4, arg5, arg6), arg7, arg8); } else if (arg6 instanceof HTimeZone) { return HDateTime.make(HDate.make(arg1, arg2, arg3), HTime.make(arg4, arg5, 0), arg6, arg7); } else if (arg3 instanceof HTimeZone) { // use Date to decode millis to fields var d = utcDate(arg1.year, arg1.month, arg1.day, arg2.hour, arg2.min, arg2.sec, arg2.ms); var tzOffset = arg4; if (typeof(tzOffset) == 'undefined') { // convert to designated timezone d = moment(d).tz(arg3.js.name); tzOffset = d.utcOffset() * 60; } var ts = new HDateTime(arg1, arg2, arg3, tzOffset); ts.millis = d.valueOf() + (tzOffset * -1000); return ts; } else if (this.typeis(arg1, 'string', String)) { // TODO: Implemet parsing // var val = new HZincReader(arg1).readScalar(); // if (typeof(val) == HDateTime) return val; // throw new Error("Parse Error: " + arg1); } else { var tz = arg2; if (typeof(tz) == 'undefined') tz = HTimeZone.DEFAULT; var d = new Date(arg1); // convert to designated timezone d = moment(d).tz(tz.js.name); tzOffset = d.utcOffset() * 60; var ts = new HDateTime(HDate.make(d), HTime.make(d), tz, tz.getOffset()); ts.millis = arg1; } }; /** HDateTime - Get HDateTime for given timezone */ HDateTime.now = function(tz) { return make(new Date().getTime(), tz); };

HTime.js

var HVal = require('./HVal'); // require('./io/HZincReader'); /** Private constructor */ function HTime(hour, min, sec, ms) { /** int - Hour of day as 0-23 */ this.hour = hour; /** int - Minute of hour as 0-59 */ this.min = min; /** int - Second of minute as 0-59 */ this.sec = (typeof(sec) == 'undefined' ? 0 : sec); /** int - Fractional seconds in milliseconds 0-999 */ this.ms = (typeof(ms) == 'undefined' ? 0 : ms); }; HTime.prototype = Object.create(HVal.prototype); /** int - Hash code is based on hour, min, sec, ms */ HTime.prototype.hashCode = function() { return (this.hour << 24) ^ (this.min << 20) ^ (this.sec << 16) ^ this.ms; }; /** boolean - Equals is based on hour, min, sec, ms */ HTime.prototype.equals = function(that) { return that instanceof HTime && this.hour === that.hour && this.min === that.min && this.sec === that.sec && this.ms === that.ms; }; /** int - Return sort order as negative, 0, or positive */ HTime.prototype.compareTo = function(that) { if (this.hour < that.hour) return -1; else if (this.hour > that.hour) return 1; if (this.min < that.min) return -1; else if (this.min > that.min) return 1; if (this.sec < that.sec) return -1; else if (this.sec > that.sec) return 1; if (this.ms < that.ms) return -1; else if (this.ms > that.ms) return 1; return 0; }; /** String - Encode as "hh:mm:ss.FFF" */ HTime.prototype.toZinc = function() { var s = ""; if (this.hour < 10) s += "0"; s += this.hour + ":"; if (this.min < 10) s += "0"; s += this.min + ":"; if (this.sec < 10) s += "0"; s += this.sec; if (this.ms != 0) { s += "."; if (this.ms < 10) s += "0"; if (this.ms < 100) s += "0"; s += this.ms; } return s; }; /** Export for use in testing */ module.exports = HTime; /** Singleton for midnight 00:00 */ HTime.MIDNIGHT = new HTime(0, 0, 0, 0); /** Construct with all fields, with Javascript Date object, or Parse from string fomat "hh:mm:ss.FF" */ HTime.make = function(arg1, min, sec, ms) { if (HVal.typeis(arg1, 'string', String)) { // TODO: Implemet parsing // var val = new HZincReader(arg1).readScalar(); // if (val instanceof HTime) return val; // throw new Error("Parse Error: " + arg1); } else if (arg1 instanceof Date) { return new HTime(arg1.getHours(), arg1.getMinutes(), arg1.getSeconds(), arg1.getMilliseconds()); } else { return new HTime(arg1, min, sec, ms); } };

HTimeZone.js

var moment = require('moment-timezone'); var HVal = require('./HVal'); /** Package private constructor */ function HTimeZone(name, js) { /** Haystack timezone name */ this.name = name; /** Javascript (moment) representation of this timezone. */ this.js = js; }; /** String - Return Haystack timezone name */ HTimeZone.prototype.toString = function() { return this.name; }; module.exports = HTimeZone; HTimeZone.make = function(arg1, checked) { if (typeof(checked) == 'undefined') return HTimeZone.make(arg1, true); if (HVal.typeis(arg1, 'string', String)) { /** * Construct with Haystack timezone name, raise exception or * return null on error based on check flag. */ // lookup in cache var tz = cache[arg1]; if (typeof(tz) != 'undefined') return tz; // map haystack id to Javascript full id var jsId = toJS[arg1]; if (typeof(jsId) == 'undefined') { if (checked) throw new Error("Unknown tz: " + arg1); return undefined; } // resolve full id to HTimeZone and cache var js = moment.tz.zone(jsId) tz = new HTimeZone(arg1, js); cache[arg1] = tz; return tz; } else { /** * Construct from Javascript timezone. Throw exception or return * null based on checked flag. */ var jsId = arg1.name; if (jsId.startsWith("GMT")) fixGMT(jsId); var name = fromJS[jsId]; if (typeof(name) != 'undefined') return HTimeZone.make(name); if (checked) throw new Error("Invalid Java timezone: " + arg1.name); return; } }; function fixGMT(jsId) { // Javscript (moment) IDs can be in the form "GMT[+,-]h" as well as // "GMT", and "GMT0". In that case, convert the ID to "Etc/GMT[+,-]h". // V8 uses the format "GMT[+,-]hh00 (used for default timezone), this also // needs converted. if (jsId.indexOf("+")<0 && jsId.indexOf("-")<0) return "Etc/" + jsId; // must be "GMT" or "GMT0" which are fine // get the prefix var pre = jsId.substring(0, 4); var num = parseInt(jsId.substring(4, 6)); // ensure we have a valid value if ((pre.substring(3)=="+" && num<13) || (pre.substring(3)=="-" & num<15)) return "Etc/" + pre + num; // nothing we could do, return what was passed return jsId; } var cache = {}; var toJS = {}; var fromJS = {}; { try { // only time zones which start with these // regions are considered valid timezones var regions = {}; regions["Africa"] = "ok"; regions["America"] = "ok"; regions["Antarctica"] = "ok"; regions["Asia"] = "ok"; regions["Atlantic"] = "ok"; regions["Australia"] = "ok"; regions["Etc"] = "ok"; regions["Europe"] = "ok"; regions["Indian"] = "ok"; regions["Pacific"] = "ok"; // iterate Javascript timezone IDs available var ids = moment.tz.names(); for (var i=0; i<ids.length; ++i) { var js = ids[i]; // skip ids not formatted as Region/City var slash = js.indexOf('/'); if (slash < 0) continue; var region = js.substring(0, slash); if (typeof(regions[region]) == 'undefined') continue; // get city name as haystack id slash = js.lastIndexOf('/'); var haystack = js.substring(slash+1); // store mapping b/w Javascript <-> Haystack toJS[haystack] = js; fromJS[js] = haystack; } } catch (err) { console.log(err.stack); } var utc; try { utc = HTimeZone.make(moment.tz.zone("Etc/UTC")); } catch (err) { console.log(err.stack); } var def; try { // check if configured with system property var defName = process.env["haystack.tz"]; if (defName != null) { def = make(defName, false); if (typeof(def) == 'undefined') console.log("WARN: invalid haystack.tz system property: " + defName); } // if we still don't have a default, try to use Javascript's if (typeof(def) == 'undefined') { var date = new Date().toString(); var gmtStart = date.indexOf("GMT"); var gmtEnd = date.indexOf(" ", gmtStart); def = fromJS[fixGMT(date.substring(gmtStart, gmtEnd))]; } } catch (err) { console.log(err.stack); def = utc; } /** UTC timezone */ HTimeZone.UTC = utc; /** Default timezone for VM */ HTimeZone.DEFAULT = def; }

UPDATE - I added more information. The issue seems to be dependant on the order of the require statements. Unfortunately, fixing one breaks the other, please help!!!

I cannot figure out what is going on here. I have 5 files shown below, and am using index.js simply to demonstrate the issue. If HDate is required first then HDate.make fails within the HDateTime class. If HDateTime is required first, then HDateTime.make fails within the HDate class. Appears it is possibly a circular reference issue, but I have not been able to figure out how to correct the problem.

index.js - fails on DATETIME

var HDate = require('./HDate'); var HDateTime = require('./HDateTime'); var HTimeZone = require('./HTimeZone'); var utc = HTimeZone.UTC; console.log('DATE: ' + HDate.make(2011, 1, 2)); console.log('MIDNIGHT: ' + HDate.make(2011, 1, 2).midnight(utc)); console.log('DATETIME: ' + HDateTime.make(2011, 1, 2, 3, 4, 5, utc, 0)); ERROR OUTPUT: C:\Users\Shawn\nodehaystack>node index.js DATE: 2011-01-02 MIDNIGHT: 2011-01-02T00:00:00Z UTC C:\Users\Shawn\nodehaystack\HDateTime.js:95 return HDateTime.make(HDate.make(arg1, arg2, arg3), HTime.make(arg4, arg5, ^ TypeError: undefined is not a function at Function.HDateTime.make (C:\Users\Shawn\nodehaystack\HDateTime.js:95:33) at Object.<anonymous> (C:\Users\Shawn\nodehaystack\index.js:8:38) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3

index.js - fails on MIDNIGHT

var HDateTime = require('./HDateTime'); var HDate = require('./HDate'); var HTimeZone = require('./HTimeZone'); var utc = HTimeZone.UTC; console.log('DATE: ' + HDate.make(2011, 1, 2)); console.log('DATETIME: ' + HDateTime.make(2011, 1, 2, 3, 4, 5, utc, 0)); console.log('MIDNIGHT: ' + HDate.make(2011, 1, 2).midnight(utc)); ERROR OUTPUT: C:\Users\Shawn\nodehaystack>node index.js DATE: 2011-01-02 DATETIME: 2011-01-02T03:04:05Z UTC C:\Users\Shawn\nodehaystack\HDate.js:46 HDate.prototype.midnight = function(tz) { return HDateTime.make(this, HTime.MI ^ TypeError: undefined is not a function at HVal.HDate.midnight (C:\Users\Shawn\nodehaystack\HDate.js:46:60) at Object.<anonymous> (C:\Users\Shawn\nodehaystack\index.js:8:51) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:501:10) at startup (node.js:129:16) at node.js:814:3

HDate.js

var HVal = require('./HVal'); var HDateTime = require('./HDateTime'); var HTime = require('./HTime'); /** Private constructor */ function HDate(year, month, day) { /** Four digit year such as 2011 */ this.year = year; /** Month as 1-12 (Jan is 1, Dec is 12) */ this.month = month; /** Day of month as 1-31 */ this.day = day; }; HDate.prototype = Object.create(HVal.prototype); /** int - Hash is based on year, month, day */ HDate.prototype.hashCode = function() { return (this.year << 16) ^ (this.month << 8) ^ this.day; }; /** String - Encode as "YYYY-MM-DD" */ HDate.prototype.toZinc = function() { var s = this.year + "-"; if (this.month < 10) s += "0"; s += this.month + "-"; if (this.day < 10) s += "0"; s += this.day; return s; }; /** boolean - Equals is based on year, month, day */ HDate.prototype.equals = function(that) { return that instanceof HDate && this.year === that.year && this.month === that.month && this.day === that.day; }; /** int - Return sort order as negative, 0, or positive */ HDate.prototype.compareTo = function(that) { if (this.year < that.year) return -1; else if (this.year > that.year) return 1; if (this.month < that.month) return -1; else if (this.month > that.month) return 1; if (this.day < that.day) return -1; else if (this.day > that.day) return 1; return 0; }; /** Convert this date into HDateTime for midnight in given timezone. */ HDate.prototype.midnight = function(tz) { return HDateTime.make(this, HTime.MIDNIGHT, tz); }; /** Return date in future given number of days */ HDate.prototype.plusDays = function(numDays) { if (numDays == 0) return this; if (numDays < 0) return this.minusDays(-numDays); var year = this.year; var month = this.month; var day = this.day; for (; numDays > 0; --numDays) { day++; if (day > HDate.daysInMonth(year, month)) { day = 1; month++; if (month > 12) { month = 1; year++; } } } return HDate.make(year, month, day); }; /** Return date in past given number of days */ HDate.prototype.minusDays = function(numDays) { if (numDays == 0) return this; if (numDays < 0) return this.plusDays(-numDays); var year = this.year; var month = this.month; var day = this.day; for (; numDays > 0; --numDays) { day--; if (day <= 0) { month--; if (month < 1) { month = 12; year--; } day = HDate.daysInMonth(year, month); } } return HDate.make(year, month, day); }; /** Return day of week: Sunday is 1, Saturday is 7 */ HDate.prototype.weekday = function() { return new Date(this.year, this.month-1, this.day).getDay() + 1; }; /** Export for use in testing */ module.exports = HDate; /** Construct from basic fields, javascript Date instance, or String in format "YYYY-MM-DD" */ HDate.make = function(arg, month, day) { if (arg instanceof Date) { return new HDate(arg.getFullYear(), arg.getMonth() + 1, arg.getDate()); } else if (HVal.typeis(arg, 'string', String)) { try { var s = arg.split('-'); return new HDate(parseInt(s[0]), parseInt(s[1]), parseInt(s[2])); } catch(err) { throw err; } } else { if (arg < 1900) throw new Error("Invalid year"); if (month < 1 || month > 12) throw new Error("Invalid month"); if (day < 1 || day > 31) throw new Error("Invalid day"); return new HDate(arg, month, day); } }; /** Get HDate for current time in default timezone */ HDate.today = function() { return HDateTime.now().date; }; /** Return if given year a leap year */ HDate.isLeapYear = function(year) { if ((year & 3) != 0) return false; return (year % 100 != 0) || (year % 400 == 0); }; /** Return number of days in given year (xxxx) and month (1-12) */ var daysInMon = [ -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; var daysInMonLeap = [ -1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; HDate.daysInMonth = function(year, mon) { return HDate.isLeapYear(year) ? daysInMonLeap[mon] : daysInMon[mon]; };

HDateTime.js

var moment = require('moment-timezone'); var HVal = require('./HVal'); var HDate = require('./HDate'); var HTime = require('./HTime'); var HTimeZone = require('./HTimeZone'); // require('./io/HZincReader'); /** Private constructor */ function HDateTime(date, time, tz, tzOffset) { /** HDate - Date component of the timestamp */ this.date = date; /** HTime - Time component of the timestamp */ this.time = time; /** int - Offset in seconds from UTC including DST offset */ this.tz = tz; /** HTimeZone - Timezone as Olson database city name */ this.tzOffset = (typeof(tzOffset) == 'undefined' ? 0 : tzOffset); /** long - millis since Epoch */ this.millis; } HDateTime.prototype = Object.create(HVal.prototype); /** long - Get this date time as Java milliseconds since epoch */ HDateTime.prototype.millis = function() { if (this.millis <= 0) { var d = new Date(this.date.year, this.date.month-1, this.date.day, this.time.hour, this.time.min, this.time.sec, this.time.ms); //TODO: implement UTC timezone this.millis = d.getTime(); } return this.millis; }; /** int - Hash code is based on date, time, tzOffset, and tz */ HDateTime.prototype.hashCode = function() { return this.date.hashCode() ^ this.time.hashCode() ^ tzOffset ^ this.tz.hashCode(); }; /** String - Encode as "YYYY-MM-DD'T'hh:mm:ss.FFFz zzzz" */ HDateTime.prototype.toZinc = function() { var s = this.date.toZinc() + "T" + this.time.toZinc(); if (this.tzOffset == 0) s += "Z"; else { var offset = this.tzOffset; if (offset < 0) { s += "-"; offset = -offset; } else { s += "+"; } var zh = offset / 3600; var zm = (offset % 3600) / 60; if (zh < 10) s += "0"; s += zh + ":"; if (zm < 10) s += "0"; s += zm; } s += " " + this.tz; return s; }; /** boolean - Equals is based on date, time, tzOffset, and tz */ HDateTime.prototype.equals = function(that) { return that instanceof HDateTime && this.date === that.date && this.time === that.time && this.tzOffset === that.tzOffset && this.tz === that.tz; }; /** int - Comparison based on millis. */ HDateTime.prototype.compareTo = function(that) { var thisMillis = this.millis(); var thatMillis = that.millis(); if (thisMillis < thatMillis) return -1; else if (thisMillis > thatMillis) return 1; return 0; }; /** Export for use in testing */ module.exports = HDateTime; function utcDate(year, month, day, hour, min, sec, ms) { var d = new Date(); d.setUTCFullYear(year); d.setUTCMonth(month-1); d.setUTCDate(day); d.setUTCHours(hour); d.setUTCMinutes(min); d.setUTCSeconds(sec); d.setUTCMilliseconds(ms); return d; } /** Construct from various values */ HDateTime.make = function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) { if (arg7 instanceof HTimeZone) { return HDateTime.make(HDate.make(arg1, arg2, arg3), HTime.make(arg4, arg5, arg6), arg7, arg8); } else if (arg6 instanceof HTimeZone) { return HDateTime.make(HDate.make(arg1, arg2, arg3), HTime.make(arg4, arg5, 0), arg6, arg7); } else if (arg3 instanceof HTimeZone) { // use Date to decode millis to fields var d = utcDate(arg1.year, arg1.month, arg1.day, arg2.hour, arg2.min, arg2.sec, arg2.ms); var tzOffset = arg4; if (typeof(tzOffset) == 'undefined') { // convert to designated timezone d = moment(d).tz(arg3.js.name); tzOffset = d.utcOffset() * 60; } var ts = new HDateTime(arg1, arg2, arg3, tzOffset); ts.millis = d.valueOf() + (tzOffset * -1000); return ts; } else if (this.typeis(arg1, 'string', String)) { // TODO: Implemet parsing // var val = new HZincReader(arg1).readScalar(); // if (typeof(val) == HDateTime) return val; // throw new Error("Parse Error: " + arg1); } else { var tz = arg2; if (typeof(tz) == 'undefined') tz = HTimeZone.DEFAULT; var d = new Date(arg1); // convert to designated timezone d = moment(d).tz(tz.js.name); tzOffset = d.utcOffset() * 60; var ts = new HDateTime(HDate.make(d), HTime.make(d), tz, tz.getOffset()); ts.millis = arg1; } }; /** HDateTime - Get HDateTime for given timezone */ HDateTime.now = function(tz) { return make(new Date().getTime(), tz); };

HTime.js

var HVal = require('./HVal'); // require('./io/HZincReader'); /** Private constructor */ function HTime(hour, min, sec, ms) { /** int - Hour of day as 0-23 */ this.hour = hour; /** int - Minute of hour as 0-59 */ this.min = min; /** int - Second of minute as 0-59 */ this.sec = (typeof(sec) == 'undefined' ? 0 : sec); /** int - Fractional seconds in milliseconds 0-999 */ this.ms = (typeof(ms) == 'undefined' ? 0 : ms); }; HTime.prototype = Object.create(HVal.prototype); /** int - Hash code is based on hour, min, sec, ms */ HTime.prototype.hashCode = function() { return (this.hour << 24) ^ (this.min << 20) ^ (this.sec << 16) ^ this.ms; }; /** boolean - Equals is based on hour, min, sec, ms */ HTime.prototype.equals = function(that) { return that instanceof HTime && this.hour === that.hour && this.min === that.min && this.sec === that.sec && this.ms === that.ms; }; /** int - Return sort order as negative, 0, or positive */ HTime.prototype.compareTo = function(that) { if (this.hour < that.hour) return -1; else if (this.hour > that.hour) return 1; if (this.min < that.min) return -1; else if (this.min > that.min) return 1; if (this.sec < that.sec) return -1; else if (this.sec > that.sec) return 1; if (this.ms < that.ms) return -1; else if (this.ms > that.ms) return 1; return 0; }; /** String - Encode as "hh:mm:ss.FFF" */ HTime.prototype.toZinc = function() { var s = ""; if (this.hour < 10) s += "0"; s += this.hour + ":"; if (this.min < 10) s += "0"; s += this.min + ":"; if (this.sec < 10) s += "0"; s += this.sec; if (this.ms != 0) { s += "."; if (this.ms < 10) s += "0"; if (this.ms < 100) s += "0"; s += this.ms; } return s; }; /** Export for use in testing */ module.exports = HTime; /** Singleton for midnight 00:00 */ HTime.MIDNIGHT = new HTime(0, 0, 0, 0); /** Construct with all fields, with Javascript Date object, or Parse from string fomat "hh:mm:ss.FF" */ HTime.make = function(arg1, min, sec, ms) { if (HVal.typeis(arg1, 'string', String)) { // TODO: Implemet parsing // var val = new HZincReader(arg1).readScalar(); // if (val instanceof HTime) return val; // throw new Error("Parse Error: " + arg1); } else if (arg1 instanceof Date) { return new HTime(arg1.getHours(), arg1.getMinutes(), arg1.getSeconds(), arg1.getMilliseconds()); } else { return new HTime(arg1, min, sec, ms); } };

HTimeZone.js

var moment = require('moment-timezone'); var HVal = require('./HVal'); /** Package private constructor */ function HTimeZone(name, js) { /** Haystack timezone name */ this.name = name; /** Javascript (moment) representation of this timezone. */ this.js = js; }; /** String - Return Haystack timezone name */ HTimeZone.prototype.toString = function() { return this.name; }; module.exports = HTimeZone; HTimeZone.make = function(arg1, checked) { if (typeof(checked) == 'undefined') return HTimeZone.make(arg1, true); if (HVal.typeis(arg1, 'string', String)) { /** * Construct with Haystack timezone name, raise exception or * return null on error based on check flag. */ // lookup in cache var tz = cache[arg1]; if (typeof(tz) != 'undefined') return tz; // map haystack id to Javascript full id var jsId = toJS[arg1]; if (typeof(jsId) == 'undefined') { if (checked) throw new Error("Unknown tz: " + arg1); return undefined; } // resolve full id to HTimeZone and cache var js = moment.tz.zone(jsId) tz = new HTimeZone(arg1, js); cache[arg1] = tz; return tz; } else { /** * Construct from Javascript timezone. Throw exception or return * null based on checked flag. */ var jsId = arg1.name; if (jsId.startsWith("GMT")) fixGMT(jsId); var name = fromJS[jsId]; if (typeof(name) != 'undefined') return HTimeZone.make(name); if (checked) throw new Error("Invalid Java timezone: " + arg1.name); return; } }; function fixGMT(jsId) { // Javscript (moment) IDs can be in the form "GMT[+,-]h" as well as // "GMT", and "GMT0". In that case, convert the ID to "Etc/GMT[+,-]h". // V8 uses the format "GMT[+,-]hh00 (used for default timezone), this also // needs converted. if (jsId.indexOf("+")<0 && jsId.indexOf("-")<0) return "Etc/" + jsId; // must be "GMT" or "GMT0" which are fine // get the prefix var pre = jsId.substring(0, 4); var num = parseInt(jsId.substring(4, 6)); // ensure we have a valid value if ((pre.substring(3)=="+" && num<13) || (pre.substring(3)=="-" & num<15)) return "Etc/" + pre + num; // nothing we could do, return what was passed return jsId; } var cache = {}; var toJS = {}; var fromJS = {}; { try { // only time zones which start with these // regions are considered valid timezones var regions = {}; regions["Africa"] = "ok"; regions["America"] = "ok"; regions["Antarctica"] = "ok"; regions["Asia"] = "ok"; regions["Atlantic"] = "ok"; regions["Australia"] = "ok"; regions["Etc"] = "ok"; regions["Europe"] = "ok"; regions["Indian"] = "ok"; regions["Pacific"] = "ok"; // iterate Javascript timezone IDs available var ids = moment.tz.names(); for (var i=0; i<ids.length; ++i) { var js = ids[i]; // skip ids not formatted as Region/City var slash = js.indexOf('/'); if (slash < 0) continue; var region = js.substring(0, slash); if (typeof(regions[region]) == 'undefined') continue; // get city name as haystack id slash = js.lastIndexOf('/'); var haystack = js.substring(slash+1); // store mapping b/w Javascript <-> Haystack toJS[haystack] = js; fromJS[js] = haystack; } } catch (err) { console.log(err.stack); } var utc; try { utc = HTimeZone.make(moment.tz.zone("Etc/UTC")); } catch (err) { console.log(err.stack); } var def; try { // check if configured with system property var defName = process.env["haystack.tz"]; if (defName != null) { def = make(defName, false); if (typeof(def) == 'undefined') console.log("WARN: invalid haystack.tz system property: " + defName); } // if we still don't have a default, try to use Javascript's if (typeof(def) == 'undefined') { var date = new Date().toString(); var gmtStart = date.indexOf("GMT"); var gmtEnd = date.indexOf(" ", gmtStart); def = fromJS[fixGMT(date.substring(gmtStart, gmtEnd))]; } } catch (err) { console.log(err.stack); def = utc; } /** UTC timezone */ HTimeZone.UTC = utc; /** Default timezone for VM */ HTimeZone.DEFAULT = def; }

最满意答案

问题是如何导出函数。

你说module.exports = HDate哪个好,但是你做的是module.exports.make = function(){}这也没关系。 但是,正如你刚才所经历的那样,两者并不可靠。

要修复该类导出类似于module.exports.hdate或者将make函数添加到HDate :

Hdate.make = myFunction() {}

对于您这样导出的所有方法,这显然都是如此。

让我知道,如果这解决了你的问题:)

I have found that the best solution to this issue is to move all the require statements that could cause a cyclical dependency to ensure they are after the constructor for my class and after the module.exports statement. For example...

var HVal = require('./HVal'); /** * HDate models a date (day in year) tag value. * @see {@link http://project-haystack.org/doc/TagModel#tagKinds|Project Haystack} * * @constructor * @private * @extends {HVal} * @param {int} year - Four digit year such as 2011 * @param {int} month - Month as 1-12 (Jan is 1, Dec is 12) * @param {int} day - Day of month as 1-31 */ function HDate(year, month, day) { this.year = year; this.month = month; this.day = day; } HDate.prototype = Object.create(HVal.prototype); module.exports = HDate; var HDateTime = require('./HDateTime'), HTime = require('./HTime');

Doing this method consistently in all of my classes prevents any cyclical issues.

更多推荐

本文发布于:2023-07-23 00:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1225177.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:奇怪   js   node   require   behavior

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!