时区转换工具+PWA离线网页
时区转换工具+PWA离线网页
一、时区转换工具对比
工具 | 说明 |
---|---|
Date | 原生 JS API,有限的时区支持,无法指定时区,仅使用本地时区。 |
Intl.DateTimeFormat | 原生格式化显示,可指定时区,但不能修改时区逻辑。 |
luxon | 强烈推荐,现代、轻量、功能强,原生支持时区、时间戳、格式化等。 |
dayjs + timezone 插件 | 类似 moment,更现代,但时区支持需插件。 |
moment-timezone | 功能全面但体积大,moment 官方已不推荐用于新项目。 |
二、Luxon 使用示例
1. 美国时间 -> 中国时间
import { DateTime } from 'luxon'
const usTime = DateTime.fromISO('2025-04-01T11:11:00', { zone: 'America/Los_Angeles' })
const timestamp = usTime.toMillis()
const cnTime = usTime.setZone('Asia/Shanghai')
console.log('美国时间:', usTime.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ'))
console.log('时间戳:', timestamp)
console.log('对应的中国时间:', cnTime.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ'))
美国时间:2025-04-01 11:11:00 GMT-7
时间戳:1743521460000
对应的中国时间:2025-04-02 02:11:00 GMT+8
2. 中国时间 -> 美国时间
const cn = DateTime.fromISO('2025-04-01T11:11:00', { zone: 'Asia/Shanghai' })
const us = cn.setZone('America/Los_Angeles')
console.log('中国时间:', cn.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ'))
console.log('对应的美国时间:', us.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ'))
console.log('时间戳(UTC):', cn.toMillis())
3. 转换逻辑总结
场景 | 方法 |
---|---|
指定时区的时间 → 时间戳 | DateTime.fromISO(...).toMillis() |
时间戳 → 指定时区时间 | DateTime.fromMillis(...).setZone(...) |
不同时区之间转换 | .setZone(...) |
时间格式化 | .toFormat('yyyy-MM-dd HH:mm:ss') 等 |
4. 常用时区 ID 表
名称 | IANA 时区 ID |
---|---|
北京/上海(Asia/Shanghai) | Asia/Shanghai |
香港(Asia/Hong_Kong) | Asia/Hong_Kong |
日本(Asia/Tokyo) | Asia/Tokyo |
韩国(Asia/Seoul) | Asia/Seoul |
新加坡(Asia/Singapore) | Asia/Singapore |
印度(Asia/Kolkata) | Asia/Kolkata |
美国西部 - 洛杉矶(America/Los_Angeles) | America/Los_Angeles |
美国中部 - 芝加哥(America/Chicago) | America/Chicago |
美国东部 - 纽约(America/New_York) | America/New_York |
英国(Europe/London) | Europe/London |
德国(Europe/Berlin) | Europe/Berlin |
法国(Europe/Paris) | Europe/Paris |
澳大利亚 - 悉尼(Australia/Sydney) | Australia/Sydney |
新西兰(Pacific/Auckland) | Pacific/Auckland |
夏威夷(Pacific/Honolulu) | Pacific/Honolulu |
UTC(协调世界时) | UTC |
三、时区转换脚本
1. NodeJS 脚本(使用 luxon)
const { DateTime } = require('luxon')
function convertTime({
timeStr = '2025-04-01 11:11:00',
fromZone = 'America/Los_Angeles',
toZone = 'Asia/Shanghai'
}) {
const fromTime = DateTime.fromFormat(timeStr, 'yyyy-MM-dd HH:mm:ss', { zone: fromZone })
const toTime = fromTime.setZone(toZone)
console.log(`原始时间 (${fromZone}):`, fromTime.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ'))
console.log(`时间戳(UTC 毫秒):`, fromTime.toMillis())
console.log(`转换后 (${toZone}):`, toTime.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ'))
}
// 修改这里的参数即可
convertTime({
timeStr: '2025-04-01 11:11:00',
fromZone: 'America/Los_Angeles',
toZone: 'Asia/Shanghai'
})
2. Python 脚本(使用 pytz)
pip install pytz
from datetime import datetime
import pytz
def convert_time(time_str='2025-04-01 11:11:00', from_zone='America/Los_Angeles', to_zone='Asia/Shanghai'):
from_tz = pytz.timezone(from_zone)
to_tz = pytz.timezone(to_zone)
naive_dt = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
from_dt = from_tz.localize(naive_dt)
to_dt = from_dt.astimezone(to_tz)
print(f'原始时间 ({from_zone}): {from_dt.strftime("%Y-%m-%d %H:%M:%S %Z%z")}')
print(f'时间戳(UTC 秒): {int(from_dt.timestamp())}')
print(f'转换后 ({to_zone}): {to_dt.strftime("%Y-%m-%d %H:%M:%S %Z%z")}')
# 修改参数即可
convert_time(
time_str='2025-04-01 11:11:00',
from_zone='America/Los_Angeles',
to_zone='Asia/Shanghai'
)
四、网页小工具
使用 Luxon + HTML 原生控件制作的小工具,支持:
- 输入时间
- 原始/目标时区选择
- 时间戳显示
- 一键复制
1. 代码展示
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title> 时区时间转换工具</title>
<script src="https://cdn.jsdelivr.net/npm/luxon@3/build/global/luxon.min.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
padding: 2rem;
max-width: 700px;
margin: auto;
background: #f8f9fa;
}
h2 {
text-align: center;
margin-bottom: 2rem;
}
label {
font-weight: bold;
margin-top: 1rem;
display: block;
}
input, select, button {
width: 100%;
padding: 0.6rem;
margin: 0.4rem 0 1rem;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 1rem;
}
button {
background: #007bff;
color: white;
cursor: pointer;
border: none;
transition: background 0.3s;
}
button:hover {
background: #0056b3;
}
.result {
background: #fff;
border-left: 5px solid #007bff;
padding: 1rem;
margin-top: 1rem;
border-radius: 5px;
white-space: pre-wrap;
font-size: 0.95rem;
}
.error {
color: red;
margin-top: 1rem;
}
.copy-btn {
margin-top: 0.5rem;
background: #28a745;
}
.copy-btn:hover {
background: #1e7e34;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 2rem;
background: #fff;
}
th, td {
border: 1px solid #ddd;
padding: 0.6rem;
text-align: left;
}
th {
background-color: #007bff;
color: white;
}
</style>
</head>
<body>
<h2> 时区转换小工具</h2>
<label for="inputDate">选择时间</label>
<input type="datetime-local" id="inputDate" />
<label for="fromZone">原始时区</label>
<select id="fromZone"></select>
<label for="toZone">目标时区</label>
<select id="toZone"></select>
<button onclick="convertTime()">转换时间</button>
<div class="result" id="output"> 转换结果将在这里显示</div>
<button class="copy-btn" onclick="copyResult()"> 复制结果</button>
<div class="error" id="error"></div>
<script>
const { DateTime } = luxon
const timezones = [
{ label: '北京(Asia/Shanghai)', value: 'Asia/Shanghai' },
{ label: '香港(Asia/Hong_Kong)', value: 'Asia/Hong_Kong' },
{ label: '日本(Asia/Tokyo)', value: 'Asia/Tokyo' },
{ label: '韩国(Asia/Seoul)', value: 'Asia/Seoul' },
{ label: '新加坡(Asia/Singapore)', value: 'Asia/Singapore' },
{ label: '印度(Asia/Kolkata)', value: 'Asia/Kolkata' },
{ label: '美国西部 - 洛杉矶(America/Los_Angeles)', value: 'America/Los_Angeles' },
{ label: '美国中部 - 芝加哥(America/Chicago)', value: 'America/Chicago' },
{ label: '美国东部 - 纽约(America/New_York)', value: 'America/New_York' },
{ label: '英国(Europe/London)', value: 'Europe/London' },
{ label: '德国(Europe/Berlin)', value: 'Europe/Berlin' },
{ label: '法国(Europe/Paris)', value: 'Europe/Paris' },
{ label: '澳大利亚 - 悉尼(Australia/Sydney)', value: 'Australia/Sydney' },
{ label: '新西兰(Pacific/Auckland)', value: 'Pacific/Auckland' },
{ label: '夏威夷(Pacific/Honolulu)', value: 'Pacific/Honolulu' },
{ label: 'UTC(协调世界时)', value: 'UTC' },
]
function renderTimezoneOptions() {
const fromSelect = document.getElementById('fromZone')
const toSelect = document.getElementById('toZone')
const tableBody = document.getElementById('timezoneTable')
timezones.forEach(({ label, value }) => {
const opt1 = new Option(label, value)
const opt2 = new Option(label, value)
fromSelect.appendChild(opt1)
toSelect.appendChild(opt2)
})
fromSelect.value = 'Asia/Shanghai'
toSelect.value = 'America/Los_Angeles'
}
document.addEventListener('DOMContentLoaded', () => {
renderTimezoneOptions()
const now = new Date()
const local = now.toISOString().slice(0, 16)
document.getElementById('inputDate').value = local
})
function convertTime() {
const input = document.getElementById('inputDate').value
const fromZone = document.getElementById('fromZone').value
const toZone = document.getElementById('toZone').value
const output = document.getElementById('output')
const error = document.getElementById('error')
error.textContent = ''
if (!input) {
error.textContent = ' 请选择一个时间'
return
}
try {
const dt = DateTime.fromISO(input, { zone: fromZone })
const toTime = dt.setZone(toZone)
const result = `
原始时间(${fromZone}):
${dt.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ')}
时间戳(UTC 毫秒):
${dt.toMillis()}
️ 转换后时间(${toZone}):
${toTime.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ')}
`.trim()
output.textContent = result
}
catch (e) {
error.textContent = ' 转换失败,请检查输入'
}
}
function copyResult() {
const result = document.getElementById('output').textContent
if (!result || result.includes('将在这里显示'))
return
navigator.clipboard.writeText(result).then(() => {
alert(' 已复制到剪贴板!')
})
}
</script>
</body>
</html>
2. 示例截图
五、PWA 应用支持
1. PWA 结构
.
├── icons
│ ├── time_192.png
│ └── time_512.png
├── index.html
├── luxon.min.js
├── manifest.json
└── service-worker.js
2. manifest.json
用于定义名称、图标、启动方式等:
{
"name": "时区时间转换工具",
"short_name": "时区转换",
"start_url": "./index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#007bff",
"description": "支持多时区时间互转、时间戳生成的轻量工具",
"icons": [
{
"src": "icons/time_192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/time_512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
3. service-worker.js
实现核心缓存功能,支持离线访问:
const CACHE_NAME = 'timezone-converter-0.0.1'
const urlsToCache = [
'./',
'./index.html',
'./manifest.json',
'./service-worker.js',
'./icons/time_192.png',
'./icons/time_512.png',
'./luxon.min.js'
]
// 安装时预缓存核心资源
self.addEventListener('install', event => {
self.skipWaiting()
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
)
})
// 激活时清除旧缓存
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k)))
)
)
self.clients.claim()
})
// 拦截所有请求,优先从缓存读取,失败则网络请求
self.addEventListener('fetch', event => {
const request = event.request
event.respondWith(
caches.match(request).then(cachedResponse => {
if (cachedResponse) return cachedResponse
return fetch(request)
.then(networkResponse => {
if (
networkResponse &&
networkResponse.status === 200 &&
request.url.startsWith(self.location.origin)
) {
const cloned = networkResponse.clone()
caches.open(CACHE_NAME).then(cache => {
cache.put(request, cloned)
})
}
return networkResponse
})
.catch(() => {
if (request.headers.get('accept')?.includes('text/html')) {
return caches.match('./index.html')
}
})
})
)
})
4. html 文件
整合 Luxon + PWA 注册逻辑
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title> 时区时间转换工具1</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#007bff" />
<link rel="manifest" href="manifest.json" />
<link rel="icon" href="icons/time_192.png" />
<link rel="apple-touch-icon" href="icons/time_512.png" />
<script src="./luxon.min.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
padding: 2rem;
max-width: 700px;
margin: auto;
background: #f8f9fa;
}
h2 {
text-align: center;
margin-bottom: 2rem;
}
label {
font-weight: bold;
margin-top: 1rem;
display: block;
}
input, select, button {
width: 100%;
padding: 0.6rem;
margin: 0.4rem 0 1rem;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 1rem;
}
button {
background: #007bff;
color: white;
cursor: pointer;
border: none;
transition: background 0.3s;
}
button:hover {
background: #0056b3;
}
.result {
background: #fff;
border-left: 5px solid #007bff;
padding: 1rem;
margin-top: 1rem;
border-radius: 5px;
white-space: pre-wrap;
font-size: 0.95rem;
}
.error {
color: red;
margin-top: 1rem;
}
.copy-btn {
margin-top: 0.5rem;
background: #28a745;
}
.copy-btn:hover {
background: #1e7e34;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 2rem;
background: #fff;
}
th, td {
border: 1px solid #ddd;
padding: 0.6rem;
text-align: left;
}
th {
background-color: #007bff;
color: white;
}
</style>
</head>
<body>
<h2> 时区转换小工具</h2>
<label for="inputDate">选择时间</label>
<input type="datetime-local" id="inputDate" />
<label for="fromZone">原始时区</label>
<select id="fromZone"></select>
<label for="toZone">目标时区</label>
<select id="toZone"></select>
<button onclick="convertTime()">转换时间</button>
<div class="result" id="output"> 转换结果将在这里显示</div>
<button class="copy-btn" onclick="copyResult()"> 复制结果</button>
<div class="error" id="error"></div>
<script>
const { DateTime } = luxon
const timezones = [
{ label: '北京(Asia/Shanghai)', value: 'Asia/Shanghai' },
{ label: '香港(Asia/Hong_Kong)', value: 'Asia/Hong_Kong' },
{ label: '日本(Asia/Tokyo)', value: 'Asia/Tokyo' },
{ label: '韩国(Asia/Seoul)', value: 'Asia/Seoul' },
{ label: '新加坡(Asia/Singapore)', value: 'Asia/Singapore' },
{ label: '印度(Asia/Kolkata)', value: 'Asia/Kolkata' },
{ label: '美国西部 - 洛杉矶(America/Los_Angeles)', value: 'America/Los_Angeles' },
{ label: '美国中部 - 芝加哥(America/Chicago)', value: 'America/Chicago' },
{ label: '美国东部 - 纽约(America/New_York)', value: 'America/New_York' },
{ label: '英国(Europe/London)', value: 'Europe/London' },
{ label: '德国(Europe/Berlin)', value: 'Europe/Berlin' },
{ label: '法国(Europe/Paris)', value: 'Europe/Paris' },
{ label: '澳大利亚 - 悉尼(Australia/Sydney)', value: 'Australia/Sydney' },
{ label: '新西兰(Pacific/Auckland)', value: 'Pacific/Auckland' },
{ label: '夏威夷(Pacific/Honolulu)', value: 'Pacific/Honolulu' },
{ label: 'UTC(协调世界时)', value: 'UTC' }
]
function renderTimezoneOptions() {
const fromSelect = document.getElementById('fromZone')
const toSelect = document.getElementById('toZone')
timezones.forEach(({ label, value }) => {
const opt1 = new Option(label, value)
const opt2 = new Option(label, value)
fromSelect.appendChild(opt1)
toSelect.appendChild(opt2)
})
fromSelect.value = 'Asia/Shanghai'
toSelect.value = 'America/Los_Angeles'
}
function convertTime() {
const input = document.getElementById('inputDate').value
const fromZone = document.getElementById('fromZone').value
const toZone = document.getElementById('toZone').value
const output = document.getElementById('output')
const error = document.getElementById('error')
error.textContent = ''
if (!input) {
error.textContent = ' 请选择一个时间'
return
}
try {
const dt = DateTime.fromISO(input, { zone: fromZone })
const toTime = dt.setZone(toZone)
const result = `
原始时间(${fromZone}):
${dt.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ')}
时间戳(UTC 毫秒):
${dt.toMillis()}
️ 转换后时间(${toZone}):
${toTime.toFormat('yyyy-MM-dd HH:mm:ss ZZZZ')}
`.trim()
output.textContent = result
} catch (e) {
error.textContent = ' 转换失败,请检查输入'
}
}
function copyResult() {
const result = document.getElementById('output').textContent
if (!result || result.includes('将在这里显示')) return
navigator.clipboard.writeText(result).then(() => {
alert(' 已复制到剪贴板!')
})
}
// 初始化
document.addEventListener('DOMContentLoaded', () => {
renderTimezoneOptions()
const now = new Date()
const local = now.toISOString().slice(0, 16)
document.getElementById('inputDate').value = local
})
// 注册 PWA service worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log(' Service Worker 注册成功'))
.catch(err => console.log(' 注册失败:', err))
})
}
</script>
</body>
</html>
5. Live server 启动
启动完成安装到本地即可
六、总结
本项目对比并选用 Luxon 实现多时区转换,支持各时区时间互转。
提供 NodeJS 与 Python 脚本、网页小工具及 PWA 应用,功能完整、结构清晰。
适用于快速使用、系统集成或离线访问,具备良好扩展性。
时区转换工具+PWA离线网页的更多相关文章
- 音乐解锁工具v1.10.3,QQ音乐,网易云,酷狗音乐格式转换工具,ncm转mp3,kgm转mp3,kgma转mp3,mgg转mp3,mflac转mp3,qmc转mp3,xm转mp3,kwm转mp3
现在主流的听歌软件开会员听歌和下载单曲已经是两套业务了,即使开了会员下载的单曲也只能用固定的播放器进行播放,不能使用其他软件播放. 目前QQ音乐.网抑云音乐.酷狗等会员歌曲下载后都不再是传统的音频文件 ...
- web字体格式及几种在线格式转换工具介绍
原文地址:http://blog.csdn.net/xiaolongtotop/article/details/8316554 目前,文字信息仍是网站最主要的内容,随着CSS3技术的不断成熟,Web字 ...
- 推荐一款免费的PDF转换工具 | PDFCandy
相信大家在用的PDF转换工具也很多,下面良心推荐这款软件(PDFCandy)给大家,方便在今后的工作中进行运用.提高大家的工作效率. PDFCandy分为两种:网页端和客户端.(根据大家的喜好度来进行 ...
- 爬虫 Http请求,urllib2获取数据,第三方库requests获取数据,BeautifulSoup处理数据,使用Chrome浏览器开发者工具显示检查网页源代码,json模块的dumps,loads,dump,load方法介绍
爬虫 Http请求,urllib2获取数据,第三方库requests获取数据,BeautifulSoup处理数据,使用Chrome浏览器开发者工具显示检查网页源代码,json模块的dumps,load ...
- 使用wget工具抓取网页和图片 及 相关工具几个
想保存一些网页,最后找到这 wget 的 shell脚本,虽然不是太理想,亲测可用呢. 使用wget工具抓取网页和图片 来源 https://my.oschina.net/freestyletim ...
- SQL Server全时区转换
SQL Server全时区转换 假如你的应用程序是跨国(例如跨国银行交易)使用的话,那么数据库的一些国际化特性支持可以说是非常重要 其中最常见的就是各国时区上的差异,由于SQL Server getd ...
- Unicode编码解码在线转换工具
// Unicode编码解码在线转换工具 Unicode 是基于通用字符集(Universal Character Set)的标准来发展,并且同时也以书本的形式(The Unicode Standar ...
- android px,dp,sp大小转换工具
package com.voole.playerlib.util; import android.content.Context; /** * Android大小单位转换工具类<br/> ...
- Json与javaBean之间的转换工具类
/** * Json与javaBean之间的转换工具类 * * {@code 现使用json-lib组件实现 * 需要 * json-lib-2.4-jdk15.jar * ...
- Rsa加解密Java、C#、php通用代码 密钥转换工具
之前发了一篇"TripleDes的加解密Java.C#.php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主 ...
随机推荐
- 插入dp学习笔记
定义 插入 \(\text{dp}\) 适用于计数.求最优解且具有选择.排列元素过程等题目. 插入 \(\text{dp}\) 大致分为两类: 乱搞型:状态定义天马行空,但始终围绕着将新元素插入到旧元 ...
- ESP32 idf常用脚本命令及git命令
一.Linux环境 1.下载并安装相关的工具 ./install.sh 2.添加ESP-IDF工具到PATH中 . ./export.sh 3.打开配置界面 idf.py menuconfig 4.设 ...
- 微信小程序slot(二)
在组件的 wxml 中可以包含 slot 节点,用于承载组件使用者提供的 wxml 结构. 默认情况下,一个组件的 wxml 中只能有一个 slot .需要使用多 slot 时,可以在组件 js 中声 ...
- SQL SERVER日常运维(二)
以下语句请使用SA用户或者有DBA权限的用户进行执行,否则可能会出现权限不足报错. 查看当前用户查看当前用户 select system_user; 检查SQL Agent是否开启 IF EXISTS ...
- SOUI4新版本的日志系统介绍
原来的日志输出宏用法有点奇怪,感觉总是不够理想.这近有点时间终于把它重整了一下. 以前的用法就不介绍了,重点介绍一下新版本的用法. 在SOUI中使用的日志系统包含两个部分:日志输出宏及日志到文件的打印 ...
- 斩获“年度突破成果”奖!天翼云构建强大AI算力基础,制胜人工智能新时代
8月18-19日,2023中国算力大会在宁夏银川举办.在大会"年度突破成果"发布环节,中国电信天翼云<基于异构多云环境下的息壤算力调度应用实践>荣获2023中国算力大会 ...
- AllPairs工具助力正交表测试用例设计
AllPairs工具助力正交表测试用例设计 正交表法是一种高效的测试方法,特别适用于软件测试中需要处理多个控件及其多种取值组合的情况.以下是对正交表法的详细解释: 一.正交表法概述 正交表法是一种利用 ...
- iceberg调研-查询Iceberg表流程
1.查询表结构 show create table data_lake_ods.dws_service_subclazz_lesson_user_learn_stat_rt_v2 CREATE TAB ...
- CSP 2024 游记
初赛 Day -1 唐,rp--了. 上午语文正卷满分,然后作文挂完了靠.我没想到我作文能挂到 40pts. 吃饭的时候 gcy 说了什么奇怪的东西,然后喷饭爆金币了,社死现场.吃饭的时候还 tm 咬 ...
- Luogu P3177 树上染色 [ 蓝 ] [ 树形 dp ] [ 贡献思维 ]
一道很好的树形 dp !!!!! 树上染色. 错误思路 定义 \(dp[u][i]\) 表示以 \(u\) 为根的子树中,把 \(i\) 个点染成黑色的最大收益. 但这样写,就在转移的时候必须枚举每一 ...