因为开发的APP需要在国外进行使用,数据库时间统一保存为东八区(Asia/Shanghai
),所以在APP端需要对时间进行转换,显示为用户当前所在的时区,严格来说应该是用户手机设置的时区,而不是根据地理位置确认的时区。
安装插件
dayjs
官网:day.js.org
npm install dayjs
引用依赖
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
// 启用插件
dayjs.extend(utc);
dayjs.extend(timezone);
注意:uni-app
运行在多端环境(小程序、H5、App等),某些端可能不支持 Intl
。可以使用 Date.prototype.getTimezoneOffset()
结合 dayjs
来实现时区计算,所以下面介绍使用 Intl
和不使用 Intl
的两种实现方式。
使用 Intl
(代码更简单)
这种方式需要依赖 Intl
内置对象,如果环境不支持,会出现 Intl is not defined
的错误
/**
* 将指定时区的时间转换为目标时区的时间
* @param {string} targetTime - 目标时间,格式 "yyyy-MM-dd HH:mm:ss"
* @param {string} fromTimeZone - 目标时间的时区 (如 "Asia/Shanghai")
* @param {string} toTimeZone - 结果时间的时区 (如 "America/New_York")
* @returns {string} - 转换后的时间,格式 "yyyy-MM-dd HH:mm:ss"
*/
const convertTimeZone = (targetTime, fromTimeZone, toTimeZone) => {
return dayjs.tz(targetTime, "YYYY-MM-DD HH:mm:ss", fromTimeZone)
.tz(toTimeZone)
.format("YYYY-MM-DD HH:mm:ss");
};
// 示例
console.log(convertTimeZone("2025-01-01 12:00:00", "Asia/Shanghai", "Europe/London"));
// 结果:"2025-01-01 04:00:00"
不使用 Intl
(兼容性更好)
const getCurrentTimeZone = () => {
const offset = new Date().getTimezoneOffset(); // 以分钟为单位,东八区是 -480
const offsetHours = -offset / 60; // 转换为小时
const sign = offsetHours >= 0 ? "+" : "-";
const formattedOffset = `${sign}${String(Math.abs(offsetHours)).padStart(2, "0")}:00`;
return `UTC${formattedOffset}`;
};
/**
* 将指定时区的时间转换为目标时区的时间
* @param {string} targetTime - 目标时间,格式 "yyyy-MM-dd HH:mm:ss"
* @param {string} fromTimeZone - 目标时间的时区 (如 "UTC+08:00")
* @param {string} toTimeZone - 结果时间的时区 (如 "UTC-05:00")
* @returns {string} - 转换后的时间,格式 "yyyy-MM-dd HH:mm:ss"
*/
const convertTimeZone = (targetTime, fromTimeZone, toTimeZone) => {
// 解析 fromTimeZone 的 UTC 偏移量
const fromOffset = getTimeZoneOffset(fromTimeZone);
const toOffset = getTimeZoneOffset(toTimeZone);
// 计算时间差(分钟)
const offsetDiff = toOffset - fromOffset;
// 使用 dayjs 进行时间计算
return dayjs(targetTime, "YYYY-MM-DD HH:mm:ss")
.add(offsetDiff, "minute")
.format("YYYY-MM-DD HH:mm:ss");
};
/**
* 获取时区的 UTC 偏移量(分钟)
* @param {string} timeZoneStr - 时区表示,例如 "UTC+08:00" 或 "UTC-05:00"
* @returns {number} - 偏移量(分钟),例如 "+08:00" 返回 480
*/
const getTimeZoneOffset = (timeZoneStr) => {
const match = timeZoneStr.match(/UTC([+-])(\d{2}):(\d{2})/);
if (!match) return 0; // 默认 UTC+0
const sign = match[1] === "+" ? 1 : -1;
const hours = parseInt(match[2], 10);
const minutes = parseInt(match[3], 10);
return sign * (hours * 60 + minutes);
};
// **示例**
const CurrentTimeZone = getCurrentTimeZone(); // 例如: "UTC-05:00"
console.log(convertTimeZone("2025-01-01 12:00:00", "UTC+08:00", CurrentTimeZone));
// 结果:"2024-12-31 23:00:00"