time-zone-conversion
Version:
time-zone-conversion
103 lines (96 loc) • 4 kB
text/typescript
/**
* @param dateTime
* @returns
*/
const dateTimeFormatter = (dateTime: string | number | Date): Date => {
let _dateTime: Date;
// 由于浏览器之间的差异与不一致性,强烈不推荐使用Date构造函数来解析日期字符串 (或使用与其等价的Date.parse)
if (typeof dateTime === "string") {
const regexFormats: RegExp[] = [
/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}$/, // YYYY-MM-DD hh:mm:ss
/^\d{4}\/\d{2}\/\d{2}\s+\d{2}:\d{2}:\d{2}$/, // YYYY/MM/DD hh:mm:ss
/^\d{2}-\d{2}-\d{4}\s+\d{2}:\d{2}:\d{2}$/, // DD-MM-YYYY hh:mm:ss
/^\d{2}\/\d{2}\/\d{4}\s+\d{2}:\d{2}:\d{2}$/, // DD/MM/YYYY hh:mm:ss
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/, // ISO 8601: YYYY-MM-DDThh:mm:ssZ
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/, // ISO 8601 with milliseconds: YYYY-MM-DDThh:mm:ss.sssZ
];
const index: number = regexFormats.findIndex((regex) => regex.exec(dateTime) !== null);
if (index > -1) {
const [year, month, day, hours, minutes, seconds] = regexFormats[index].exec(dateTime) as string[];
if (index <= 3) {
_dateTime = new Date(Number(year), Number(month) - 1, Number(day), Number(hours), Number(minutes), Number(seconds));
} else {
_dateTime = new Date(Date.parse(dateTime));
}
} else {
throw new Error("Invalid date format");
}
} else if (typeof dateTime === "number") {
_dateTime = new Date(dateTime);
} else {
_dateTime = dateTime;
}
return _dateTime;
};
/**
* 格式化时间
* 调用formatDate(strDate, 'yyyy-MM-dd');
* @param strDate(中国标准时间、时间戳等)
* @param strFormat(返回格式)
*/
export const formatDate = (strDate: any, strFormat?: any) => {
if (!strDate) {
return;
}
if (!strFormat) {
strFormat = "yyyy-MM-dd";
}
switch (typeof strDate) {
case "string":
strDate = new Date(strDate.replace(/-/, "/"));
break;
case "number":
strDate = new Date(strDate);
break;
}
if (strDate instanceof Date) {
const dict: any = {
yyyy: strDate.getFullYear(),
M: strDate.getMonth() + 1,
d: strDate.getDate(),
H: strDate.getHours(),
m: strDate.getMinutes(),
s: strDate.getSeconds(),
MM: ("" + (strDate.getMonth() + 101)).substr(1),
dd: ("" + (strDate.getDate() + 100)).substr(1),
HH: ("" + (strDate.getHours() + 100)).substr(1),
mm: ("" + (strDate.getMinutes() + 100)).substr(1),
ss: ("" + (strDate.getSeconds() + 100)).substr(1),
};
return strFormat.replace(/(yyyy|MM?|dd?|HH?|mm?|ss?)/g, function () {
return dict[arguments[0]];
});
}
};
/**
* 日期时间的时区转换
* @param {string|number|Date} dateTime 日期时间
* @param {string} [sourceZone="GMT+0"] sourceZone 待转换时间的时区,仅支持GMT(默认东八区)
* @param {string} [targetZone="GMT+0"] targetZone 目标时区,仅支持GMT(默认零时区)
* @param {string} [strFormat="YYYY-MM-DD hh:mm:ss"] strFormat 返回值序列化格式
* @returns {string}
*/
const timeZoneParse = (dateTime: Date, sourceZone: string, targetZone: string = "GMT+0", strFormat: string = "YYYY-MM-DD hh:mm:ss"): string => {
if (!sourceZone.includes("GMT") || !targetZone.includes("GMT")) {
throw new Error("SourceZone or targetZone only the GMT time zone format is supported, example 'GMT+8'");
}
const _dateTime = dateTimeFormatter(dateTime);
const sourceOffset = parseInt(sourceZone.replace("GMT", "")) * 60;
const targetOffset = parseInt(targetZone.replace("GMT", "")) * 60;
// 根据源时区偏移量调整时间
const sourceTime = new Date(_dateTime.getTime() + sourceOffset * 60000);
// 根据目标时区偏移量调整时间
const targetTime = new Date(sourceTime.getTime() - targetOffset * 60000);
return formatDate(targetTime, strFormat);
};
export default timeZoneParse;