redux 根据React中的时区更改时间

mlmc2os5  于 2022-11-24  发布在  React
关注(0)|答案(4)|浏览(321)

我有一个方法,它获取一个时间字符串“15:35”作为参数。这个时间是UTC时区。但是我想把它转换成不同的时区(例如America/New_约克或...)。
示例中提到有一个名为“moment”的软件包,其中包含一个“tz”方法,但我检查了一下,该软件包中没有这样的方法。另外,我不能更新软件包或安装一个。我如何在不进行解析的情况下将给定时间转换为根据给定时区?
示例:UTC时间为“18:35”-〉美国/约克时间为14:35

qco9c6ql

qco9c6ql1#

我建议你应该使用moment,因为如果与纯javascript/typescript相比,它非常容易使用。
你可以用下面的方法来做到这一点:

moment.tz.setDefault(String)

在您的情况下,可以通过以下方式将时区设置为“美洲/约克”:

moment.tz.setDefault("America/New_York")

有关详细信息,请访问https://momentjs.com/timezone/docs/#/using-timezones/default-timezone/

nbewdwxp

nbewdwxp2#

我真的不明白为什么你不能安装一个包。如果你能使用moment.js(我推荐),并且你的字符串不是日期字符串(比如“2021-09- 22 T15:35:00 Z”),你可以这样解决:

function changeDatetimeByTimezone(datetime, timezone) {
    const parsedDateAsUtc = moment.utc()
      .startOf('day') 
      .add(datetime.substring(0, 2), "hours")
      .add(datetime.substring(3, 5), "minutes");
    return parsedDateAsUtc.clone().tz(timezone).format("hh:mm");
}

然后像这样使用它:

const dateTimeNY = changeDatetimeByTimezone("15:35", "America/New_York"); // 11:35
const dateTimeBE = changeDatetimeByTimezone("15:35", "Europe/Berlin"); // 17:35
ltqd579y

ltqd579y3#

安装***moment-timezone***软件包。它将帮助转换时间。请参考下面的链接。
https://momentjs.com/timezone/

使用方法:
1.将以下两个软件包导入到组件文件的顶部。

import moment from "moment";
import 'moment-timezone';

2.按如下方式转换时间。

var localTime = moment.utc('18:35', "HH:mm").tz('America/New_York').format("HH:mm");
console.log(localTime);
ct2axkht

ct2axkht4#

下面是一个带有自定义时区转换的time select react组件,它可以保存UTC日期,然后发布到服务器。
momentmoment-timezone react-select //可以只使用您自己的选择组件react-datepicker看看这个方便的用法我刚刚创建的效果
你有三个州
A.表单对象
B.时区
C.初始时区
有一个日期选择器可以让你选择一个日期,它从日期选择器中获取日期对象,它总是在你的本地时区创建一个日期。因此,日期选择器的onChange删除你的本地偏移,应用一个你想要的自定义时区偏移,例如“America/New_约克”),然后给你一个UTC时间保存到你的服务器。如果你决定在你选择一个日期后更改你的时区,它获取UTC时间,删除CHOSEN时区,添加新时区的偏移量,并返回服务器的UTC时间。

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>
)}

和一些时区数据提供给react-select组件

{UTC: "(UTC -03:00) America/Paramaribo",zoneTitle: "America/Paramaribo"},
    {UTC: "(UTC -03:00) Antarctica/Rothera",zoneTitle: "Antarctica/Rothera"},
    {UTC: "(UTC -03:00) Atlantic/Stanley",zoneTitle: "Atlantic/Stanley"},
    {UTC: "(UTC -03:00) Antarctica/Palmer",zoneTitle: "Antarctica/Palmer"},
    {UTC: "(UTC -03:00) America/Montevideo",zoneTitle: "America/Montevideo"},
    {UTC: "(UTC -02:30) America/St Johns",zoneTitle: "America/St_Johns"},
    {UTC: "(UTC -02:00) America/Godthab",zoneTitle: "America/Godthab"},
    {UTC: "(UTC -02:00) America/Miquelon",zoneTitle: "America/Miquelon"},
    {UTC: "(UTC -02:00) America/Noronha",zoneTitle: "America/Noronha"},
    {UTC: "(UTC -02:00) Atlantic/South Georgia",zoneTitle: "Atlantic/South_Georgia"},
    {UTC: "(UTC -01:00) Atlantic/Cape Verde",zoneTitle: "Atlantic/Cape_Verde"},
    {UTC: "(UTC +00:00) Atlantic/Azores",zoneTitle: "Atlantic/Azores"},
    {UTC: "(UTC +00:00) America/Scoresbysund",zoneTitle: "America/Scoresbysund"},
    {UTC: "(UTC +00:00) Africa/Abidjan",zoneTitle: "Africa/Abidjan"},
    {UTC: "(UTC +00:00) Africa/Dakar",zoneTitle: "Africa/Dakar"},
    {UTC: "(UTC +00:00) America/Danmarkshavn",zoneTitle: "America/Danmarkshavn"},
    {UTC: "(UTC +00:00) Atlantic/Reykjavik",zoneTitle: "Atlantic/Reykjavik"},
    {UTC: "(UTC +00:00) UTC",zoneTitle: "UTC"},
    {UTC: "(UTC +01:00) Africa/Casablanca", zoneTitle: "Africa/Casablanca"},
    {UTC: "(UTC +01:00) Europe/Guernsey", zoneTitle: "Europe/Guernsey"},
    {UTC: "(UTC +01:00) Europe/Belfast", zoneTitle: "Europe/Belfast"},
    {UTC: "(UTC +01:00) Atlantic/Madeira", zoneTitle: "Atlantic/Madeira"},
    {UTC: "(UTC +01:00) Atlantic/Faroe", zoneTitle: "Atlantic/Faroe"},
    {UTC: "(UTC +01:00) Atlantic/Faeroe", zoneTitle: "Atlantic/Faeroe"},
    {UTC: "(UTC +01:00) Atlantic/Canary", zoneTitle: "Atlantic/Canary"},
    {UTC: "(UTC +01:00) Europe/Jersey", zoneTitle: "Europe/Jersey"},
    {UTC: "(UTC +01:00) Europe/Isle of Man", zoneTitle: "Europe/Isle_of_Man"},
    {UTC: "(UTC +01:00) Europe/Lisbon", zoneTitle: "Europe/Lisbon"},
    {UTC: "(UTC +01:00) Europe/Dublin", zoneTitle: "Europe/Dublin"},
    {UTC: "(UTC +01:00) Europe/London", zoneTitle: "Europe/London"},
    {UTC: "(UTC +01:00) Africa/Algiers", zoneTitle: "Africa/Algiers"},
    {UTC: "(UTC +01:00) Africa/Brazzaville",zoneTitle: "Africa/Brazzaville"},
    {UTC: "(UTC +01:00) Africa/Kinshasa", zoneTitle: "Africa/Kinshasa"},
    {UTC: "(UTC +01:00) Africa/Lagos", zoneTitle: "Africa/Lagos"},
    {UTC: "(UTC +01:00) Africa/Luanda", zoneTitle: "Africa/Luanda"},
    {UTC: "(UTC +01:00) Africa/Malabo", zoneTitle: "Africa/Malabo"},
    {UTC: "(UTC +01:00) Africa/Porto-Novo", zoneTitle: "Africa/Porto-Novo"},
    {UTC: "(UTC +01:00) Africa/Tunis", zoneTitle: "Africa/Tunis"},
    {UTC: "(UTC +02:00) Europe/Paris", zoneTitle: "Europe/Paris"},
    {UTC: "(UTC +02:00) Europe/Stockholm"  , zoneTitle: "Europe/Stockholm"},
    {UTC: "(UTC +02:00) Europe/Zurich"           , zoneTitle: "Europe/Zurich"},
    {UTC: "(UTC +02:00) Europe/Vienna"           , zoneTitle: "Europe/Vienna"},
    {UTC: "(UTC +02:00) Europe/Copenhagen"           , zoneTitle: "Europe/Copenhagen"},
    {UTC: "(UTC +02:00) Europe/Warsaw"           , zoneTitle: "Europe/Warsaw"},
    {UTC: "(UTC +02:00) Europe/Berlin"           , zoneTitle: "Europe/Berlin"},
    {UTC: "(UTC +02:00) Europe/Rome"           , zoneTitle: "Europe/Rome"},
    {UTC: "(UTC +02:00) Europe/Amsterdam"           , zoneTitle: "Europe/Amsterdam"},
    {UTC: "(UTC +02:00) Europe/Oslo"           , zoneTitle: "Europe/Oslo"},
    {UTC: "(UTC +02:00) Europe/Madrid"           , zoneTitle: "Europe/Madrid"},
    {UTC: "(UTC +02:00) Africa/Khartoum"           , zoneTitle: "Africa/Khartoum"},

相关问题