Sco*_*amb 7 javascript momentjs material-ui date-fns moment-timezone
我的应用程序需要material-ui日期和时间选择器才能在服务器指定的远程时区上运行。我希望日期选择器上的今天圆圈实际指示远程时区中的今天,并且我想将远程时区中的日期时间转换为自 以来的秒数1970-01-01T00:00:00Z。
我正在使用material-ui v5 alphas。文档说您为时间库指定了一个@date-io适配器。看起来有四个明显的选择:
@date-io/date-fns(基于date-fns和date-fns-tz 的远程时区设计有问题。它使用 Javascript Dates 来表示远程时区的日期和时间,但如果本地时区有“春天向前”小时,有时候你无法代表问题。@date-io/dayjs(基于dayjs)无法正确处理夏令时。问题@date-io/luxon(基于luxon)看起来很有前途@date-io/moment(基于时刻和时刻时区)看起来很有希望所以我想为 luxon 或 moment 指定一个适配器,以在特定区域中构造日期。
这两个库都支持设置全局默认时区(luxon、moment),但我更愿意在构建特定日期适配器时设置时区。根据服务器响应来搞乱全局状态是很恶心的。
我发现了一个date-io 问题,上面写着:
您可以将时刻时区直接传递给 ,
libInstance在这种情况下,它将使用时刻实例或全局实例的时区集
这就是我想要的!但我对这个实例到底应该是什么感到困惑。我对 Javascript 还很陌生,这并没有帮助。
今天的构造函数@date-io/luxon似乎不允许重写这样的实例。
试图让第一时刻开始工作:
$ mkdir tztest
$ cd tztest
$ npm init -y
$ npm install --save moment moment-timezone '@date-io/moment'
$ node
> let MomentUtils = require('@date-io/moment');
undefined
> let moment = require('moment');
undefined
> let _ = require('moment-timezone');
undefined
> // Operations including the following should all work similarly to when using the default instance:
> (new MomentUtils()).date();
Moment<2021-03-18T11:57:30-07:00>
> (new MomentUtils()).date('2021-01-01T00:00:00');
Moment<2021-01-01T00:00:00-08:00>
> (new MomentUtils()).getCurrentLocaleCode();
'en'
> // Here's some garbage I tried
> (new MomentUtils({instance: moment().tz('America/New_York')})).date();
Uncaught TypeError: _this.moment is not a function
at MomentUtils.date (/Users/slamb/git/tztest/node_modules/@date-io/moment/build/index.js:78:32)
> (new MomentUtils({instance: moment.tz('America/New_York')})).date();
Uncaught TypeError: _this.moment is not a function
at MomentUtils.date (/Users/slamb/git/tztest/node_modules/@date-io/moment/build/index.js:78:32)
> (new MomentUtils({instance: () => moment.tz('America/New_York')})).date();
Moment<2021-03-18T14:44:07-04:00>
> (new MomentUtils({instance: () => moment.tz('America/New_York')})).date('2021-01-01T00:00:00');
Moment<2021-03-18T14:44:19-04:00>
> (new MomentUtils({instance: (arg1, arg2, arg3, arg4) => moment.tz(arg1, arg2, arg3, arg4, 'America/New_York')})).date('2021-01-01T00:00:00');
Moment<2021-01-01T00:00:00-05:00>
> (new MomentUtils({instance: (arg1, arg2, arg3, arg4) => moment.tz(arg1, arg2, arg3, arg4, 'America/New_York')})).getCurrentLocaleCode();
Uncaught TypeError: _this.moment.locale is not a function
at MomentUtils.getCurrentLocaleCode (/private/tmp/tztest/node_modules/@date-io/moment/build/index.js:63:49)
> (new MomentUtils({instance: (arg1, arg2, arg3, arg4) => moment.tz(arg1, arg2, arg3, arg4, 'America/New_York')})).date();
Moment<2021-03-18T14:44:36-04:00>
> (new MomentUtils({instance: function() { return moment(arguments).tz('America/New_York'); } })).date()
...here the interpreter started making fun of me...
Run Code Online (Sandbox Code Playgroud)
从@date-io/moment来源来看,如下引用,我看到它以几种不同的方式使用它。当然,我希望所有这些都能正常工作。
export default class MomentUtils implements IUtils<defaultMoment.Moment> {
...
constructor({ locale, formats, instance }: Opts = {}) {
this.moment = instance || defaultMoment;
...
return /A|a/.test(this.moment().localeData().longDateFormat("LT"));
...
return this.moment.localeData().longDateFormat(token as LongDateFormatKey);
...
return this.locale || this.moment.locale();
...
return this.moment(value, format, this.locale, true);
...
return this.moment(value, format, true);
...
const moment = this.moment(value);
...
return this.moment.weekdaysShort(true);
Run Code Online (Sandbox Code Playgroud)
问题是material-ui 对于不同的主要版本有不同的文档和日期适配器集成API。
我moment-timezone与@material-ui/pickers@4.0.0-alpha.11
"@material-ui/core": "4.11.3",
"@material-ui/pickers": "4.0.0-alpha.11",
"moment": "2.29.1",
"moment-timezone": "0.5.33",
"react": "17.0.2",
"react-dom": "17.0.2"
Run Code Online (Sandbox Code Playgroud)
https://codesandbox.io/s/material-ui-starter-template-forked-pvpmc
import React from "react";
import { render } from "react-dom";
import momentTimezone from "moment-timezone";
import { TextField } from "@material-ui/core";
import { DatePicker, LocalizationProvider } from "@material-ui/pickers";
import MomentAdapter from "@material-ui/pickers/adapter/moment";
const App = () => {
const timeZoneFromServer = "Asia/Tokyo";
const { moment } = new MomentAdapter({ instance: momentTimezone });
const dateWithTimeZone = moment().tz(timeZoneFromServer);
const handleDateChange = () => {};
return (
<LocalizationProvider dateAdapter={MomentAdapter}>
<DatePicker
renderInput={(props) => <TextField {...props} />}
value={dateWithTimeZone}
onChange={handleDateChange}
/>
</LocalizationProvider>
);
};
render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15047 次 |
| 最近记录: |