/**
* 擷取指定時區的時間
* @param offset 時區
* @returns {Date} 指定時區的 時間資訊
*/
module.exports.getZoneTime = (offset)=> {
// 取本地時間
let localtime = new Date();
// 取本地毫秒數
let localmesc = localtime.getTime();
// 取本地時區與格林尼治所在時區的偏差毫秒數
let localOffset = localtime.getTimezoneOffset() * ;
// 反推得到格林尼治時間
let utc = localOffset + localmesc;
// 得到指定時區時間
let calctime = utc + ( * offset);
return new Date(calctime);
};
帶驗證 方法 參考Java實作
/**
* 檢查時區 函數 錯誤時區就傳回+0000
* @param tz 時區 參考JAVA實作方法
*/
module.exports.checkTz = (tz) => {
if (!tz) {
tz = "+0000";
}
if ('-' != tz.charAt() && '+' != tz.charAt()) {
tz = "+" + tz;
}
let hours, minutes, seconds;
switch (tz.length) {
case :
tz = tz.charAt() + "0" + tz.charAt();
case :
hours = parseNumber(tz, , false);
minutes = ;
seconds = ;
break;
case :
hours = parseNumber(tz, , false);
minutes = parseNumber(tz, , false);
seconds = ;
break;
case :
hours = parseNumber(tz, , false);
minutes = parseNumber(tz, , true);
seconds = ;
break;
case :
hours = parseNumber(tz, , false);
minutes = parseNumber(tz, , false);
seconds = parseNumber(tz, , false);
break;
case :
hours = parseNumber(tz, , false);
minutes = parseNumber(tz, , true);
seconds = parseNumber(tz, , true);
break;
default:
throw new Error("Invalid ID for ZoneOffset, invalid format: " + tz);
}
let first = tz.charAt();
if (first != '+' && first != '-') {
throw new Error("Invalid ID for ZoneOffset, plus/minus not found when expected: " + tz);
}
if (first == '-') {
return ofHoursMinutesSeconds(-hours, -minutes, -seconds);
} else {
return ofHoursMinutesSeconds(hours, minutes, seconds);
}
};
/**
* 解析 數字
* @param tz 時區
* @param pos 起始位置
* @param precededByColon 是否有:
* @returns {number} 解析後的結果
*/
function parseNumber(tz, pos, precededByColon) {
if (precededByColon && tz.charAt(pos - ) != ":") {//檢驗 格式為:+08:00
throw new Error("Invalid ID for ZoneOffset, colon not found when expected: " + tz);
}
let ch1 = tz.charCodeAt(pos);
let ch2 = tz.charCodeAt(pos + );
if (String.fromCharCode(ch1) < "0" || String.fromCharCode(ch1) > "9" ||
String.fromCharCode(ch2) < "0" || String.fromCharCode(ch2) > "9") {
throw new Error("Invalid ID for ZoneOffset, non numeric characters found: " + tz);
}
return (ch1 - ) * + (ch2 - );
}
function ofHoursMinutesSeconds(hours, minutes, seconds) {
validate(hours, minutes, seconds);
let totalS = totalSeconds(hours, minutes, seconds);
return ofTotalSeconds(totalS);
}
function ofTotalSeconds(totalS) {
// 取本地時間
let localtime = new Date();
// 取本地毫秒數
let localmesc = localtime.getTime();
// 取本地時區與格林尼治所在時區的偏差毫秒數
let localOffset = localtime.getTimezoneOffset() * ;
// 反推得到格林尼治時間
let utc = localOffset + localmesc;
// 得到指定時區時間
let calctime = utc + (totalS*);
return new Date(calctime);
}
/**
* 計算秒數
* @param hours 小時
* @param minutes 分鐘
* @param seconds 秒
* @returns {*} 總共多少秒
*/
function totalSeconds(hours, minutes, seconds) {
return hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
}
/**
* Validates the offset fields.
* 驗證時間偏移量字段
* @param hours in hours, from -18 to +18
* @param minutes in minutes, from 0 to ±59
* @param seconds in seconds, from 0 to ±59
* @throws Error if the offset is not in the required range
*/
function validate(hours, minutes, seconds) {
if (hours < - || hours > ) {
throw new Error("Zone offset hours not in valid range: value " + hours +
" is not in the range -18 to 18");
}
if (hours > ) {
if (minutes < || seconds < ) {
throw new Error("Zone offset minutes and seconds must be positive because hours is positive");
}
} else if (hours < ) {
if (minutes > || seconds > ) {
throw new Error("Zone offset minutes and seconds must be negative because hours is negative");
}
} else if ((minutes > && seconds < ) || (minutes < && seconds > )) {
throw new Error("Zone offset minutes and seconds must have the same sign");
}
if (Math.abs(minutes) > ) {
throw new Error("Zone offset minutes not in valid range: abs(value) " +
Math.abs(minutes) + " is not in the range 0 to 59");
}
if (Math.abs(seconds) > ) {
throw new Error("Zone offset seconds not in valid range: abs(value) " +
Math.abs(seconds) + " is not in the range 0 to 59");
}
if (Math.abs(hours) == && (Math.abs(minutes) > || Math.abs(seconds) > )) {
throw new Error("Zone offset not in valid range: -18:00 to +18:00");
}
}