React-datepicker changes date but not time - reactjs

I'm using Moment.js with react-datepicker. It works as intended in terms of the date transformation to ISO-8601, but I can't get it compliant with the time.
Here's my component:
Stated initially:
this.state = {
from: moment().subtract(7, "days"), // Default 1 week back
to: moment(), // Current date
};
The component itself:
<DatePicker
dateFormat="DD-MMM HH:mm"
dropdownMode="select"
selected={this.state.from}
onChange={this.handleFromChange}
/>
And the onchange trigger:
handleFromChange(date) {
this.setState({
from : date
});
}
I think my issue is the dateFormat; The DD-MMM are easily transformed to ISO-8601 by calling using the ECMAScript function toISOString() before posting it to some backend services. But how do I get the time to go with it?
The user(myself, testing) can chance the time on the datepicker itself, but it won't register in the state. Simply it will just pick the current time, or current time 1 week ago(as per the moment from/to initial states). The date, i can change also, but the time remains the same(current time).
How do I change the dateFormat so it takes the time input from the user? How do I make it ISO 8601 compliant per default in the dateFormat attribute?
Edit: I just tested with setting "from" to subtract 5 minutes at such:
this.state = {
from: moment().subtract(5, "minutes"),
to: moment(), // Current date
};
And it formats it correctly when I post it. Seems strange. It must be related to the onChange function then?

Try using dateFormat="dd-MMM hh:mm" and change onChange function to this to avoid error.
handleFromChange(date) {
this.setState({
from : date || ""
});
}

Related

react-intl FormattedDate component giving Invalid Date changed to en-GB locale

I have my date formatted like this
let formattedDate = new Date(updated_at).toLocaleDateString('en-US', { timeZone: 'UTC' })
Then I have the FormattedDate component from 'react-intl' package used like this
<FormattedDate value={formattedDate} />
Then It renders the formattedDate value like this on the browser(MM/DD/YYY)
Now I'd like to change it to en-GB date format(DD/MM/YYYY) so I did this,
let formattedDate = new Date(updated_at).toLocaleDateString('en-GB', { timeZone: 'UTC' })
But then I get invalid date on my table after that, but some of the rows render with date with now the correct format I wanted.
Here are the errors by the way in the browser console.
Error: [#formatjs/intl Error FORMAT_ERROR] Error formatting date.
Invalid time value
RangeError: Invalid time value
at formatDate (dateTime.js:50:1)
And If I console.log those problem dates before being formatted, just in their raw form here they are:
2022-09-22T06:52:32.870184Z
2022-09-22T03:04:54.983147Z
2022-09-20T08:09:22.845208Z
Weird though, if I console.log those three using this my line of code
let formattedDate = new Date(updated_at).toLocaleDateString('en-GB', { timeZone: 'UTC' })
Then I'll get a proper value
22/09/2022
So, I'm really stuck how to fix this, as the other dates can be formatted correctly with my approach, but the first three dates on my table won't. Though they are the same in format as I can tell. Thanks in advance for any help.

MomentJS providing time an hour behind what is selected

I seem to be having a bit of a weird bug wherein as the title states, MomentJS is providing a time that is an hour behind. This is my code so far:
import { AdapterMoment } from "#mui/x-date-pickers/AdapterMoment";
import moment from "moment";
...
const [job, setJob] = useState({
name: "",
outgoingDateTime: moment.now(),
jobStartDateTime: moment.now(),
returningDateTime: moment.now(),
jobFinishDateTime: moment.now(),
isJobStartLinked: jobStartLinked,
isJobFinishLinked: jobFinishLinked,
contact: null,
});
const handleOutgoingDateTimeChange = (newValue) => { setJob({...job, outgoingDateTime: newValue}); }
With the above code, when I trigger the DateTimePicker to be displayed, it displays the correct time. For example, if I trigger it on 19/09/2022 at 23:45, it will display 19/09/2022 23:45.
This is what I'm using to display this:
<LocalizationProvider dateAdapter={AdapterMoment}>
<DateTimePicker
label="Outgoing Date and Time"
value={job.outgoingDateTime}
onChange={handleOutgoingDateTimeChange}
inputFormat="DD/MM/YYYY HH:mm"
ampm={false}
renderInput={(params) => <TextField {...params} />} />
</LocalizationProvider>
Might I also add that when I change the value of the DateTimePicker, it correctly states the input. For example, let's say I input 25/09/2022 07:30. It would display 25/09/2022 07:30.
Now, when I then tap save, the returned value is an hour behind. So, for example, let's take what I entered just now 25/09/2022 07:30. It would come back as 25/09/2022 06:30.
I'm checking my back end to see if that was the issue, however, upon doing so, I could see that the front end is passing along the hour behind data.
What could be happening and how could I fix this?
So, after looking into this a little further, I found that my back end was using LocalDateTime which, living in the UK is bad... Bad because LocalDateTime is not Daylight Saving aware. After changing the variables to ZonedDateTime (which is DST aware) and zoning it in to Europe/London, it now saves to the database properly.

Display Date off by one in react

I am using the html input type date on a form in react. Previously when encountering issues with the javascript date object and getting it to display correctly, I used the method of .replace(/-/g, "/") and the day passed in would be displayed correctly.
I am making a new app and trying the same thing and receiving the following error basically copying and pasting lines of code.
The specified value "2021/07/06" does not conform to the required format, "yyyy-MM-dd".
So apparently you are required to do a timezone offset to get the date object to correctly display in react?
Here is what i am trying to do to get a proper date to display in the value of the date picker:
<input
type='date'
name='startDate'
value={startDisplay != null && startDisplay}
id=''
onChange={(e) => {
setStartDate(e.target.value);
setStartDisplay(
Intl.DateTimeFormat({
year: "numeric",
month: "numeric",
day: "numeric",
})
.format(new Date(startDate))
.replace(/-/, "/")
.replace(/-/, "/")
);
}}
/>
I'm wondering if there is a fix that allows the replace method to work, or if someone can help me write a function for setDisplayDate that properly uses timezoneoffset.
or should I just suck it up and add the date picker library?

How Can I Set Global Timezone and Change Time in React?

How can I set the time zone globally in react? Is it possible? I know the new Date() of javascript actually gives the time zone of the system. But I want to set the time zone in one file in react application and re use it. And when I will change the time, the time will also be changed according to the specific time zone. Thanks in advance.
Hey this is not a react related question, I would say more of a JS question but what I normally do is to use Luxon, you need to install the library an afterwards what I do is this:
// src/utils/luxon/index.ts
import {DateTime, Settings} from 'luxon'
// Example to set EST as the default timezone in the app.
Settings.defaultZoneName = 'America/New_York'
export {DateTime, Settings}
Then I just import that utils file and use the DateTime object to parse and handle dates.
So if you have lets say for example an epoch date you can parse it like this
import {DateTime} from 'utils/luxon'
const epochDate = 1597354080
const luxonDate = DateTime.fromSeconds(epochReleaseDate)
console.log(luxonDate.toLocaleString(DateTime.TIME_SIMPLE))
If you click this page you will notice that the current est time for that epoch should return Thursday August 13, 2020 17:28:00 (pm)
You can parse those dates to Javascript date objects but I suggest you to get used to luxon because it makes working with dates pretty easy. Just remember that the Date returned by luxon is way different than the Js Date object so don't combine them, instead use the parsing methods of luxon to convert a Js Date to Luxon Date and vice versa
I actually tried to solve the problem this way. to initialize the date in the ui I called the getGlobalDate function instead of calling new Date() in js. And for changing the date I passed the date object to onChangeFormat function and convert the date time.
export const language = "en-US";
export const timeZone = { timeZone: "Pacific/Auckland" };
//to initialize the date
export function getGlobalDate() {
return new Date().toLocaleString(language, timeZone);
}
//for onChanging the date and convert it to the timzone
export function onChangeFormat(e) {
const convertToUTC = e.toLocaleString(language, timeZone);
console.log(convertToUTC);
return convertToUTC;
}

MomentJs invalid date from datepicker

I Am trying to format a date from react datepicker, the value going in is 1441062000000
onChangeStartDate: function(value) {
this.setState({
startDate: moment(value)
})
},
When I check the date in dev tools I get a moment invalid date, can anyone tell me how I can create a date from the value?
I'm using the value 1443135600000 with format, but still getting invalid date:
onChangeEndDate: function onChangeEndDate(value) {
console.log(moment(value, ConfigProvider.getKey('dateFormat')));
You might need to pass the format as a second argument to moment - in case of react date picker, it defaults to 'x', e.g. unix timestamp:
this.setState({
startDate: moment(value, 'x')
})
If you omit the second argument, moment tries to parse the input by looking for ISO 8601 formats, but a unix timestamp will cause this algorithm to fail. That's why you need to specify the format explicitly.
The other way would be to configure your date picker to emit changes in an IS 8601 compliant format, for example format='YYYY-MM-DD'.

Resources