So I wanted to compare two dates inside a post object. I tried to compare the date objects, but that returned NaN. Then I tried converting it to milliseconds since 1970 by using .now() on these dates, but it returned the following error:
It happens: TypeError: a.date.now is not a function
I tried typeof a.date and this returned string. I don't know why I can't use the .now() method. Can someone help me?
the whole function inside of angular service
getPosts(section) {
return this.http.get(url + '/forum/getPosts/' + section )
.map( (posts: any) => {
// posts should be ordened based on latest replies. If there are no replies yet, we compare it to the date
// of the original post
posts.obj.sort((a, b) => {
const aHasReplies = a.replies.length !== 0;
const bHasReplies = b.replies.length !== 0;
if (aHasReplies && bHasReplies ) {
return a.replies.slice(-1, 1)[0].date - b.replies.slice(-1, 1)[0].date;
} else if ( aHasReplies && !bHasReplies) {
return a.replies.slice(-1, 1)[0].date - b.date;
} else if ( !aHasReplies && bHasReplies) {
return a.date - b.replies.slice(-1, 1)[0].date;
} else {
console.log(a.date.now());
return a.date - b.date;
}
});
return posts;
});
}
It should be object, not string, if that's what you meant, because there is no "date string".
Other than that try:
new Date(a.date).getTime()
Because .now is a static method, you always use it as Date.now()
This means, that Date.now() always returns milliseconds elapsed since the UNIX epoch.
For converting to unix time use getTime.
If you want to compare them, compare two dates without conversion.
But keep in mind, that unix time is in seconds, and javascript method return in milliseconds. If you need exactly unix time, divide by 1000.
You can compare two dates in the year-month-day format (yyyy-mm-dd) using regular javascript comparators such as < and > etc
I suggest use moment.js library (https://momentjs.com/docs/) to parse Date from String.
So you can have some thing like
let date = moment(a.date)
Related
I've got a server instance (NodeJS) that receives a set of objects, and schedules them for sending push notifications to users.
Some of these objects, are periodic, and this periodicity is handled by a string like this:
90=>Mon&Tue&Thu=>16:00
Which is read as:
offset_minutes=>days_of_the_week=>initial_hour
Then, what I do is to check whether the current day matches one of the given days in the string, and then, modify the date to the given hour in the "initial_hour", and finally, substract the "offset_minutes" amount of minutes from the Date object.
Seems straightforward until now, right? Well, not that much. Let's first see the code:
const isToday = weekDays.split("&")
.map(a => {
switch (a) {
case 'Mon': return 1;
case 'Tue': return 2;
case 'Wed': return 3;
case 'Thu': return 4;
case 'Fri': return 5;
case 'Sat': return 6;
case 'Sun': return 7;
}
})
.some(v => v == currentDay);
if (isToday) {
let finalDate = moment(today)
.set("hour", Number(hour))
.set("minute", Number(mins));
if (offset) {
finalDate.subtract('minutes', Number(offset));
}
return finalDate.toDate();
Everything works well, until I do the MomentJS transformations. When I output a Date object with the ".toDate()" method, this object is always set to 2 hours before the expected time. But if I use the .toISOString() method, I get the proper time for all the occurrencies.
I guess that something is wrong with my Date objects, setting them up at a different timezone than the one I have. A couple of examples:
For the string 90=>Mon&Tue&Thu=>16:00 I get the Date object: 2019-10-14T14:00:11.852Z
For the string 30=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30 I get the Date object: 2019-10-14T16:30:11.866Z
I would like to know what's the explanation for such a behavior, and if I can do something to change it so the normal Javascript Date object points to the same hour than my momentjs object, or the .toISOString() output.
Thank you!
The posted code is incomplete and doesn't demonstrate the issue described.
I've reimplemented the code without moment.js as best I can and simplified it. It seems to work fine:
function parseThing(s) {
// Parse input string
let b = s.split('=>');
let offset = +b[0];
let days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
let weekDays = b[1].split('&').map(day => days.indexOf(day));
let [hr, min] = b[2].split(':');
// Get a date for today
let date = new Date();
// If today included, return an adjusted date
if (weekDays.includes(date.getDay())) {
date.setHours(hr, min, 0, 0);
if (offset) {
date.setMinutes(date.getMinutes()+ Number(offset));
}
return date;
}
// If today isn't included, return null
return null;
}
let s0 = '90=>Mon&Tue&Thu=>16:00';
let s1 = '0=>Mon&Tue&Wed&Thu&Fri&Sat&Sun=>18:30';
console.log(parseThing(s0).toString());
console.log(parseThing(s1).toString());
Where the local day is one of those in the string (Mon, Tue, Thu) it returns a Date equivalent to a local time of 17:30, which is 90 minutes offset from 16:00, which seems to be correct.
PS I've changed Sunday to 0 as I can't see any rationale for it to be 7. Also seconds and milliseconds are zeroed too.
I have an array which contains a set of start/end date objects (time included)
i.e.
results["records"] =
[0] -[startDate,endDate]
[1] -[startDate, endDate]
I also have another two date objects stored locally as JS variables.
How do I check if these variables i.e. startDateObj && endDateObj OVERLAP with ANY record in the array, by that I mean crossover with any time between and including any start date or end date.
Thank you in advance
Initial attempt below
$(results['records']).each(function() {
console.log('end:' + this[1])
console.log('start:' + this[0])
if(startDateObj < this[1].end && endDateObj > this[0].start) {
alert('this overlaps')
}
});
EDIT: Answer added below
Have a great day!
I'm assuming this structure in your "dateArray" because to check overlaps you need to define a range of date and time.
dateArray: [{start: Date, end: Date}];
dateArray.forEach(date => {
if(startDateObj < date.end && endDateObj > date.start) {
//this is an overlap
}
});
The answer was the full date objects in the array where being treated as a string
so to convert and fix
function toDateString(date)
{
var formatedDate = new Date(date);
return formatedDate;
}
$(results['records']).each(function() {
if(startDateObj < toDateString(this[1]) && endDateObj > toDateString(this[0]))
{
//overlaps
}
In my node script I have the following function, which determines max date:
if (result.rows.length > 0) {
var maxDate = new Date(
result.rows.map(o => o.REPORTED_DATE).reduce(function(a, b) {
return Math.max(a, Date.parse(b));
})
);
}
The REPORTED_DATE used to be a date, but now it changed to the unix epoch, which is a 10-digit number.
What is the proper syntax to determine max number instead of the date?
If REPORTED_DATE is now a number then you should be able to simply remove the Date.parse() call within your existing .reduce() function:
return Math.max(a, b);
However, given that Math.max() can handle any number of arguments you don't need to use .reduce(), you can instead just use .apply() to pass Math.max() the array of numbers that you're producing with .map():
Math.max.apply(null, result.rows.map(o => o.REPORTED_DATE))
If the REPORTED_DATE is a Unix-style 10-digit number then that is number of seconds, so you'd need to multiple it by 1000 to get milliseconds for conversion to a JavaScript Date object. So putting that together in context:
if (result.rows.length > 0) {
var maxDate = new Date(
Math.max.apply(null, result.rows.map(o => o.REPORTED_DATE)) * 1000
);
}
Would this code work if both the timestamps are in mysql 2013-03-21 18:16:50 format?
$.get('current.php', { lastTime: time, current: true, Cla: Class }, function(html) {
var Date1 = Date.parse($(html).find("#timestamp").val());
var Date2 = Date.parse($("#timestamp").val());
if (Date.parse(Date1) < Date.parse(Date2)) {$(html).find("#timestamp").remove();}else {$("#timestamp").remove();}
}
I think you want something like this:
$.get('current.php', { lastTime: time, current: true, Cla: Class }, function(html) {
var $dateInput1 = $(html).find('#timestamp'),
$dateInput2 = $("#timestamp");
if ($dateInput1.val() < $dateInput1.val()) {
$dateInput1.remove();
} else {
$dateInput2.remove();
}
// ... add $html somewhere to the DOM ...
});
Since your dates are already in a format that is comparable lexically, it doesn't require using Date.parse() at all. Also, you'd only be creating one jQuery object per element, so it's more efficient in that way, too.
Date.parse return time in milliseconds which you can use it for comparison.
if (Date1 < Date2) {
$(html).find("#timestamp").remove();
}else {
$("#timestamp").remove();
}
You are calling Date.parse twice on the values, and Date.parse does not accept the milliseconds number returned by the previous invocation as a valid date.
if (Date1 < Date2)
is enough to compare them. Notice that if either of them could not be parsed, you will be comparing to NaN.
Is there a way to take a date object from a HTML object in the format of ####-##-## and convert it to epoch time. For example, the user inputs the value of August 12, 2012 which shows as 2012-08-12 when I print out the .val() of it, and I need to get this in Epoch time.
EDIT
Code to date:
if (hvStartDate == "") {
hvStartDate = "start"
}
else {
console.log($("#hv-start-date").val()); // => 2012-08-20
hvStartDate = new Date($("#hv-start-date").val()).getTime(); // => NaN
}
if (hvEndDate == "") {
hvEndDate = "end"
}
else {
hvEndDate = new Date($("#hv-end-date").val()).getTime(); // => NaN
}
var myTmp = new Date("2012-08-20");
console.log(myTmp.getTime()); // => NaN
Javascript's Date built-in allows you to pass a date string into its constructor, giving you a Date based on that string. From there, calling getTime( ) will give you the epoch time.
new Date($('.user-value').val()).getTime(); // => epoch time
new Date('2012-08-12').getTime(); // 1344729600000
Caveat: Beware of locale strings and locale-specific date formatting (for example, the position of days and months switch depending on locale).
EDIT: Based on your code in the comment below, here's what you need to do. Notice that you have to instantiate a new Date Object before calling getTime():
if (hvStartDate == "") {
hvStartDate = "start"
}
else {
hvStartDate = new Date($("#hv-start-date").val()).getTime();
}
Simply use the getTime() function. It returns the number of milliseconds since Epoch :
var msSinceEpoch = myDate.getTime();
Complete Date reference at MDN : https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date
EDIT : if you have to parse it too, you may :
use new Date(theString) if it has the good format
set yourself the different date fields (see reference) after having parsed it
use a date parsing library. I use this one : http://www.datejs.com/ which is very powerful for all date parsing, computing and formating.