【发布时间】:2018-10-29 18:50:51
【问题描述】:
我正在使用react-datepicker 让用户选择一个日期。但是,现在它使用本地时间 (PDT),但我想对其进行硬编码以使用特定时区 (PST)。
我尝试使用 utcOffset 道具,但它似乎没有做任何事情。有谁知道如何做到这一点?
【问题讨论】:
我正在使用react-datepicker 让用户选择一个日期。但是,现在它使用本地时间 (PDT),但我想对其进行硬编码以使用特定时区 (PST)。
我尝试使用 utcOffset 道具,但它似乎没有做任何事情。有谁知道如何做到这一点?
【问题讨论】:
就我而言,我在渲染 React-dates 插件之前设置了 defaultTimezone。 React-dates 只会使用默认时区。
moment.tz.setDefault('America/Los_Angeles');
【讨论】:
import moment from 'moment-timzeone 而不仅仅是import moment from 'moment'。我犯了这个错误,很困惑为什么它不起作用。
这对我有用:
import React, { ComponentProps } from "react"
import DatePicker from "react-datepicker"
import moment from "moment"
interface Props {
timezone: string
}
const DatePickerWithTimezone = ({
selected,
onChange,
timezone,
...props
}: Props & ComponentProps<typeof DatePicker>) => (
<DatePicker
selected={selected ? setLocalZone(selected, timezone) : null}
onChange={(v, e) => {
onChange(v ? setOtherZone(v, timezone) : null, e)
}}
{...props}
/>
)
const setLocalZone = (date: Date, timezone: string) => {
const dateWithoutZone = moment
.tz(date, timezone)
.format("YYYY-MM-DDTHH:mm:ss.SSS")
const localZone = moment(dateWithoutZone).format("Z")
const dateWithLocalZone = [dateWithoutZone, localZone].join("")
return new Date(dateWithLocalZone)
}
const setOtherZone = (date: Date, timezone: string) => {
const dateWithoutZone = moment(date).format("YYYY-MM-DDTHH:mm:ss.SSS")
const otherZone = moment.tz(date, timezone).format("Z")
const dateWithOtherZone = [dateWithoutZone, otherZone].join("")
return new Date(dateWithOtherZone)
}
export default DatePickerWithTimezone
【讨论】:
convertToLocalTime(date, { timeZone: timezone }) 和convertToTimeZone(date, { timeZone: timezone }) 的date-fns-timezone 库,它会变得更简单一些,它们的工作方式与setLocalZone 和setOtherZone 函数的工作方式基本相同。
由于 datepicker 不再使用 moment.js,我尝试为这个问题实现一个 hacky 解决方案,假设初始值是一个字符串,例如:
export const formatUTC = (dateInt, addOffset = false) => {
let date = (!dateInt || dateInt.length < 1) ? new Date : new Date(dateInt);
if (typeof dateInt === "string") {
return date;
} else {
const offset = addOffset ? date.getTimezoneOffset() : -(date.getTimezoneOffset());
const offsetDate = new Date();
offsetDate.setTime(date.getTime() + offset * 60000)
return offsetDate;
}
}
在日期内我这样称呼格式化程序:
selected={formatUTC(this.props.input.value,true)}
onChange={date => formatUTC(date)}
【讨论】:
我已经经历过这个,如果您决定只想忽略本地偏移量,那么您可以对该区域进行硬编码。
观察只是为了给出一个完整的答案: PST 将始终为 -08:00,但如果您想要例如太平洋时间,现在是 -07:00,在这种情况下,您可能需要安装'moment.timezone' 然后import moment from 'moment-timezone' 并使用moment.tz('US/Pacific').format('Z') 获取当前偏移量
typescript 中的代码(如果需要,我可以将其更改为 Javascript):
interface ICalendarInputProps {
handleChange: (newDate: moment.Moment) => void;
}
const CalendarInput = ({ handleChange }: ICalendarInputProps) => {
const onChange = (date: Date) => {
handleChange(moment(`${moment(date).format('YYYY-MM-DDThh:mm:ss')}-08:00`));
// This is to get the offset from a timezone: handleChange(moment(`${moment(date).format('YYYY-MM-DDThh:mm:ss')}${moment.tz('US/Pacific').format('Z')}`));
};
return (<DatePicker onChange={onChange} />);
};
export default CalendarInput;
【讨论】:
${moment(date).format('YYYY-MM-DDTHH:mm:ss')}-08:00)
此组件在所选日期开始时输出设置为当地时间午夜的 Date 对象。这是个问题。如果有办法配置这种行为,我还没有找到。
在处理日期时保持清醒的唯一方法是确保您的日期始终是相关日期开始时的午夜 UTC。要从 react-datepicker 中获得这种行为,我发现的唯一一件事就是从输出中减去时区偏移量......
interface IProps {
value: any
setValue: (value: Date) => void
}
const DayPicker: FC<IProps> = ({ value, setValue, placeholderText = "", minDate = new Date() }) => {
function correctToUtcThenSet(val: Date) {
setValue(new Date(val.getTime() - val.getTimezoneOffset() * 60000))
}
return <DatePicker
onChange={correctToUtcThenSet}
selected={value}
/>
}
【讨论】:
utcOffset 我也没有运气。您可以在项目中使用 moment-timezone 而不是 moment 并自行转换:
import moment from "moment-timezone";
onDateChange = date => {
console.log("as is:", date.format("YYYY-MM-DD HH:mm:ss"));
console.log("PST:", moment(date).tz("America/Los_Angeles").format("YYYY-MM-DD HH:mm:ss"));
};
【讨论】:
由于您使用的是 moment.js,因此您可以尝试使用 moment.utc() 并将小时数减去 pst 时区。
moment.utc().startOf('day').subtract(8, 'hours')
【讨论】: