This question already has answers here:
Javascript date variable assignment
(9 answers)
Closed 10 days ago.
G'day,
I would like to have 3 elements :
Current Date (to display current month)
current date less 1 month (to display the month before)
current date plus 1 month (to display the next month)
I calculate the 2 others months in getter, but when I calc my "lastmonth", it change the selectedMonth value in getter environment :
my code :
import { defineStore } from "pinia";
import type {
agendaState,
} from "#/myApp/interfaces";
export const useAgenda = defineStore("useAgenda", {
state: (): agendaState => ({
selectedMonth: new Date(),
lastMonth: new Date(),
nextMonth: new Date(),
}),
getters: {
lastMonthCalc: (state: agendaState): Date => {
console.log("selectedMonth before : ", state.selectedMonth);
const myDate = state.selectedMonth;
state.lastMonth = myDate;
state.lastMonth = new Date(
state.lastMonth.setMonth(state.lastMonth.getMonth() - 1)
);
console.log("lastMonth after : ", state.lastMonth);
return state.lastMonth;
},
nextMonthCalc: (state: agendaState): Date => {
console.log("selectedMonth before : ", state.selectedMonth);
const theDate = state.selectedMonth;
state.nextMonth = theDate;
state.nextMonth = new Date(
state.nextMonth.setMonth(state.nextMonth.getMonth() + 1)
);
console.log("nextMonth after : ", state.nextMonth);
return state.nextMonth;
},
},
});
The VueJS plugin in chrome display :
My console log looks like (in the chrome console) :
And I would like to have :
selectedMonth = Thu Feb 09 2023 11:05:41 GMT+0100 (heure normale d’Europe centrale),
lastMonth: Mon Jan 09 2023 11:05:41 GMT+0100 (heure normale d’Europe centrale),
nextMonth: Thu Mar 09 2023 11:05:41 GMT+0100 (heure normale d’Europe centrale),
Do you know why ? What is my mistake ?
I try a lot of things but nothing workss.
I find the solution .... the good code is this one :
import { defineStore } from "pinia";
import type {
agendaState,
} from "#/interfaces";
export const useAgenda = defineStore("useAgenda", {
state: (): agendaState => ({
selectedMonth: new Date(),
}),
getters: {
lastMonth: (state: agendaState): Date => {
const myDate = new Date(state.selectedMonth);
new Date(
myDate.setMonth(myDate.getMonth() - 1)
);
return myDate;
},
nextMonth: (state: agendaState): Date => {
const theDate = new Date(state.selectedMonth);
new Date(
theDate.setMonth(theDate.getMonth() + 1)
);
return theDate;
},
},
});
Thanks to my cat to show me what is the point so I change the code for this last version !!!!
Related
I'm building a live music gig listing app in React Native with expo.
An array of gig objects is fetched from firebase, with the following shape:
gigs:
[
{
dateAndTime:{seconds:2345234748},
gigName: 'gigAtVenue',
...
},
{...}
]
In my component listByDay.txs, I've written some code to filter through this array of gig objects, and return only the current day's gigs:
const gigsToday = gigs.filter((gig) => {
const formattedDate = format(new Date(currentDateMs), 'do MMMM Y')
const formattedGigDate = format(new Date(gig.dateAndTime.seconds*1000) ,'do MMMM Y')
return formattedGigDate === formattedDate
})
I've written the following test, but it seems very clunky to be re-writing the filter function for my test - is there a way I can "extract" the filter from it's component listByDay.tsx? What's the best library to use for a test like this?
test('should filter gigs by date', () => {
// create an array of gigs
const gigs = [
{ dateAndTime: { seconds: 1609459200 } }, // 1 September 2021
{ dateAndTime: { seconds: 1609545600 } }, // 2 September 2021
{ dateAndTime: { seconds: 1609632000 } }, // 3 September 2021
]
// create a new date object with the current date
const currentDate = new Date(2021, 8, 1) // 1 September 2021
// pass the gigs and currentDate to the filter function
const gigsToday = gigs.filter((gig) => {
const formattedDate = format(currentDate, 'do MMMM Y')
const formattedGigDate = format(new Date(gig.dateAndTime.seconds*1000) ,'do MMMM Y')
return formattedGigDate === formattedDate
})
// check that the filter function returned the correct gigs
expect(gigsToday).toBe([{ dateAndTime: { seconds: 1609459200 } }])
})
You can create a standalone callback function to be used by the first parameter of Array.filter.
Remove the callback function from the react component body, then you can export the function to be unit tested it by itself.
const gigs = [{
dateAndTime: {
seconds: 2345234748
},
gigName: 'gigAtVenue',
}]
export const filterByToday = (gig) => {
const formattedDate = format(new Date(currentDateMs), 'do MMMM Y')
const formattedGigDate = format(new Date(gig.dateAndTime.seconds * 1000), 'do MMMM Y')
return formattedGigDate === formattedDate
}
const ListByDay = ({ gigs }) => {
const gigsToday = gigs.filter(filterByToday)
return (
// some JSX
)
}
I'm working on DayPicker to get all the range dates, but I couldn't have any good idea of knowing the dates between the start date and end date.
import { DateRange, DayPicker } from 'react-day-picker'
const [range, setRange] = useState<DateRange | undefined>()
useEffect(() => {
if(range && range.from && range.to) {
console.log('range.from', range.from)
console.log('range.to', range.to)
// range.from Mon Aug 01 2022 00:00:00 GMT-0700 (Pacific Daylight Time)
// range.to Sat Aug 06 2022 00:00:00 GMT-0700 (Pacific Daylight Time)
// I want get 8/1, 8/2, 8/3, 8/4, 8/5 as string data
}
}, [range])
return (
<DayPicker
mode="range"
defaultMonth={new Date()}
selected={range}
onSelect={setRange}
/>
)
Use date-fns and create a function.
const getDatesInRange = (startDate: Date, numberOfDays: number) => {
const dates: Date[] = [];
[...Array(numberOfDays + 1)].forEach((_, i) => {
dates.push(addDays(startDate, i));
});
console.log(dates); // For debugging purposes
return dates;
};
Add an array state const [dateRangeArray, setDateRangeArray] = useState<Date[]>(); and and we update the useEffect.
Here is the full code:
import { addDays, differenceInDays } from 'date-fns';
// inside the component
const [range, setRange] = useState<DateRange | undefined>();
const [dateRangeArray, setDateRangeArray] = useState<Date[]>();
const getDatesInRange = (startDate: Date, numberOfDays: number) => {
const dates: Date[] = [];
[...Array(numberOfDays + 1)].forEach((_, i) => {
dates.push(addDays(startDate, i));
});
console.log(dates); // For debugging purposes
return dates;
};
useEffect(() => {
if (range && range.to && range.from && dateRangeArray === undefined) {
let daysDiff = differenceInDays(range.to, range?.from);
setDateRangeArray(getDatesInRange(range.from, daysDiff));
}
if (range && range.from && range.to) {
console.log('range.from', range.from);
console.log('range.to', range.to);
// range.from Mon Aug 01 2022 00:00:00 GMT-0700 (Pacific Daylight Time)
// range.to Sat Aug 06 2022 00:00:00 GMT-0700 (Pacific Daylight Time)
// I want get 8/1, 8/2, 8/3, 8/4, 8/5 as string data
}
}, [range]);
return (
<div>
<DayPicker mode='range' defaultMonth={new Date()} selected={range} onSelect={setRange} />
</div>
);
I'm trying to compare two dates in UTC format with date-fns, but I'm not getting it. The two values look the same, but the isEquals() function returns false for comparison.
The purpose of the code below is to search for the schedules that are marked and check if they fit the times of the array range, if there is a compatible schedule, it returns the object by inserting it in the constant date
import React, { useState, useEffect } from 'react';
import { utcToZonedTime } from 'date-fns-tz';
import {
format,
setHours,
setMinutes,
setSeconds,
isBefore,
isEqual,
parseISO,
} from 'date-fns';
import enUS from 'date-fns/locale/en-US';
import api from '~/services/api';
const range = [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
export default function Dashboard() {
const [date, setDate] = useState(new Date());
useEffect(() => {
async function loadSchedule() {
const response = await api.get('schedule', {
params: { date },
});
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const data = range.map((hour) => {
const checkDate = setSeconds(setMinutes(setHours(date, hour), 0), 0);
const compareDate = utcToZonedTime(checkDate, timezone);
return {
time: `${hour}:00h`,
past: isBefore(compareDate, new Date()),
appointment: response.data.find((appoint) =>
isEqual(parseISO(appoint.date), compareDate)
),
};
});
setSchedule(data);
}
loadSchedule();
}, [date]);
}
I made a test code to print the results on the Reactotron and below are the printed values:
console.tron.log(`${isEqual(parseISO(response.data[1].date),
compareDate)}\n
${parseISO(response.data[1].date)}\n${compareDate}`);
Result:
false
Wed Jun 10 2020 19:00:00 GMT-0300 (Brasilia Standard Time)
Wed Jun 10 2020 19:00:00 GMT-0300 (Brasilia Standard Time)
Actual values for each of the dates:
console.tron.log(`${response.data[1].date}\n${compareDate}`);
2020-06-10T22:00:00.000Z
Wed Jun 10 2020 20:00:00 GMT-0300 (Brasilia Standard Time)
But if I print only the value of the compareDate variable, it changes the format:
console.tron.log(compareDate);
2020-06-10T21:00:00.002Z
date-fns's isEqual() function also takes into consideration the milliseconds value, as questioned in the comments.
This information can also be found on date-fns isEqual() docs, in the example:
// Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal?
var result = isEqual(
new Date(2014, 6, 2, 6, 30, 45, 0),
new Date(2014, 6, 2, 6, 30, 45, 500)
)
// it returns false`
You should import setMilliseconds() from date-fns and also use it in the line where you set checkDate value.
I am attempting to compare 2 dates and I am getting an error.
These are my functions:
const validateDate = (date: string): Moment => {
return moment(`${moment().year()}/${date}`);
};
export const themes: Theme[] = [{
siteCode: '',
costCenter: '',
theme: 'spring',
bannerImage: 'spring.jpg',
cssOverride: 'springThemeStyles.scss',
endDate: moment(validateDate('6/19')).toDate(),
startDate: moment(validateDate('3/20')).toDate()
}];
export const getActiveTheme = (): any => {
const now = moment().toDate();
console.log(now); // Thu Mar 19 2020 21:56:10 GMT-0600 (Central Standard Time)
console.log(themes[0].startDate); // Fri Mar 20 2020 00:00:00 GMT-0600 (Central Standard Time)
console.log(themes[0].startDate >= now); // true
return themes.map((t: Theme) => {
if (t.startDate >= now) { // this is always true I don't know why
if (t.theme.toLowerCase() === 'spring') {
return require('../../../styles/spring.theme.scss');
}
return null;
}
});
};
I don't get why the condition if (t.startDate >= now) {...} is always true.
Any thoughts?
It is simply because startDate is on the Fri Mar 20 2020 and now is on the Thu Mar 19 2020 so it's clear that startDate >= now should be true
Since you have set your startDate to the 20th, startDate >= now would be false when now would be on 21th
Below is the code I am using in Hooks to update the updatedAt column for two objects:
hooks: {
afterUpdate: (group, options, callback) => {
console.log("groudId " + groupId + " options " + options)
},
afterCreate: (member, options, callback) => {
return new Promise((resolve, reject) => {
sequelize.models.Group.findOne({
where: {
id: member.group_id
}
}).then((group) => {
if (group) {
var date = new Date();
console.log("BEFORE group.updatedAt " + group.updatedAt)
group.dataValues.updatedAt = new Date()
console.log("CHANGED group.updatedAt " + group.updatedAt)
group.save().then((Group) => {
if (Group) {
console.log("UPDATED Group.updatedAt " + Group.updatedAt)
console.log("UPDATED group.updatedAt " + group.updatedAt)
resolve(Group)
} else {
console.log("NO GROUP Found")
return reject(group.id)
}
}).catch((error) => {
return (error)
})
} else {
return reject(id)
}
}).catch((error) => {
return (reject)
})
})
}
Console Log:
BEFORE group.updatedAt Fri Feb 17 2017 17:36:00 GMT-0800 (PST)
CHANGED group.updatedAt Tue Feb 28 2017 14:00:17 GMT-0800 (PST)
UPDATED Group.updatedAt Tue Feb 28 2017 14:00:17 GMT-0800 (PST)
UPDATED group.updatedAt Tue Feb 28 2017 14:00:17 GMT-0800 (PST)
BEFORE group.updatedAt Fri Feb 17 2017 17:36:00 GMT-0800 (PST)
CHANGED group.updatedAt Tue Feb 28 2017 14:00:19 GMT-0800 (PST)
UPDATED Group.updatedAt Tue Feb 28 2017 14:00:19 GMT-0800 (PST)
UPDATED group.updatedAt Tue Feb 28 2017 14:00:19 GMT-0800 (PST)
While the log, what I think, appears correct, why isn't the actual object in the DB updated to the new updatedAt value? Or is there an easier way to update an objects updatedAt column?
This worked for me
group.changed('updatedAt', true)
await group.update({
updatedAt: new Date()
})
Calling just update with updatedAt = new Date is not enough, you must flag column as changed
The following worked for:
group.changed('updatedAt', true)
This will mark the updatedAt column as dirty so it will be updated.
None of the above worked for me, so I had to use model method instead:
await MyModel.update({ updatedAt }, { where: { id: instance.id }, silent: true });
Accodrding to the docs, you can update an instance value by calling instance.set(key, value, [options]), so, in your case it should be:
console.log("BEFORE group.updatedAt " + group.updatedAt)
group.set('updatedAt', new Date())
console.log("CHANGED group.updatedAt " + group.updatedAt)
group.save().then((Group) => { /* the other part of your code*/ })
I was able to update the updatedAt property on a model instance with the .changed() method. This only works if you set two property instances to changed = true
group.changed('updatedAt', true)
group.changed('exampleProperty', true)
await group.save({ silent: false })
it's work
sequelize.getQueryInterface().queryGenerator.updateQuery(
'YOU_TABLE',
{ updated_at: sequelize.literal('CURRENT_TIMESTAMP') },
{ id: 1 },
{ returning: false },
)
sequelize.query(query)
The only thing that worked for me:
await sequelize.query("UPDATE groups SET updatedAt = :date WHERE id = :id", {
replacements: { date: new Date(2012, 7, 22, 2, 30, 0, 0), id: group.id },
});
I made a few small changes to Alexander Zinchuk's code and it works for me:
await MyModel.update({ updatedAt: new Date() }, { where: { id: instance.id }})