简体   繁体   中英

Trying to convert React JS new Date() output to date-fns formatISO

I am working on an application that collects event data entry from the user. My data structure is simple

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

There is a popup for the date portion and another for the time portion. The data captured needs to be stored in the date_time field in my database.

I have to default the date and time to now using 'new Date()' when the user enters the screen. The user can use the popups to change the date and time values

My issue is the (new Date()) generated is formatted like this Fri Jul 09 2021 05:39:30 GMT-0400 (EDT) and I need it formatted to this timezone aware string 2021-07-09T05:39:30-04:00

As you can see in my separate testing code, I use date-fns/formatISO which produces the correct format. But when I try to set it into my state object, it throws the exceptions commented in the code

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;

Thank you for help. Jenny P.

What I was missing was that myDate is not a date object which I can later fully manipulate like a date object like we do in Java for example. I needed to apply the formatISO on the creation of the object -

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM