reactjs - 尝试将 React JS new Date() 输出转换为 date-fns 格式ISO

标签 reactjs datetime timezone date-fns

我正在开发一个从用户收集事件数据输入的应用程序。我的数据结构很简单

const dummyEvent = JSON.parse(
  '{"id":0,"notes":"","date_time":""}'
);

有一个用于日期部分的弹出窗口,另一个用于时间部分的弹出窗口。捕获的数据需要存储在我的数据库中的date_time字段中。

当用户进入屏幕时,我必须使用“new Date()”将日期和时间默认为现在。用户可以使用弹出窗口更改日期和时间值

我的问题是生成的 (new Date()) 的格式如下 2021 年 7 月 9 日星期五 05:39:30 GMT-0400 (EDT) 我需要将其格式化为时区感知字符串 2021-07-09T05:39:30-04:00

正如您在我单独的测试代码中看到的,我使用 date-fns/formatISO 生成正确的格式。但是当我尝试将其设置到我的状态对象中时,它会抛出代码中注释的异常

import React, {useState} from 'react';
import { parse, parseDate, format, addDays, isAfter, formatISO, parseISO } from "date-fns";
import {StyleSheet, View, Text, Button, Platform} from 'react-native';

import DateTimePicker from '@react-native-community/datetimepicker';

const App = () => {
  const [isPickerShowDate, setIsPickerShowDate] = useState(false);
  const [myDate, setMyDate] = useState(new Date(Date.now()));

  const [isPickerShowTime, setIsPickerShowTime] = useState(false);

  const showPickerDate = () => {
    setIsPickerShowDate(true);
    setIsPickerShowTime(false);
  };
  
  const showPickerTime = () => {
    setIsPickerShowTime(true);
    setIsPickerShowDate(false);
  };

  const onChangeDate = (event, value) => {
    falseEmBoth();
    setMyDate(value);
  };
  const onChangeTime = (event, value) => {
  falseEmBoth();
    setMyDate(value);
  };

  const falseEmBoth = () => {
  setIsPickerShowTime(false);
  setIsPickerShowDate(false);
  console.log('\nIn falseEmBoth');
  };

  return (
    <View style={styles.container}>
      <View style={styles.pickedDateContainer}>
        <Text style={styles.pickedDate}>{format(myDate, 'P')}</Text>
      </View>
      <View style={styles.btnContainer}>
        <Button title="Show Date Picker" color="purple" onPress={showPickerDate} />
      </View>

      {isPickerShowDate && (
        <DateTimePicker
          value={myDate}
          mode={'date'}
          display={Platform.OS === 'ios' ? 'spinner' : 'default'}
          onChange={onChangeDate}
          style={styles.datePicker}
        />
      )}

      <View style={styles.pickedDateContainer}>
        <Text style={styles.pickedDate}>{format(myDate, 'p')}</Text>
      </View>
      <View style={styles.btnContainer}>
        <Button title="Show Time Picker" color="purple" onPress={showPickerTime} />
      </View>

      {isPickerShowTime && (
        <DateTimePicker
          value={myDate}
          mode={'time'}
          display={Platform.OS === 'ios' ? 'spinner' : 'default'}
          onChange={onChangeTime}
          style={styles.datePicker}
        />
      )}
      
      <View style={styles.pickedDateContainer}>
        <Text style={styles.pickedDate}>{ format(myDate, 'Pp') }</Text>
      </View>
      <View style={styles.pickedDateContainer}>
        <Text style={styles.pickedDate}>{ format(myDate, 'PPpp') }</Text>
      </View>

      <View style={styles.btnContainer}>
        <Button
          title="Log Date Value"
          onPress={() => {
            const t = format(myDate, 'yyyy-MM-dTHH:m:s-OOOO');
            const tt = formatISO(myDate);
//            const t = format(myDate, "yyyy-MM-dd'T'HH:mm:ssOOOO");
              //  above produces -- ERROR  RangeError: Invalid time value

//            const t = formatISO(myDate, "yyyy-MM-dd'T'HH:mm:ssOOOO");
//            const t = parseDate(myDate, "yyyy-MM-dd'T'HH:mm:ssOOOO", new Date());
            //  above produces --  ERROR  TypeError: (0, _$$_REQUIRE(_dependencyMap[5], "date-fns").parseDate) is not a function.

//            const t = parse(myDate, "yyyy-MM-dd'T'HH:mm:ssOOOO", new Date());
              //   above produces --  ERROR  RangeError: Invalid time value

            console.log('\nBefore myDate value: ' + myDate);
            console.log('format yyyy-MM-ddTHH:m:s-OOOO date value:\n' + t);
            console.log('formatISO tt date value:\n' + tt);

//            setMyDate(formatISO(new Date(myDate)));
              //  above produces --  above yields: Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO`

//            setMyDate(formatISO(new Date(date), { representation: 'complete' }));
//            setMyDate(format(myDate, 'yyyy-MM-ddTHH:m:s-OOOO'));

            setMyDate(t);
            console.log('After date value: ' + myDate);
          }}
        />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
    padding: 50,
  },
  pickedDateContainer: {
    padding: 20,
    backgroundColor: '#eee',
    borderRadius: 10,
  },
  pickedDate: {
    fontSize: 18,
    color: 'black',
  },
  btnContainer: {
    padding: 30,
  },
  // This only works on iOS
  datePicker: {
    width: 320,
    height: 260,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'flex-start',
  },
});

export default App;

谢谢你的帮助。 珍妮·P。

最佳答案

我缺少的是 myDate 不是一个日期对象,我以后可以像在 Java 中那样完全操作日期对象。我需要在创建对象时应用 formatISO -

const [myDate, setMyDate] = useState(formatISO(new Date()))

关于reactjs - 尝试将 React JS new Date() 输出转换为 date-fns 格式ISO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68315128/

相关文章:

java - 日期的创建周期在列表中是连续的(它们之间相差一天)

java - 格式 EEEE、MMMM d、YYYY h :mm:ss a z 的解析器异常

c# - 时区信息|GetUtcOffset : A better solution?

javascript - Reactjs : How I can change button style when clicked

javascript - 如何逐步渲染 react 组件?

reactjs - 在 useEffect React 中调用异步函数中的 Firebase v9 onSnapShot

python - 处理 panda to_datetime 函数中的时区

javascript在 meteor 中生成重复的图像

r - 如何在 R 编程中将日期时间更改为新列中的日期?

java - 将当前日期时间转换为夏令时罗马尼亚时间