javascript 如何使用MUI日期选择器和dayjs设置自定义时区?

vohkndzv  于 2022-12-21  发布在  Java
关注(0)|答案(2)|浏览(210)
    • bounty将于明天到期**。回答此问题可获得+100的声望奖励。Mabeh Al-Zuq Yadeek希望吸引更多人关注此问题。

我有一个应用程序,其中用户的时区是由服务器提供的,而不是通过浏览器内置的方法使用。
因此,当我从服务器获取unix戳并将其传递给日期选取器时,它显示了"错误"的日期,因为日期选取器使用的是浏览器时区设置,而不是我从服务器获取的时区设置。我使用dayjs和adapterdayjs进行时间转换。

<LocalizationProvider dateAdapter={AdapterDayjs}>
 <DatePicker />
</LocalizationProvider>

我尝试用dayjs设置默认时区:

dayjs.extend(utc);
  dayjs.extend(timezone);

  dayjs.tz.setDefault('Asia/Makassar');

但这并不影响MUI日期选择器本身,有没有办法覆盖浏览器的时区设置,用AdapterDayjs、dayjs和MUI日期选择器插入服务器端提供的值?
编辑:
所以我想到了怎么做...但日历现在变慢了。
我将默认时区设置为:

dayjs.extend(utc);
  dayjs.extend(timezone);

  dayjs.tz.setDefault('Asia/Makassar');

Then passed dayjs.tz as the dateLibInstance param of LocalizationProvider, so now every time any dayjs method is called, it's done via dayjs.tz

<LocalizationProvider
        dateLibInstance={dayjs.tz}
        dateAdapter={AdapterDayjs}>
        <DatePicker />
      </LocalizationProvider>

现在唯一的问题是日历真的很慢。

t2a7ltrp

t2a7ltrp1#

如果你的解决方案很落后,为什么不把unix的时间戳转换成相关的时区,然后再把它存储在state中并提供给datepicker呢?根据从服务器返回给用户的时区来做这件事。
根据时区从dayjs解析unix戳:第一个月
此示例沙箱显示了两个Datepickers,用于模拟多伦多用户和悉尼用户的日期显示方式。您可以看到,多伦多用户显示的是31/12/2021,而悉尼用户显示的是01/01/2022。
https://codesandbox.io/s/mui-5-forked-8hznux?file=/src/ArrowPopper.js:0-2022

import * as React from "react";
import dayjs from "dayjs";
import TextField from "@mui/material/TextField";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
dayjs.extend(utc);
dayjs.extend(timezone);

export default function BasicDatePicker() {
  const [torontoUser, setTorontoUser] = React.useState(null);
  const [sydneyUser, setSydneyUser] = React.useState(null);

  React.useEffect(() => {
    const getServerData = async () => {
      // Simulate if the user was from Toronto
      const dataFromServerToronto = {
        unix: 1640959201000,
        timezone: "America/Toronto"
      };
      const datetimeToronto = dayjs(dataFromServerToronto.unix).tz(
        dataFromServerToronto.timezone
      );
      setTorontoUser(datetimeToronto);

      // Simulate if the use was from Sydney
      const dataFromServerSydney = {
        unix: 1640959201000, // same Unix stamp as above
        timezone: "Australia/Sydney"
      };
      const datetimeSydney = dayjs(dataFromServerSydney.unix).tz(
        dataFromServerSydney.timezone
      );
      setSydneyUser(datetimeSydney);
    };
    void getServerData();
  }, []);

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <DatePicker
        label="User From Toronto"
        value={torontoUser}
        onChange={(newValue) => {
          setTorontoUser(newValue);
        }}
        renderInput={(params) => (
          <TextField
            sx={{
              mb: 2
            }}
            {...params}
          />
        )}
      />
      <DatePicker
        label="User From Sydney"
        value={sydneyUser}
        onChange={(newValue) => {
          setSydneyUser(newValue);
        }}
        renderInput={(params) => <TextField {...params} />}
      />
    </LocalizationProvider>
  );
}
y1aodyip

y1aodyip2#

dayjs.extend(utc)
dayjs.extend(timezone)

// current time zone is 'Europe/Berlin' (offset +01:00)
// Parsing
dayjs.tz("2013-11-18 11:55:20", "America/Toronto") // '2013-11-18T11:55:20-05:00'

// Converting (from time zone 'Europe/Berlin'!)
dayjs("2013-11-18 11:55:20").tz("America/Toronto") // '2013-11-18T05:55:20-05:00'

相关问题