NodeJS 获取指定时区的时间

/**
 * 获取指定时区的时间
 * @param offset 时区
 * @returns {Date} 指定时区的 时间信息
 */
module.exports.getZoneTime = (offset)=> {
    // 取本地时间
    let localtime = new Date();
    // 取本地毫秒数
    let localmesc = localtime.getTime();
    // 取本地时区与格林尼治所在时区的偏差毫秒数
    let localOffset = localtime.getTimezoneOffset() * 60000;
    // 反推得到格林尼治时间
    let utc = localOffset + localmesc;
    // 得到指定时区时间
    let calctime = utc + (3600000 * offset);
    return new Date(calctime);
};

带验证 方法 参考Java实现

/**
 * 检查时区 函数  错误时区就返回+0000
 * @param tz 时区 参考JAVA实现方法
 */
module.exports.checkTz = (tz) => {
    if (!tz) {
        tz = "+0000";
    }
    if ('-' != tz.charAt(0) && '+' != tz.charAt(0)) {
        tz = "+" + tz;
    }
    let hours, minutes, seconds;
    switch (tz.length) {
        case 2:
            tz = tz.charAt(0) + "0" + tz.charAt(1);
        case 3:
            hours = parseNumber(tz, 1, false);
            minutes = 0;
            seconds = 0;
            break;
        case 5:
            hours = parseNumber(tz, 1, false);
            minutes = parseNumber(tz, 3, false);
            seconds = 0;
            break;
        case 6:
            hours = parseNumber(tz, 1, false);
            minutes = parseNumber(tz, 4, true);
            seconds = 0;
            break;
        case 7:
            hours = parseNumber(tz, 1, false);
            minutes = parseNumber(tz, 3, false);
            seconds = parseNumber(tz, 5, false);
            break;
        case 9:
            hours = parseNumber(tz, 1, false);
            minutes = parseNumber(tz, 4, true);
            seconds = parseNumber(tz, 7, true);
            break;
        default:
            throw new Error("Invalid ID for ZoneOffset, invalid format: " + tz);
    }
    let first = tz.charAt(0);
    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 - 1) != ":") {//检验 格式为:+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 + 1);
    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 - 48) * 10 + (ch2 - 48);
}

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() * 60000;
    // 反推得到格林尼治时间
    let utc = localOffset + localmesc;
    // 得到指定时区时间
    let calctime = utc + (totalS*1000);
    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 &plusmn;59
 * @param seconds   in seconds, from 0 to &plusmn;59
 * @throws Error if the offset is not in the required range
 */
function validate(hours, minutes, seconds) {
    if (hours < -18 || hours > 18) {
        throw new Error("Zone offset hours not in valid range: value " + hours +
            " is not in the range -18 to 18");
    }
    if (hours > 0) {
        if (minutes < 0 || seconds < 0) {
            throw new Error("Zone offset minutes and seconds must be positive because hours is positive");
        }
    } else if (hours < 0) {
        if (minutes > 0 || seconds > 0) {
            throw new Error("Zone offset minutes and seconds must be negative because hours is negative");
        }
    } else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
        throw new Error("Zone offset minutes and seconds must have the same sign");
    }
    if (Math.abs(minutes) > 59) {
        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) > 59) {
        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) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
        throw new Error("Zone offset not in valid range: -18:00 to +18:00");
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值