MomentJS providing time an hour behind what is selected - reactjs

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.

Related

RangeError: Invalid Time Value after incorporating local storage

I'm working on a forum and using a form that the user fills out I'm storing data as an object inside an array. The data I'm storing includes the title of a topic, the message, the author and the date. That data is stored inside a topic array which I'm mapping on screen so the user can see all current topics, who created them and the date in which they were created. I also started to use localStorage so I can save my data and test to make sure everything looks good after my page refreshes.
const [topic, setTopic] = useState(() => {
const topicJson = localStorage.getItem("topic");
return topicJson ? JSON.parse(topicJson) : [];
});
const updatedTopic = [
...topic,
{
title: title,
message,
author: "Dagger",
date: new Date(),
},
];
setTopic(updatedTopic);
};
That's the code that I'm using which works as intended however when I map through the array to post the data on screen, I'm having trouble with showing the date. I'm using date-fns because it displays the date exactly how I want it.
Example: 2/19 9:39PM. That's how I want the date to look on screen and using date-fns has been the only thing I've found that makes it look that way.
{topic
.sort((a, b) => b.date - a.date)
.map(({ date }, index) => (
<tr>
{<td>{format(date, "M/dd h:mma")}</td>}
</tr>
))}
That's the code I'm using to map through the array to show the date. Before adding localStorage it worked fine. When I remove the format and show the code as date it works but including format gives me this error:
throw new RangeError('Invalid time value');
// Convert the date in system timezone to the same date in UTC+00:00 timezone.
// This ensures that when UTC functions will be implemented, locales will be compatible with them.
I think your are using Date object to store date and JSON.stringify cant handle Date object. You should to use Date method.
Easy way just save not Date object but ISO string.
date.toISOString()
And in table:
{<td>{format(parseISO(date), "M/dd h:mma")}</td>}

React Big Calendar - change the agenda range to include all days of the current month only

I want to modify the visible range showed in the agenda view so it includes all the days from the current month only, so far this is my attempt:
const Scheduler = () => {
const [currentDate, setCurrentDate] = useState(new Date())
const onNavigate = newDate => {
const d = new Date(newDate.getFullYear(), newDate.getMonth(), 1);
setCurrentDate(d)
}
return (
<Calendar
onNavigate={onNavigate}
date={currentDate}
/>
)
}
So because per default the length prop is set to 30 to accomplish my goal I just need to set the day of date prop to always be first one, this is why inside onNavigate function I create a new Date object (called d in my code) in which I basically copy the Date object being received by the function but set its day to 1.
This works only the first time I click the next button, if I attempt to go to future months nothing happens and when I log the Date object received by the function(newDate in the code) it changes only the first time the function is called but after that the Date it receives is always the same one.
This happens only for the agenda view and only when going to future months.
I can go just fine to past months in the agenda view and in the calendar view I can go to future and past months without problems.
PD: I omited unnecessary props like events, localizer... etc because I think they are not relevant as the calendar works fine is just this functionality I'm trying to change that is not working as expected.

How to handle date picker in Cypress

How to select a past date in the DOB field? What Javascript function can I use in Cypress automation?
It is not a free text field, only can select from the date picker. Here is the screenshot and the HTML
<input _ngcontent-kgi-c484="" id="dob" formcontrolname="dob" readonly=""
bsdatepicker="" placeholder="Optional" class="form-control
plore-form-control ng-valid ng-touched ng-dirty" ng-reflect-name="dob"
ng-reflect-bs-config="[object Object]"
ng-reflect-max-date="Fri Apr 16 2021 00:00:00 GMT+1">
I tried this function but it didn't work
cy.get('#dob').invoke('val').then((text) => {
expect('08/05/1999').to.equal(text);
What I did was add a custom command (we have various datepickers throughout our system, each having a slightly different selector).
Cypress.Commands.add("setDateInput", (selector, value) => {
// wait for the flatpickr instance to be applied before setting the date
// 'flatpickr-input' class is added on initiation
cy.get(`${selector}.flatpickr-input`).then($el => {
$el.get(0)._flatpickr.setDate(value, true)
})
});
Here, you can pass in a changing selector and then the DD/MM/YYYY format as parameters. Hope this helps someone.
The control is a bunch of buttons, you can click them in Cypress, e.g
cy.get('button').contains('8').click(); // select the 8th day
The chevrons (left and right) you'll need to click a few times,
cy.get('button.uib-left').click().click().click().click() // keep going for MM/YY
You can click on that middle part, but I can't figure that one out exactly.
Ok, I figured it out, click "April 2021" once to choose the month
cy.get('button').contains('April 2021').click();
// now select the month
cy.get('button').contains('May').click()
OR click the "April 2021" then "2021" to select the year
cy.get('button').contains('April 2021').click();
cy.get('button').contains('2021').click();
cy.get('button.uib-left').click().click() // get decade with 1999
// now select the year
cy.get('button').contains('1999').click()
But you get the idea, interact the way a user does.

Antd Timepicker set defaultValue from variable

As per their Timepicker library i did following in React:
<TimePicker defaultValue={moment(dbTime1, format)} format={format}
onChange={time => setStartTime(moment(time).format(format))}/>
the state is:
const [dbTime1, setDbTime1] = useState("");
const [startTime, setStartTime] = useState(new Date());
Reading from database the string value 09:00 with:
setDbTime1(moment(timeWindowsData.din_times_for_rep[0].val));
The problem that the visual part is not displaying required to me 09:00 time, it just offering to select a time. If I do some modifications to the formats, etc - it gaves me various errors. Starting from invalid date and finishing with ipossibility to select a time, falling back to Date(), etc.
How can I store the variable and display the time in time field as default value?
It's working if i just drop the string there:
<TimePicker defaultValue={"09:00", format)} format={format}
onChange={time => setStartTime(moment(time).format(format))}/>
But I need that it must read from variable.
I removed this component and used the other ones.

React-datepicker changes date but not time

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 || ""
});
}

Resources