getDateInTimezone.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /**
  2. * 将时区偏移小时转换为 ±HHMM 格式
  3. * @param {number|string} offset 如 8, -4, "+8", "-04"
  4. * @returns {string} 如 "+0800", "-0400"
  5. */
  6. const formatTimezoneOffset = (offset) => {
  7. const hours = Number(offset);
  8. if (Number.isNaN(hours)) {
  9. throw new Error('Invalid timezone offset');
  10. }
  11. const sign = hours >= 0 ? '+' : '-';
  12. const hh = String(Math.abs(hours)).padStart(2, '0');
  13. return `${sign}${hh}00`;
  14. }
  15. /**
  16. * 判断日期是否无效
  17. * @param {Date} date
  18. * @returns {boolean}
  19. */
  20. const isInvalidDate = (date) => {
  21. return date instanceof Date && Number.isNaN(date.getTime());
  22. }
  23. /**
  24. * 获取指定时区当前日期或时间
  25. * @param {number} offset - 时区相对 UTC 的偏移(例如:-4 表示 GMT-4)
  26. * @param {number} timestamp - 时间戳(可选)
  27. * @param {boolean} [withTime=false] - 是否返回完整时间(默认只返回日期)
  28. * @returns {string} 格式化的日期或时间字符串
  29. */
  30. const getDateInTimezone = (offset, timestamp, withTime=false) => {
  31. offset = Number(offset);
  32. if (Number.isNaN(offset)) {
  33. throw new Error('Invalid timezone offset');
  34. }
  35. if (typeof(timestamp) === 'undefined') {
  36. timestamp = Date.now();
  37. }
  38. else if (typeof(timestamp) === 'boolean') {
  39. withTime = timestamp;
  40. timestamp = Date.now();
  41. }
  42. else if (typeof(timestamp) === 'string') {
  43. const date = new Date(timestamp);
  44. if (isInvalidDate(date)) {
  45. throw new Error('Invalid timestamp');
  46. }
  47. timestamp = date.getTime();
  48. }
  49. else if (typeof(timestamp) !== 'number') {
  50. throw new Error('Invalid timestamp');
  51. }
  52. const nowUTC = new Date(timestamp);
  53. const targetTime = new Date(nowUTC.getTime() + offset * 60 * 60 * 1000);
  54. const year = targetTime.getUTCFullYear();
  55. const month = String(targetTime.getUTCMonth() + 1).padStart(2, '0');
  56. const day = String(targetTime.getUTCDate()).padStart(2, '0');
  57. if (!withTime) {
  58. return `${year}-${month}-${day}`;
  59. }
  60. const hours = String(targetTime.getUTCHours()).padStart(2, '0');
  61. const minutes = String(targetTime.getUTCMinutes()).padStart(2, '0');
  62. const seconds = String(targetTime.getUTCSeconds()).padStart(2, '0');
  63. return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}${formatTimezoneOffset(offset)}`;
  64. }
  65. export default getDateInTimezone;