英文:
change time base on timezone momen-timezone
问题
我想将所选的时间转换为用户配置文件中保存的时区,使用 moment-timezone 库。
我的本地系统时区是 PKT(巴基斯坦),用户在他的配置文件中保存的时区是 AEST(澳大利亚/悉尼)。因此,当用户选择时间时,我只希望将该时间转换为用户的时区,并发送到 API。
例如:
const time = "07:00";
const date = "06/13/2023";
const timezone = "Australian/Sydney";
moment(`${date} ${time}`).tz(timezone).format() // 2023-06-20T12:00:00+10:00
转换后的时间应该是上午 7 点 AEST,但库将其转换为中午 12 点。如果我将 moment 默认时区更改为用户配置文件时区,仍然无法获得正确的输出。
例如:
const time = "07:00";
const date = "06/13/2023";
const timezone = "Australian/Sydney";
moment.tz.setDefault(timezone)
moment(`${date} ${time}`).tz(timezone).format() // 2023-06-20T12:00:00+10:00
moment(`${date} ${time}`).format() // 2023-06-20T12:00:00+10:00
moment.tz(`${date} ${time}`, timezone).format() // 2023-06-20T17:00:00+10:00
您可以看到,没有一个输出是我想要实现的。如果 moment 不支持此功能,那么如果您告诉我其他库将会很有帮助。
英文:
i want to convert selected time into timezone saved in user profile using moment-timezone library
my local system timezone is PKT(pakistan) and user has saved timezone in his Profile is AEST(australian/sydney). so when user select time i just want that time in userTimezone and send in API.
e.g
const time = "07:00"
const date = "06/13/2023"
const timezone = "Australian/Sydney"
moment(`${date} ${time}`).tz(timezone).format() // 2023-06-20T12:00:00+10:00
converted time should be 7Am AESt but library has convert it into 12pm. if i change moment default timezone into user profile timezone then still i dont get correct output
e.g
const time = "07:00"
const date = "06/13/2023"
const timezone = "Australian/Sydney"
moment.tz.setDefault(timezone)
moment(`${date} ${time}`).tz(timezone).format() //2023-06-20T12:00:00+10:00
moment(`${date} ${time}`).format() //2023-06-20T12:00:00+10:00
moment.tz(`${date} ${time}`, timezone).format() // 2023-06-20T17:00:00+10:00
you can see none of the output is what i am trying to acheive. it would be greate if you let me know other library if moment does not support this.
答案1
得分: 0
// 使用以下npm包,"luxon"
// https://moment.github.io/luxon/api-docs/index.html
const { DateTime } = require("luxon");
const yourInputTime = "13:45:21";
const yourDateInput = "2023-06-25";
// 这些输入位于您的时区
// 现在您想要将它们转换成新加坡时区
// 您可以在以下链接中找到所有时区的完整列表
/* https://stackoverflow.com/questions/38399465/how-to-get-list-of-all-timezones-in-javascript/54500197#54500197 */
// 首先构建一个ISO字符串
const yourInputISO = `${yourDateInput}T${yourInputTime}`;
const convertedISO = DateTime.fromISO(yourInputISO).setZone("Asia/Singapore").toISO(); // 2023-06-25T15:45:21.000+08:00
const yourDesiredTime = convertedISO.split("T")[1].split(".")[0] // 15:45:21
英文:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
// use the following npm package, "luxon"
// https://moment.github.io/luxon/api-docs/index.html
const { DateTime } = require("luxon");
const yourInputTime = "13:45:21";
const yourDateInput = "2023-06-25";
// these inputs are in your timezone
// now you want to convert these to let's day Singapore timezone
// you can find the whole list of timezone from the following link
/* https://stackoverflow.com/questions/38399465/how-to-get-list-of-all-timezones-in-javascript/54500197#54500197 */
// first construct an ISO string
const yourInputISO = `${yourDateInput}T${yourInputTime}`;
const convertedISO = DateTime.fromISO(yourInputISO).setZone("Asia/Singapore").toISO(); // 2023-06-25T15:45:21.000+08:00
const yourDesiredTime = convertedISO.split("T")[1].split(".")[0] // 15:45:21
<!-- end snippet -->
答案2
得分: 0
开始阅读Intl Web/JS API的支持值,然后检查可用的内容 => https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf . 列表中返回的任何内容都可以在您的代码/应用程序和浏览器中使用,但可能在其他客户端和浏览器中不起作用。
除非您深入研究时间主题,否则不建议尝试将用户在其个人资料中选择的新位置输入的时间转换为其他地方的时间 - 这可能会很复杂。最好让用户选择一个位置,然后让该位置设置时间,然后保存。计算时间的前后?不需要 - 只需使用Intl API来读取。
话虽如此,请尝试我的代码,不使用外部库:
- 用户登录并基于巴基斯坦或其他地方
- 用户然后更改时区到新加坡或其他地方 - 这是在代码的这一部分中完成的
let userSelectedCountry = 'Asia/Singapore'
,然后使用Date和RegEx API调用我们的函数来实现我们需要的内容并提取所选(在我们的数组中可用的)时区的正确时间
要使用它,请按照代码注释中的步骤1和2操作。
const event = new Date();
//locales列表 - 不是穷尽无涯的
const localeCodes = ['el', 'en-au', 'en-ca', 'en-gb', 'en-us', 'es-es', 'es-mx', 'it-it'];
//时区列表 - 不是穷尽无涯的
const timeZonesL = ["Africa/Abidjan", "Asia/Aden", "Asia/Almaty", /* ... 省略部分 ... */, "Asia/Yerevan", "Europe/London"];
getDateTime = (country) => {
const regexp = new RegExp(`\\b${country}\\b`, 'gi') // 显示如何传递可选标志
const userTimeZone = timeZonesL.filter(timeZ => timeZ == timeZ.match(country))
return event.toLocaleString('en-GB', { timeZone: userTimeZone });
//return event.toLocaleString('en-GB', { timeZone: 'Asia/Singapore' });;
}
//步骤1
//测试1 - 用户登录并选择新的国家/时区后,我们为他们调用它
//例如从下拉菜单中选择
//下拉菜单中的值必须与timeZonesL数组中的某个值匹配
let userSelectedCountry = 'Asia/Singapore'
//构建正则表达式并传递所选的国家
var re = new RegExp("\\b"+userSelectedCountry+"\\b");
//如果它测试为regex匹配的真值,我们将使用它作为参数调用我们的函数
console.log(getDateTime(userSelectedCountry.match(re)))
//步骤2
//在退出登录时,将时间保存为用户选择的时间,例如
//mongoDB.save(getDateTime(userSelectedCountry.match(re)))
//现在我们可以保存用户选择的任何时间
//注意:需要更多工作来完成时区列表,因为某些时区是多余的,某些时区不受某些浏览器支持,您不希望全部都包括
英文:
Start by reading the supported values as part of the Intl Web/JS APi and checking what's available => https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf . Anything that's returned in the list you can use in your code/app and browser - but may not work in other clients and browsers.
Unless you dig deep into the topic of time I wouldn't try to convert time that a user has entered from a new location selected in their profile - this could be complicated. Better to let the user pick a location and let the location set the time then save that. Calculation back and off of the time? No need - just use Int API to read from.
That said have a try at my code using no external libraries:
- User logs in and is based in Pakistan or wherever
- User then changes the timezone to Singapore or somewhere else - this is done in this section of code
let userSelectedCountry = 'Asia/Singapore'
and call our function by using the Date and RegEx APIs to achieve what we need and pull out the correct time for selected (available timezone in our array!) timezone
To use it follow step 1 and 2 in the code comments.
const event = new Date();
//list of locales - NOT exhaustive
const localeCodes = ['el', 'en-au', 'en-ca', 'en-gb', 'en-us', 'es-es', 'es-mx','it-it']
//list of timezones - NOT exhaustive
const timeZonesL = ["Africa/Abidjan"
, "Asia/Aden"
, "Asia/Almaty"
, "Asia/Amman"
, "Asia/Anadyr"
, "Asia/Aqtau"
, "Asia/Aqtobe"
, "Asia/Ashgabat"
, "Asia/Ashkhabad"
, "Asia/Atyrau"
, "Asia/Baghdad"
, "Asia/Bahrain"
, "Asia/Baku"
, "Asia/Bangkok"
, "Asia/Barnaul"
, "Asia/Beirut"
, "Asia/Bishkek"
, "Asia/Brunei"
, "Asia/Calcutta"
, "Asia/Chita"
, "Asia/Choibalsan"
, "Asia/Chongqing"
, "Asia/Chungking"
, "Asia/Colombo"
, "Asia/Dacca"
, "Asia/Damascus"
, "Asia/Dhaka"
, "Asia/Dili"
, "Asia/Dubai"
, "Asia/Dushanbe"
, "Asia/Famagusta"
, "Asia/Gaza"
, "Asia/Harbin"
, "Asia/Hebron"
, "Asia/Ho_Chi_Minh"
, "Asia/Hong_Kong"
, "Asia/Hovd"
, "Asia/Irkutsk"
, "Asia/Istanbul"
, "Asia/Jakarta"
, "Asia/Jayapura"
, "Asia/Jerusalem"
, "Asia/Kabul"
, "Asia/Kamchatka"
, "Asia/Karachi"
, "Asia/Kashgar"
, "Asia/Kathmandu"
, "Asia/Katmandu"
, "Asia/Khandyga"
, "Asia/Kolkata"
, "Asia/Krasnoyarsk"
, "Asia/Kuala_Lumpur"
, "Asia/Kuching"
, "Asia/Kuwait"
, "Asia/Macao"
, "Asia/Macau"
, "Asia/Magadan"
, "Asia/Makassar"
, "Asia/Manila"
, "Asia/Muscat"
, "Asia/Nicosia"
, "Asia/Novokuznetsk"
, "Asia/Novosibirsk"
, "Asia/Omsk"
, "Asia/Oral"
, "Asia/Phnom_Penh"
, "Asia/Pontianak"
, "Asia/Pyongyang"
, "Asia/Qatar"
, "Asia/Qostanay"
, "Asia/Qyzylorda"
, "Asia/Rangoon"
, "Asia/Riyadh"
, "Asia/Saigon"
, "Asia/Sakhalin"
, "Asia/Samarkand"
, "Asia/Seoul"
, "Asia/Shanghai"
, "Asia/Singapore"
, "Asia/Srednekolymsk"
, "Asia/Taipei"
, "Asia/Tashkent"
, "Asia/Tbilisi"
, "Asia/Tehran"
, "Asia/Tel_Aviv"
, "Asia/Thimbu"
, "Asia/Thimphu"
, "Asia/Tokyo"
, "Asia/Tomsk"
, "Asia/Ujung_Pandang"
, "Asia/Ulaanbaatar"
, "Asia/Ulan_Bator"
, "Asia/Urumqi"
, "Asia/Ust-Nera"
, "Asia/Vientiane"
, "Asia/Vladivostok"
, "Asia/Yakutsk"
, "Asia/Yangon"
, "Asia/Yekaterinburg"
, "Asia/Yerevan"
, "Europe/London"]
getDateTime = (country) => {
const regexp = new RegExp(`\\b${country}\\b`, 'gi') // showing how to pass optional flags
const userTimeZone = timeZonesL.filter(timeZ => timeZ == timeZ.match(country))
return event.toLocaleString('en-GB', { timeZone: userTimeZone });
//return event.toLocaleString('en-GB', { timeZone: 'Asia/Singapore' });;
}
//step 1
//test 1 - after user signs in and selects new country/timezone we call it for them
//e.g. from a dropdown
//Value in drop down must match a value in the timeZonesL array
let userSelectedCountry = 'Asia/Singapore'
//build regex and pass in selected country
var re = new RegExp("\\b"+userSelectedCountry+"\\b");
//we then call our function with it as a param if it tests truthy to regex match
console.log(getDateTime(userSelectedCountry.match(re)))
//step 2
//On sign out save the time as to what the user selected e.g.
//mongoDB.save(getDateTime(userSelectedCountry.match(re)))
//now we can save any time the user selects
//NOTE: more needs to be done to finalise list of timezones as some are redundant, not supported by some
//browsers and you don't want all of them
答案3
得分: 0
我无法使用moment-timezone
库解决这个问题,所以我转向了dayjs
,它解决了我的问题。它正确地将时间转换为所选的时区。以下是这段代码的翻译:
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc"; // 导入 dayjs 的 UTC 插件
import timezone from "dayjs/plugin/timezone";
import customParseFormat from "dayjs/plugin/customParseFormat";
// 使用所需的插件扩展 dayjs
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(customParseFormat);
const getStartAndEndDateTime = (date, time, timezone, duration) => {
let startDateTime = "";
let endDateTime = "";
if (date && time) {
const formattedDate = dayjs(date).format("YYYY-MM-DD");
const formattedTime = dayjs(time, "hh:mm a").format("H:mm");
const timestamp = `${formattedDate} ${formattedTime}`;
startDateTime = dayjs.tz(timestamp, timezone || dayjs.tz.guess()).format();
endDateTime = dayjs
.tz(timestamp, timezone || dayjs.tz.guess())
.add(duration.value, "m")
.format();
}
return { start_datetime: startDateTime, end_datetime: endDateTime };
};
注意:我已经将引号从 HTML 实体编码 ("
) 转换为双引号。
英文:
i could not solve this issue with moment-timezone
libarary and so i shift to dayjs
it solved my problem. it is correctly converting time in selected timezone. below is the code for this
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc"; // Import the UTC plugin for dayjs
import timezone from "dayjs/plugin/timezone";
import customParseFormat from "dayjs/plugin/customParseFormat";
// Extend dayjs with the required plugins
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(customParseFormat);
const getStartAndEndDateTime = (date, time, timezone, duration) => {
let startDateTime = "";
let endDateTime = "";
if (date && time) {
const formateDDate = dayjs(date).format("YYYY-MM-DD");
const formatedTime = dayjs(time, "hh:mm a").format("H:mm");
const timestamp = `${formateDDate} ${formatedTime}`;
startDateTime = dayjs.tz(timestamp, timezone || dayjs.tz.guess()).format();
endDateTime = dayjs
.tz(timestamp, timezone || dayjs.tz.guess())
.add(duration.value, "m")
.format();
}
return { start_datetime: startDateTime, end_datetime: endDateTime };
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论