I am pulling varchar dates from a db table, and trying use them to get the date of both the previous day and next day. In the example below, I would have grabbed 2020-03-26 from my table. I am trying to figure out how to get both 2020-03-25 and 2020-03-27 saved as variables that I can then use. I have figured out that in order to get the date the exact format that I want I have to use the toISOString and slice off the first 10 characters, but I am unsure how to get the previous and next days, especially if a month crossover had occurred.
var tableDate = new Date('2020-03-26')
tableDate = tableDate.toISOString().slice(0,10)
Try this one:
let tableDate = new Date('2020-03-26');
// function to increment
function incrementDate(date, days) {
let result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
// funtion to decrement
function decrementDate(date, days) {
let result = new Date(date);
result.setDate(result.getDate() - days);
return result;
}
console.log(incrementDate(tableDate, 1).toISOString().split('T')[0]);
console.log(decrementDate(tableDate, 1).toISOString().split('T')[0]);
The decidedly easiest way is using dayjs.
With it set up you'd use it something like,
const tableDate = new Date('2020-03-26')
const dayBefore = dayjs(tableDate).subtract(1, 'day')
const dayAfter = dayjs(tableDate).add(1, 'day')
You can then apply .toISOString(), or you can simply use .format() to get the exact output you'd prefer from the outset.
Related
I am trying to have previous day, current day, and next day buttons so for example, if I press the next button, it will take today's date, add one to today's date and show tomorrows information on the page.
My click handler looks like:
const nextHandler = () => {
let resDate = new Date();
let year = resDate.getFullYear();
let day = new Date().getDate();
let month = resDate.getMonth() + 1;
if (month.toString().length < 2 || day.toString().length < 2) {
month = ('0' + month).slice(-2);
day = ('0' + day).slice(-2);
}
day = parseInt(day) + 1;
let newDate = `${year}-${month}-${day}`;
// newDate --> 2021-04-11
history.push(`/dashboard?date=${newDate}`);
};
When I click my next button I get taken to: http://localhost:5000/reservations?date=2021-04-12 exactly as I would like. However, I am only able to add to the day once. How am I continuously able to update this query string?
You're only ever starting with new Date(); on your second line so it'll only ever increment once. You'll have to read from the querystring a value to put in new Date(VALUE); if it's set so that it continues to remember. Here's a stackoverflow answer from something like that: How can I get query string values in JavaScript?
You're code may look like:
const urlParams = new URLSearchParams(window.location.search);
const dateParam = urlParams.get('date');
let resDate = dateParam ? new Date(dateParam) : new Date();
It's nextHandler is using today's date to increment rather than the date of the query string.
On the first click, nextHandler today's date to increment. But, the next click should start from the date in the query string.
I hope that solve your problem.
I am working on firebase cloud functions that i'm new to , using javascript. I have a need to add n number of days to a user who has renewed a subscription.
Here is part of the function
...
var sellerRef = admin.firestore().doc('sellerProfile/'+req.query.sellerId)
var seller = sellerRef.get().then(snapshot=>{
const data= snapshot.data()
var currentDate = data.subscriptionDeadline.toDate()
Date.prototype.addDays= function(d){
this.setDate(this.getDate() + d);
return this;
};
var newDate = currentDate.addDays(30);
res.send(newDate)
})
sellerRef.update({
subscriptionDeadline: Date.parse(newDate)
})
...
In that code i got the subscription deadline of an individual then used a prototype to add 30 days as a subscription renewal. How do i convert the days back to timestamp to be able to save the new subscription deadline to firestore or better if i could add the 30 days without converting the timestamp to date.
Firestore Timestamps objects don't offer any date math operations. It will be easier if you do convert the Timestamp into a Date (or something else that lets you do math), the convert back to a Timestamp.
const timestamp = data.subscriptionDeadline;
const date = timestamp.toDate();
const laterDate = new Date(date.getTime() + 30*60*60*1000);
const laterTimestamp = admin.firestore.Timestamp.fromDate(laterDate);
I am trying to set up a Google App Script function that grabs a date (formatted dd/mm/yy) from the last column of a spread, and creates a new column with the date + one day.
I have seen previous solutions and tried to use the same, i.e.newDate.setDate(lastDate.getDate()+1) but have had issues getting the value formatted correctly in the script. This is a variation of my code that I'm using to loop through for a year's worth of values to see what I get:
for (var i=0;i<365;i++){
var lastRow = outputSheet.getLastRow();
var newDate = new Date();
var lastDate = outputSheet.getRange(lastRow,1).getValue();
var newDateRng = outputSheet.getRange(lastRow+1,1);
Logger.log(lastDate + 1, typeof lastDate, typeof (lastDate + 1));
newDate.setDate(lastDate.getDate());
Logger.log(newDate);
newDate.setDate((newDate.getDate() + 1));
Logger.log(newDate);
var newDateFormatted = Utilities.formatDate(newDate, ss.getSpreadsheetTimeZone(), "dd/MM/YY");
Logger.log(newDateFormatted);
newDateRng.setValue(newDateFormatted);
}
With a start date of "01/03/2020", I get the following behaviour:
01/03/2020
02/05/2020
03/05/2020
...
31/05/2020
01/06/2020
02/05/2020
03/05/2020
...
31/05/2020
01/06/2020
02/05/2020
...
etc. All the way through the year. Although the day increase, the month seems to reset after the first day of the month.
As a note, I am specifically looking to pick the date off of the spreadsheet rather than using new Date as today and new Date +1 as tomorrow.
Thanks
You need to use a different variable in the loop otherwise you will always return to the same month.
Also avoid using strings for the result, keep date objects and display it properly.
The code goes like this :
function otherTest(){
var lastDate = SpreadsheetApp.getActiveSheet().getActiveCell().getValue();
var date = new Date(lastDate); // create new date object
var result = [];
for (var i=0;i<365;i++){
date=new Date(date).setDate(new Date(date).getDate()+1)
Logger.log('date='+new Date(date))
result.push([new Date(date)]);
}
SpreadsheetApp.getActiveSheet().getRange(1,2,result.length,1).setValues(result).setNumberFormat('dd/MM/yyyy');
}
I have a method that accepts a javascript date with time as input, and determines if the current date and time is within -30 mins. However, when I debug this at runtime, moment.add doesn't seem to be working with minutes as expected.
function isWithinRange(myDate: Date){
// convert to Moment obj
let myMoment = moment(myDate);
let todayMoment = moment(new Date());
let myMomentOk = myMoment.isValid();
let todayOk = todayMoment.isValid();
// create range values
let preTime = myMoment.subtract('m', 30);
let postTime = myMoment.add('m', 30);
//check values are as expected
let localeTime = myDate.toLocaleString();]
let preLocale = preTime.toLocaleString();
let postLocale = postTime.toLocaleString();
let result = todayMoment.isBetween(preTime, postTime);
return result;
}
But when I inspect the localeTime, preLocale and postLocale times at run time, all three values are the same, "Tue Jun 26 2018 09:58:00 GMT-0400". The add and subtract minutes statements had no impact.
What am I missing or doing wrong here?
Please note that both add() and subtract mutate the original moment.
add():
Mutates the original moment by adding time.
subtract:
Mutates the original moment by subtracting time.
so you have to use clone()
Moreover, in the recent version of moment, the first argument is the amount of time to add/subtract and the second argument is the string that represent the key of what time you want to add
add and subtract takes the amount of time first, and then what type of time, as documented here. Also make sure to create a new moment object for each calculation, as it mutates the moment object.
let preTime = moment(myMoment).subtract(30, 'm');
let postTime = moment(myMoment).add(30, 'm');
You're working on the same moment object all the time, because of this you have the original moment object at the time you're doing let localeTime = myDate.toLocaleString().
You just need to create a new moment object so you don't revert your changes.
...
// create range values
let preTime = moment(myMoment).subtract('m', 30);
let postTime = moment(myMoment).add('m', 30);
...
I think what you need to use is https://momentjs.com/docs/#/query/is-between/ isBetween method from the moment.
const testDate = moment()
testDate.isBetween(moment().subtract(30, 'm'), moment().add(30, 'm'))
// true
const testDate = moment().add(2, 'h');
testDate.isBetween(moment().subtract(30, 'm'), moment().add(30, 'm'))
// false
I think this should help.
I have an array with many dates, they are not in the date type but string like: "2016-08-12" for example. Then what I would like to do is to remove all dates that we already have passed. So therefor im trying to compare them to todays date and then remove it if its passed. Using typescript by the way.
my array, named datoArray, looks like this:
["2016-08-02", "2016-08-11", "2016-08-22", "2016-09-10"]
just with a lot more of the same...
then here's what I try to do:
for(var i = 0; i < this.datoArray.length; i++){
this.skoleAar = parseInt(this.datoArray[i].slice(0,4))
this.skoleMaaned = parseInt(this.datoArray[i].slice(5,8))
this.skoleDag = parseInt(this.datoArray[i].slice(8,10))
if(this.skoleAar < dagensAar){
this.datoArray.splice(i, 1);
}
if(this.skoleAar == dagensAar && this.skoleMaaned < dagensMaaned){
this.datoArray.splice(i, 1);
}
if(this.skoleAar == dagensAar && this.skoleMaaned == dagensMaaned && this.skoleDag < dagensDag){
this.datoArray.splice(i, 1);
}
}
the "dagensAar", "dagensMaaned" and "dagensDag" variables im getting from another function that works. If i "console.log" the variables it prints out int values like 2016 for the year and 8 for the month if i take from the start of the array, and for the "dagensAar", "dagensMaaned" and "dagensDag" it prints 2016 11 20, which is todays year, month and day. all is in Int type, so what im not getting here is why my "if" doesnt work? It seems like there is something wrong with the way i compare the, but i thought this was the way to compare int values?
If the dates are in ISO-8601 format then you can simply filter using Date.parse().
var dates = ["2016-08-02", "2016-08-11", "2016-08-22", "2016-09-10", "2016-12-15"];
function removePastDates(data) {
var today = new Date();
console.log('Initial state: ' + data);
var modified = dates.filter(function(dateString) {
return Date.parse(dateString) >= today;
});
console.log('Final state: ' + modified);
return modified;
}
var newDates = removePastDates(dates);
Your dates seem to be RFC compliant, meaning they can be directly fed into a new Date object. Simply compare to today and filter by that:
var today = new Date()
var futureDates = this.datoArray.filter(d => new Date(d) >= today)
(pre-ECMA6:)
var today = new Date()
var futureDates = this.datoArray.filter(function (d) {
return new Date(d) >= today;
})
I think the problem is not related to the dates.
I think the problem is that you are removing items from the array while looping the same exact array.
You should maybe try looping from the end of the array to the beginning or just save the indexes that you need to remove and later do the actual removing.
Keep in mind that when you remove an item you change the index of every item in the remaining of the array - maybe you should start removing from the greatest index so it will not confuse you.