Moment JS seemingly returning random date - react-native

Moment JS is returning a random date.
I am trying to create a calendar in a react-native project. I created this loop to count back the days from today's date. I have attached my console and tried to clearly show how I tried to debug this.
The subtract method seems not to recognise the loop and the i value seems to stay at 16.
Any help would be greatly appreciated.
This is the code that is causing all the fussThis is the output in the console

Per Moment.js, moments are mutable. Clone the moment before performing date math
https://momentjs.com/guides/#/lib-concepts/mutability/
You'll need to create a new moment instance or clone the existing one when performing operations like .add(), .subtract(), etc.
const moment = require("moment");
const today = moment();
// count back N days
const N = 3;
let i = 1;
let days = [];
// #1 - Create a new moment instance from today and add -i days
while (i <= N) {
const day = moment(today).add(-i, "days");
days.push(day);
i++;
}
console.log("Approach #1");
console.log({ days });
// #2 - A moment is mutable. So we use add() to mutate today by -1 days each iteration, clone the instance, and push to array
i = 0;
days = [];
while (i < N) {
const day = today.add(-1, "days").clone();
days.push(day);
i++;
}
console.log("Approach #2");
console.log({ days });

Related

Kotlin: How to detect 'date change'?

I will use Timer() to execute function by 5 minutes in Kotlin.
And when I execute function by 5m, if a day passed,I want count var to be 0.
So my idea was
declare two vars
var todayDate = LocalDate.now() // 2019-09-23
var todayCount:Int = 0
After that I will check this vars in 5 minutes by using Timer()
Then todayDate value differs from previous todayDate, then I can detect date change.
However, I don't know how to compare current todayDate and previous todayDate.
Any idea? or is there any other way to know day change?
For your specific question about comparing dates you can use the isEqual() method on your LocalDate instance (docs). Something like the following would likely do what you want:
// initial state
var todayDate = LocalDate.now()
var todayCount = 0
// in each timer iteration:
val now = LocalDate.now()
if (!todayDate.isEqual(now)) {
// it's a new day
todayCount = 0
todayDate = now
} else {
// it's the same day
++todayCount
}
However if you're talking about Android and using its Timer class, you need to be aware that that runs on a background thread and you will need to persist your todayDate and todayCount values somewhere (which could be app preferences, your app DB, etc.).

Can I iterate through Vuex state data with a for loop in a Getter?

I am working on a weather app in Vuex and Chart.js. I succeeded to retrieve the data from an API with an axios call and to store the data in Vuex state and to display it with Getters in a chart. The problem is that the temperature data is divided hourly a week in advance, so there are 7 times twenty-four values ​​in one array. I don't want to display the chart in hourly divisions, but in daily divisions. So I should divide the array into 24 units, calculate an average from each of them, and then create a new array from the new 7 values.
I tried to run a for loop in a getter:
getters: {
budapestTemp: state => {
let arr = state.budapest.hourly?.temperature_2m;
let avgArray = [];
for(i = 0; i < arr.length; i += 24) {
total = arr[i] + (arr[i+1] || 0)+ (arr[i+2] || 0) ;
avg = total/3;
avgArray.push(Math.round(avg));
};
return avgArray;
},
}
The getter is mapped with mapGetter in the chartData object of the component, so it should work, but I get the following error message in the console and the browser does not display anything:
Uncaught (in promise) ReferenceError: i is not defined
at budapestTemp (index.js?68eb:24:1)
at wrappedGetter (vuex.esm-bundler.js?03c9:352:1)
I have no clue how to solve this, I would really appreciate any help. Thank you in advance.

JS - How to implement the YTD (Year To Date) logic in order to do Date selection

I am trying to implement a method for a Date selection in vue-chartjs. Here is the function that i have used in the methods life cycle hook:
DateSelect(event) {
const period = event.target.value
let minValue = new Date(Math.max(...this.date) * 1000)
const axisXMin = new Date(Math.min(...this.date) * 1000)
switch (period) {
case '1m':
minValue.setMonth(minValue.getMonth() - 1)
break
case '3m':
minValue.setMonth(minValue.getMonth() - 3)
break
case 'ytd':
minValue.setFullYear(minValue.getFullYear() - minValue.getMonth()) //Here I want to implement the YTD Logic.
break
default:
minValue = axisXMin
}
const data = this.data.filter(el => {
return el.x >= minValue
})
this.GraphOutput(data) // this is vue-chartjs function.
}
Here the logic '1m' and '3m' works absolutely fine, as they display the previous 1month's and 3month's chart to the user when the respective button is clicked.
I want to know how to implement the YTD (Year to Date) Logic in the function that i have used above. Please do help me.
As far I understand you may need a full year of data in the graph. So that you need to set the minimum value as below:
case 'ytd':
minValue.setYear(minValue.getFullYear() - 1);
break

FullCalendar V4 - How to account for shorter months in a recurring event series?

I'm using FullCalendar v4-alpha-3 with the RRule plugin to generate recurring events. It works as expected with only one problem: how do I modify a recurring event to account for months with fewer days than the starting month in a series?
For example, if the first monthly occurrence happens on January 29, 2019; the event will be repeated on the 29th of all subsequent months except in February since it only has 28 days (leap years excluded).
I've tried resetting dtstart to the first day of the following month. It works, except the event is no longer recursive.
Here's a stripped down snippet of my setup:
let calendar = new Calendar(calendarEl, {
plugins: [ rrulePlugin ],
events: [
{
rrule: 'DTSTART:20190129 RRULE:FREQ=MONTHLY;UNTIL=20200130;COUNT=13;BYMONTHDAY=29'
}
],
eventRender: function(info) {
...
// reset start date to the first day of the following month
// if current month has fewer days than base month
let start = event.start;
let day = start.getDate();
let now = new Date();
let currentMonth = now.getMonth();
let currentYear = now.getFullYear();
let daysInCurrent = getDaysInMonth(currentMonth + 1, currentYear);
let nextStart = start;
if (day > daysInCurrent) {
nextStart = new Date(currentYear, currentMonth + 1, 1);
event.setStart(nextStart);
event.setEnd(null);
}
}
});
I'd appreciate any insight.
Not quite the solution I hoped for, but RRule's bysetpos property seems to offer the next best alternative as it allows for a fallback date in case the one specified doesn't exist.
For example, the following would generate an occurrence on the 30th of every month; or the last day of the month if the 30th doesn’t exist:
FREQ=MONTHLY;BYMONTHDAY=28,29,30;BYSETPOS=-1.
Sourced from: https://icalevents.com/2555-paydays-last-working-days-and-why-bysetpos-is-useful/
I know this is an old question but maybe this will be usefull for someone:
I'm using momentjs library
monthly:
let endofmonth = moment('2020-02-29', "YYYY-MM-DD").endOf('month').format('DD');
let curday = moment('2020-02-29, "YYYY-MM-DD").format('DD');
single_event.title = title;
single_event.rrule = {};
single_event.rrule.freq = 'monthly';
single_event.rrule.dtstart = start_date;
single_event.rrule.interval = reminder_interval;
single_event.rrule.count = reminder_count;
if(endofmonth == curday){
// Checking if given day of the month is last
single_event.rrule.byweekday = ['mo','tu','we','th','fr','sa','su'];
single_event.rrule.bysetpos = -1;
}
else{
single_event.rrule.bymonthday = parseInt(curday);
}
calendar_events.push(single_event);
var calendar = new FullCalendar.Calendar(calendarEl, {
...
events: calendar_events
});
yearly:
single_event.title = title;
single_event.rrule = {};
single_event.rrule.dtstart = start_date;
single_event.rrule.count = parseInt(reminder_count);
if(endofmonth == curday){
// Checking if given day of the month is last
single_event.rrule.freq = 'monthly'; // Will work as yearly if interval is 12
single_event.rrule.interval = parseInt(reminder_interval)*12;
single_event.rrule.bymonthday = [28,29,30,31];
single_event.rrule.bysetpos = -1;
}
else{
single_event.rrule.freq = 'yearly';
single_event.rrule.bymonthday = parseInt(curday);
}
calendar_events.push(single_event);
var calendar = new FullCalendar.Calendar(calendarEl, {
...
events: calendar_events
});

How to prevent user to enter specific times in datetimepicker?

I am using angular-bootstrap-datetimepicker. I know how to restrict the user from entering specific dates.
$dates.filter(function(date){
return (date.localDateValue() <= new Date().valueOf()-(24*60*60*1000));
}).forEach(function(date){
date.selectable = false;
})
This code insode startDateBefore render, prevents user from entering dates 24h past the current date.
But now I want users to enter spectic times only. Like user can select only times between 10:05am to 11:10pm. I am unable to do that. Documentation doesn't specify on how to add filter to hour and minutes. Any help on that.
In Angular Date Time Picker, the beforeRender function also takes parameter called view. So we can use the view==='hour' to restrict users from entering past hours. I was missing the code for hours.
function startDateBeforeRender ($view, $dates, $leftDate, $upDate, $rightDate) {
var today = moment().valueOf();
$dates.filter(function (date) {
return date.localDateValue() < today -(24*60*60*1000)
}).forEach(function (date) {
date.selectable = false;
});
// to restrict hours by admin
if ($view === "hour") {
// restict previous hours
$dates.filter(function (date) {
return date.localDateValue() < today
}).forEach(function (date) {
date.selectable = false;
})
}
}
date = new Date().valueOf();
if( date > 1000*(10*60+5) ){
if( date < 1000*(23*60+10) ){
//Code green, I repeat, CODE GREEN!
}
}