Date Range is starting with Plus - javascript

I have created a small function which give all dates between two dates.
but this is starting from Plus 1 date.
Here's my code (also on Here is jsfiddle):
function DateRangeArr(to, from) {
console.log(to);
console.log(from);
var Dateresult = [];
var end = new Date(from);
var loop = new Date(to);
while (loop <= end) {
Dateresult.push({ 'total': 0, 'log_date': loop });
var newDate = loop.setDate(loop.getUTCDate() + 1);
loop = new Date(newDate);
}
return Dateresult;
}
console.log(DateRangeArr('2020-12-05','2020-12-12'));
It's giving me results starting from 2020-12-06 to 2020-12-13. Also will it gives result depending upon user time zone ?

There are a couple of things going on that could account for the problem.
(This is probably the thing you're seeing) You're changing the state of the Date instance that you added to the array after adding it. That changes the instance that's in the array.
Since "2020-12-05" is a date-only string, it's parsed as UTC in specification-compliant browsers (see the rules at Date.parse), so the Date objects will represent midnight on that date UTC rather than midnight on that date in your local timezone. If you want them to reliably be midnight local time, add T00:00 to the string. If you want them to be parsed reliably as UTC, you should be able to use them as-is, but the spec moved around on this (ES2015 said they should be parsed as local time, not UTC, before being updated by ES2016) so to get UTC reliably, add T00:00Z to it. (My understanding is that the spec allows just adding a Z, but others read the spec differently, and both Safari's JavaScriptCore and Firefox's SpiderMonkey reject new Date("2020-12-05Z"), so add T00:00Z.) Or use new Date(Date.UTC(year, month - 1, day)) instead.
You're mixing up accessors here: loop.setDate(loop.getUTCDate() + 1). That's using the UTC accessor to get the date, but then the local time accessor to set it. You need to be consistent in order to add a day to the date.
You haven't said how you're using the resulting array of Date objects, but just note that the date they show may seem off if (for instance) you parse them as UTC but then display the result in local time or vice-versa, because of the time zone offset.
You have to and from reversed in your code. You're using them consistently, but it's quite hard to read. :-) When building an array in date order, it goes from the earlier date to the later date.
Here's a version updated to work entirely in UTC; the resulting Date objects represent midnight UTC on each of the dates:
function dateRangeArr(from, to) {
console.log(from);
console.log(to);
var dates = [];
var end = new Date(to + "T00:00Z");
var loop = new Date(from + "T00:00Z");
while (loop <= end) {
dates.push({ "total": 0, "log_date": new Date(+loop) });
loop.setUTCDate(loop.getUTCDate() + 1);
}
return dates;
}
console.log(dateRangeArr("2020-12-05","2020-12-12"));
(I've also updated the function and variable names to be more consistent with standard practice in JavaScript, since the function isn't a constructor function.)
Here's a version that works in local time instead:
function dateRangeArr(from, to) {
console.log(from);
console.log(to);
var dates = [];
var end = new Date(to + "T00:00");
var loop = new Date(from + "T00:00");
while (loop <= end) {
dates.push({ "total": 0, "log_date": new Date(+loop) });
loop.setDate(loop.getDate() + 1);
}
return dates;
}
console.log(dateRangeArr("2020-12-05","2020-12-12"));
Which you use depends on whether you want the Date instances to represent midnight UTC (use the UTC version) or midnight local time (use the local time version).

Related

How to get local time date instead UTC time in Node.js?

I want to get variable to save image name format using the date.
I use this following code.
const time = new Date().toJSON().slice(0,10).replace(/-/g, '');
My expected variable is 20220629. Because my local time is June 29, 2022.
But, the result variable is 20220628. I think this result time using UTC time.
Update:
I try to using JS method like toLocalDateString() and get local time.
const time = new Date().toLocaleDateString().replaceAll('/', '');
But the result is 29062022 not 20220629.
Can anyone help me how to convert into localtime? Thank you.
The date functions rely a lot on system settings to get your local date and time. If you're in the U.S. that happens to be month/day/year.
You simply need to deconstruct it to get what you're looking for. The below code will get it in the order you're looking for (and account for the month being 0-indexed):
const time = new Date()
const time2 = '' + time.getFullYear() + (time.getMonth() + 1) + time.getDate().toString().padStart(2,'0')
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Replace builtin Date without being able to recover original constructor

I want to replace Date inside a JavaScript VM (V8 but this is not specific to V8), and make it impossible to access the original Date constructor. This is meant to be one part of a defence against timing attacks like Spectre with multi-tenant JavaScript running in the same process (but different JavaScript VM.) The idea is to deny access to high resolution timers. Cloudflare does this in their Workers, for the same reason. Time is advanced only when IO happens, not during computation. I know there are other ways to construct a timer, but I'm just focused on Date for this question.
I think this can be done in pure JavaScript, and this is my attempt. Is there a way to get the original Date constructor back after running this? Is there a way this differs functionally from the builtin Date - something that could break backwards compatibility?
// Current UNIX timestamp in milliseconds, but that we set manually on each call to runTasks.
// not advancing time during computation is one of our defenses against Spectre attacks.
let NOW = Date.now();
export function setDate(unixTimestampMillis) {
NOW = unixTimestampMillis;
}
Date = function (BuiltinDate) {
function Date(...args) {
if (new.target === undefined) {
// This is the deprecated naked Date() call which returns a string
return (new BuiltinDate(NOW)).toString();
}
// Otherwise it was the constructor called with new
if (args.length === 0) {
// Return the "current" time.
return new BuiltinDate(NOW);
}
// Build a Date with the specified datetime
return new BuiltinDate(...args);
}
// Make a copy of the BuiltinDate "class" and replace the constructor,
// It needs to be impossible for the user to grab an reference to BuiltinDate.
Date.prototype = BuiltinDate.prototype;
BuiltinDate.prototype.constructor = Date;
// Add the static methods now(), UTC(), and parse() - all of which return a numeric timestamp
function now() {
return NOW;
}
Date.now = now;
Date.parse = BuiltinDate.parse; // returns a number
Date.UTC = BuiltinDate.UTC; // returns a number
return Date;
}(Date);

Moment js: moment(0) = Wed Dec 31 1969?

I tried to make null date.
so I tried to make them all 0 when I click the clear button.
this.clear = function () {
_this.newQuarters.forEach(function (_value, index) {
_value.startDate = 0;
_value.endDate = 0;
_value.suppressAllocation = false;
_value.quarters.forEach(function (_childValue, index) {
_childValue.startDate = 0;
_childValue.endDate = 0;
_childValue.suppressAllocation = false;
});
});
};
}
After that, I tried to add 0 at moment from other function.
this.newQuarters.forEach(function (_value, index) {
var startDate = moment(_value.startDate);
but, it display startDate = Wed Dec 31 1969.
Please help me to find to make all date are null.
When passing a number to the moment() function, it interpret it as a unix timestamp.
Which is the number of second since EPOCH time, or 01-01-1970.
So passing 0 to that function result in the very first second of jan 1 1970. As Bergi pointed out, you are probably displaying your dates in your local timezone, which could result in a time before 01-01-1970.
If you want to create a null date, you should set your startDate to null and handle it correctly ( with an if statement).
You could also set the date back to the current time by passing no argument to the moment() function.
Dates can be tricky to work with in an application. There is no such thing as time that is not time. At least not in the world of programming. For this reason we have to create our own understanding of what a lack of time will be.
There is no time without time but there is a lack of value.
You obviously understand this, you had an approach, in your case, you seem to be fine with simply having time be zero, it just broke when working with moment as moment is using EPOCH time. Thus, zero is time.
You are going to have to test like the rest of us.
this.newQuarters.forEach(function (_value, index) {
var startDate = _value.startDate ? moment(_value.startDate) : null;
Lack of time could be whatever you want, undefine, null, a beginning date
Be consistent: Database vendors and languages handle things differently, front end is not always the same time zone, etc.
If you are dealing with momentjs library, there is a function: invalid()
You can easily make your variables invalid moment object and control their validity.
let currentDate = moment(); // Valid moment object
console.log(currentDate.format());
// make the moment object invalid
currentDate = moment.invalid();
console.log(currentDate.isValid()); // Check validity
console.log(currentDate.format()); // Invalid date
// make the moment object valid again
currentDate = moment();
console.log(currentDate.isValid()); // Check validity
console.log(currentDate.format()); // A valid date
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

Server-Side and Time-Specific script execution

I have a list of dates in an array(for now we can say that the dates are sorted). I want to have a script execute when the date matches a date in the array. My issue is figuring how to make this work on its own. I would like to have a server somehow act like an alarm clock that can run a script for a scheduled date and time. If anyone could help with suggestions to make this work I would appreciate it.
set date >>> if (currentDate == set date) >>> run script for the respective data
Please ask if you need clarification.
The way to do this with parse is a class with a date attribute. Create one object per date in your array of dates (they needn't be sorted).
Create a scheduled job that upon running, query's the class for the first date equal to the current date. If one is found, do whatever you want to do when an alarm is triggered.
So, something like...
Parse.Cloud.job("checkStatus", function(request, status) {
var today = new Date();
today.setHours(0, 0, 0, 0);
var tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
var query = new Parse.Query("MyAlarmClass");
query.greaterThanOrEqualTo('theDateAttribute', today);
query.lessThan('theDateAttribute', tomorrow);
return query.first().then(function(anAlarm) {
if (anAlarm) {
// do whatever should be done on the alarm
} else {
// do nothing
}
}).then(function() {
status.success();
}, function(error) {
status.error(JSON.stringify(error));
});
});
Schedule this to run at least twice per day (or faster than whatever resolution you need on the alarms).

SharePoint/Javascript: comparing calendar date times in javascript

I am trying to find the best approach to comparing date/times using Javascript in order to prevent double booking on a SharePoint calendar. So I load an array with items that contain each event, including their start date/time and end date/time. I want to compare the start date/time and end date/time against the start/end date/times in the object, but I am not sure how to ensure that dates will not lapse.
like:
//date that is created from user controls
var startDate = new Date(startDat + 'T' + startHour + ':' + startMin + ':00');
var endDate = new Date(endDat+ 'T' + endHour+ ':' + endMin+ ':00');
for ( var i = 0; i < allEvents.length; i++ ) {
var thisEvent = allevents[i];
//having trouble with the compare
//i have tried silly ifs like
if (thisEvent.startDate >= startDate && thisEvent.endDate <= endDate) {
// this seems like I am going down the wrong path for sure
}
}
I then tried breaking apart the loaded object into seperate values (int) for each component of the date
var thisObj = { startMonth: returnMonth(startDate), startDay: returnDay(startDate), etc
but I am not sure this isn't just another silly approach and there is another that just makes more sense as I am just learning this.
I have a similar requirement in progress but chose to solve it at the booking stage, with jQuery/SPServices.
The code is still in build (ie not finished) but the method may help.
I attach an event handler to a column, then on selection, fetch all the dates booked in the same list to an array, then display that array on a rolling 12 month cal, as below.
I'm not checking to ensure a new booking doesn't overlap but a quick scan through the array on Pre-Save would provide a strict Go/No Go option for me. Relies on client side JS though, so not going to work in a datasheet or web services context.

Categories

Resources