0

I'm using ant design for my react hook based development. I am retrieving date from database over a network call and the date retrieved from database is look like "2020-09-01T05:02:00.000+0000". It is a string. I have to parse this date and show the date value and time value through antd datePicker in my page. Though I've success with setting up date part but I'm stuck with setting up the time. Here is my code,

########### Here is my datepicker ###########

                          <DatePicker
                            name="Campaign-date"
                            defaultValue={moment(formData['Campaign-date'].split('T')[0])}
                   
                            showTime={{
                                defaultValue: moment(formData['Campaign-date'].split('T')[1],'HH:mm'),
                                format: 'HH:mm'
                                
                            }}
                            format={'YYYY-MM-DD HH:mm'}
                            style={{ width: '100%' }}
                            onChange={handleDateChange}
                        />

########################## Here is my handleDateChange function ##########################

const handleDateChange = date => {
    setFormdata({
        ...formData,
        'Campaign-date': date
            .format('YYYY-MM-DD HH:mm')
            .split(' ')
            .join('T')
    });
};

formData['Campaign-date'] is the date retrieved from the database. I feel the showTime attribute is not working as expected. I want to get a result of "05:02" but instead the value shown is, "00:00".

I have tried different variation in showTime such as,

defaultValue: moment('05:02','HH:mm'),
//or
defaultValue: moment(formData['Campaign-date'],'HH:mm')
//or
defaultValue: moment(formData['Campaign-date'].split('T')[1].split('.),'HH:mm')

but nothing is working. It is always setting the value as "00:00". And I have no problem with my onChange functionality. It is working perfect. The date/time change code wise working as expected. It is just the view on my page is not showing correct time.

I'm really stuck with. Any help therefore, is much appreciated.

sandy
  • 283
  • 1
  • 7
  • 27

2 Answers2

1

Ant Design DatePicker:

(sandbox)

import React from "react";
import ReactDOM from "react-dom";
import { DatePicker, Space } from "antd";
import moment from "moment";

import "./index.css";
import "antd/dist/antd.css";

const initialState = {
  data1: "form field",
  data2: "form field 2",
  "Campaign-date": "2020-09-01T05:02:00.000+0000"
};

function FormComponent() {
  const [formData, setFormData] = React.useState(initialState);

  console.log(formData);

  function onChange(value, dateString) {
    if (value) {
      setFormData({
        ...formData,
        "Campaign-date": value.toISOString(true)
      });
    }
    //console.log("Selected Time: ", value); //Moment object
    //console.log("Formatted Selected Time: ", dateString); //String
  }

  return (
    <Space direction="vertical" size={12}>
      <DatePicker
        name="Campaign-date"
        defaultValue={moment(formData["Campaign-date"], "YYYY/MM/DD HH:mm")}
        format={"YYYY/MM/DD HH:mm"}
        showTime={{ format: "HH:mm" }}
        onChange={onChange}
      />
      <div style={{ marginTop: 16 }}>
        Selected Date:{" "}
        {formData["Campaign-date"]
          ? moment(formData["Campaign-date"]).format("YYYY-MM-YY HH:mm")
          : "None"}
      </div>
    </Space>
  );
}

ReactDOM.render(<FormComponent />, document.getElementById("container"));

If you are using react-datepicker 2.0 or up, you need to use a javascript Date object. Here is a working setup.

  function parseISOString(s) {
    var b = s.split(/\D+/);
    return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6]));
  }

  const isoString = '2020-09-01T05:02:00.000+0000';
  const dateFromISOString = parseISOString(isoString);
  
  <DatePicker
    selected={dateFromISOString}
    dateFormat="dd/MM/yyyy HH:mm"
    showTimeSelect
    timeFormat="HH:mm"
    timeIntervals={15}
    placeholderText="Select date"
    onChange={handleChange}
  />

Overview

The string you are receiving from the database is an ISO date string.

You can use moment.js to easily parse it or parse it manually and create a new Date object from it. Here is a snippet illustrating both. The Date example uses this answer: Change ISO Date String to Date Object - JavaScript

const isoString = "2020-09-01T05:02:00.000+0000"

// with Moment
console.log("With Moment");
const timeFromMoment = moment(isoString).format("HH:mm");
console.log(timeFromMoment);

// with Date
console.log("With Date");
// https://stackoverflow.com/questions/27012854/change-iso-date-string-to-date-object-javascript
function parseISOString(s) {
  var b = s.split(/\D+/);
  return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6]));
}

const dateFromISOString = parseISOString(isoString);
console.log(dateFromISOString);

// return Local adusted time
const localHours = dateFromISOString.getHours();
console.log(localHours);

// return UTC time
const utcHours = dateFromISOString.getUTCHours();
console.log(utcHours);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
pilchard
  • 12,414
  • 5
  • 11
  • 23
  • thanks for your answer but I don't want a string to display.Instead a moment object to setup in the defaultValue(as this takes only moment object) of showTime attribute so that it rightly displays the returned time in the time field of datePicker just the way it is displaying the date part "2020-09-01" – sandy Aug 20 '20 at 11:07
  • I edited to include moment. `moment(yourString).format("HH:mm")` – pilchard Aug 20 '20 at 11:08
  • "Up until version 1.8.0, this package was using Moment.js. Starting v2.0.0, we switched to using native Date objects to reduce the size of the package. If you're switching from 1.8.0 to 2.0.0 or higher, please see the updated example above of check out the examples site for up to date examples." [Hacker0x01 / react-datepicker](https://github.com/Hacker0x01/react-datepicker) – pilchard Aug 20 '20 at 11:15
  • thanks for your help but it didn't work. moment(yourString).format("HH:mm") returns a string whereas 'defaultValue' of showTime attribute only accepts moment object. May be I've to use timePicker and datePicker separately but this is very strange behavior. – sandy Aug 20 '20 at 11:24
  • @sandy sorry for the confusion, I thought you were using react-datepicker. I've added antd to the answer and linked to a working sandbox. – pilchard Aug 20 '20 at 12:33
  • @sandy I've edited my answer to address your handleChange question about persisting the changed date and seeing the changed values. The sandbox has been edited as well. – pilchard Aug 20 '20 at 22:26
0
<DatePicker
      name="Campaign-date"
      defaultValue={moment(formData['Campaign-date'].split('T')[0])}
               
      showTime={{
              defaultValue: moment(formData['Campaign-date'].split('T')[1].split('.')[0],'HH:mm:ss'),
              format: 'HH:mm:ss'
                            
                        }}
      format={'YYYY-MM-DD HH:mm'}
      style={{ width: '100%' }}
      onChange={handleDateChange}
      />
sazzad
  • 505
  • 4
  • 5
  • thanks but can't use a timePicker while I already have this datePicker and showTime attribute available there. I have to show the returned time using this showTime. – sandy Aug 20 '20 at 11:08
  • can you show this in a snippet as this solution didn't work – sandy Aug 20 '20 at 11:25
  • DatePicker no longer uses momentjs. – pilchard Aug 20 '20 at 11:27
  • sorry in my earlier i had a type. instead of `formData['Campaign-date']` i used `formData['Campaigndate']` – sazzad Aug 20 '20 at 11:28
  • @pilchard I am using datePicker from antd and it uses moment for it's defaultValue object. For both date and time. in my case date is working fine. the time is not working. – sandy Aug 20 '20 at 11:30
  • @pilchard they are still using momentjs . https://ant.design/components/date-picker/#header – sazzad Aug 20 '20 at 11:30
  • Sorry, the tag on the question indicated react-datepicker. I've edited my answer to include antd. – pilchard Aug 20 '20 at 11:51