import React, {useState, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux';
import Select from 'react-select';
import makeAnimated from 'react-select/animated';
import moment from 'moment';
import momentt from 'moment-timezone';
import timezones from '../../data/chat/timezones';
import DatePicker from 'react-datepicker';
const CustomDateWithTimezoneToUTCComponent = (() => {
const animatedComponents = makeAnimated();
const auth = useSelector((state) => state.auth)
const [formObj, setFormObj] = useState({ startDate: momentt.tz(new Date().toISOString().replace("Z", ""), auth.timezone).format()
// NOTE auth.timezone for me is just some redux state, it is a string like "America/Denver" or "America/New_York"
const [startDate, setStartDate] = useState(); // strictly for date-picker it needs a local date object.
const [timezone, setTimezone] = useState()
const [initialTimezone, setInitialTimezone] = useState();
useEffect(() => {
//NOTE this is not a LOCAL timezone, its whatever you want it to be
setTimezone(auth.timezone) // "America/Denver"
setInitialTimezone(auth.timezone) //"America/Denver
setFormObj({...formObj, timezone: auth.timezone}) //"America/Denver
}, [auth]) // trigger at first render and when auth changes, again this is redux state so its coming from a reducer, could just be a string for you.
useEffect(() => {
if(timezone !== initialTimezone) {
console.log("timezone ODES NOT EQUAL")
console.log("formObj.startDate", formObj.startDate) //2022-11-03T16:00:00Z
const ttDate = new Date(formObj.startDate)
// Fri Nov 04 2022 10:00:00 GMT-0600 (Mountain Daylight Time) this will alway be according to USERS SELECTED TIMEZONE not the client local
const getAuthTimezone = momentt.tz(formObj.startDate.replace("Z", ""), initialTimezone).format()
//2022-11-04T16:00:00-06:00 take the start and apply the -06:00 to it and turn it into an iso string <--custom not local
const removeInitialTimezoneOffset = ttDate.setTime(ttDate.getTime() + moment.parseZone(getAuthTimezone).utcOffset() * 60_000);
//1667556000000 get time since UTC convert the -06 into -360 and get Time
const timeWithoutInitialOffset = new Date(removeInitialTimezoneOffset).toISOString().replace("Z", "")
// 2022-11-04T10:00:00.000 turn it into an iso string
const toTz = momentt.tz(timeWithoutInitialOffset, timezone).format()
//2022-11-03T10:00:00-06:00 if denver or 2022-11-03T10:00:00-04:00 if new york
const getNewStartUTCTime = momentt.utc(toTz).format() //2022-11-03T14:00:00Z get rid of the -06:00 or -04:00 or whatever they choose and make it an actual UTC time in ISO again for server
setInitialTimezone(timezone)
setFormObj({...formObj, startDate:getNewStartUTCTime})
}
}, [timezone])
return (
<div>
<DatePicker
//portalId="portal_column_start" // this fixed the bleedthrough
showPopperArrow={false}
selected={startDate}
onChange={(date) => {
const newD = new Date(date)
const applyOffset = newD.setTime(newD.getTime() - newD.getTimezoneOffset() * 60_000);
const actualTime = new Date(applyOffset).toISOString().replace("Z", "")
const toTz = momentt.tz(actualTime, timezone).format()
const getUTCTime = momentt.utc(toTz).format()
return setStartDate(date),
setFormObj({...formObj,
start: getUTCTime,
startDate: getUTCTime
})
}}
timeIntervals={60}
showTimeSelect
timeCaption="Time"
dateFormat="h:mm aa"
/>
<Select
name="timezone"
required={true}
className="mb-3"
components={animatedComponents}
closeMenuOnSelect={true}
options={timezones}
defaultValue={{UTC: timezone}}
getOptionLabel={({UTC}) => UTC}
getOptionValue={({zoneTitle}) => zoneTitle}
onChange={(timezone) => { return setTimezone(timezone.zoneTitle), setFormObj({...formObj, timezone: timezone.zoneTitle})}}
placeholder="select Timezone"
isSearchable={true}
innerRef={register({
required: "Add your timezone"
})}
/>
</div>
)}
4条答案
按热度按时间qco9c6ql1#
我建议你应该使用moment,因为如果与纯javascript/typescript相比,它非常容易使用。
你可以用下面的方法来做到这一点:
在您的情况下,可以通过以下方式将时区设置为“美洲/约克”:
有关详细信息,请访问https://momentjs.com/timezone/docs/#/using-timezones/default-timezone/
nbewdwxp2#
我真的不明白为什么你不能安装一个包。如果你能使用moment.js(我推荐),并且你的字符串不是日期字符串(比如“2021-09- 22 T15:35:00 Z”),你可以这样解决:
然后像这样使用它:
ltqd579y3#
安装***moment-timezone***软件包。它将帮助转换时间。请参考下面的链接。
https://momentjs.com/timezone/
使用方法:
1.将以下两个软件包导入到组件文件的顶部。
2.按如下方式转换时间。
ct2axkht4#
下面是一个带有自定义时区转换的time select react组件,它可以保存UTC日期,然后发布到服务器。
momentmoment-timezone react-select //可以只使用您自己的选择组件react-datepicker看看这个方便的用法我刚刚创建的效果
你有三个州
A.表单对象
B.时区
C.初始时区
有一个日期选择器可以让你选择一个日期,它从日期选择器中获取日期对象,它总是在你的本地时区创建一个日期。因此,日期选择器的onChange删除你的本地偏移,应用一个你想要的自定义时区偏移,例如“America/New_约克”),然后给你一个UTC时间保存到你的服务器。如果你决定在你选择一个日期后更改你的时区,它获取UTC时间,删除CHOSEN时区,添加新时区的偏移量,并返回服务器的UTC时间。
和一些时区数据提供给react-select组件