Apply class to a column after date comparison in AngularJS + JavaScript - javascript

Following is the type of date I am getting from db - 2015-07-15T18:30:00.000Z . Now I am trying to add bootstap class btn-info if this date is 1 year before current date (Date.now()), if its less than or equals to 1 year but less than 3 months from current date then add class btn-warning, for 3 months or less add class btn-danger.
For this I am using ng-class on my field, like -
ng-class="calDateDiff(exp_date)"
In calDateDiff() method, I am trying to do the conversion, but unable to know which type of date format its represents.
I checked UTC in Js but its not that, also I tried Date.parse(Date.now()) but unable to know the format.
$scope.calDatediff = function(exp_date) {
// exp_date - Date.now()
// Here in calculation I am also not sure
// to handle leap years
}
Please let me know what type of date format is this and what is the right approach to handle this.
FYI- I don't want to use Moment.js as this is to be applied for only one column field, so it will be overhead just for one column to show.
EDIT 1 -
Ok I got this as its an ISO string -
so for current date I believe its going to be -
current date - new Date().toISOString()
let me know how I cam going to compare these two strings for an year, or 3 month condition ?

You can create a new date object and subtract.
Date.now() - new Date('2015-07-15T18:30:00.000Z')
1557113984
if you want to know if a year has elapsed one way to do it is to increment the date you got from the database and see if it is less than the current date:
var dbDate = new Date('2015-07-15T18:30:00.000Z');
dbDate
Wed Jul 15 2015 11:30:00 GMT-0700 (PDT)
dbDate.setMonth(dbDate.getMonth() + 12);
1468607400000
dbDate
Fri Jul 15 2016 11:30:00 GMT-0700 (PDT)
dbDate < Date.now()
false

That seems to me like an ISOString date. All you need to do is create a new object of type Date by passing that string to the constructor:
var dbDate = new Date("2015-07-15T18:30:00.000Z");
This will give you a Date object with which you can work with and easily compare it to Date.now(); I think you can do the rest of it by yourself.
Here's more info about Date: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date

Related

How can I convert GTM-0006 to ISO without Adding hours

I'm working in a from who has a date field and by default it shows the current date.
I set the date using this:
var date = new Date(); = Tue May 25 2021 17:06:01 GMT-0600 (Mountain Daylight Time) {}**
Everything works fine, but when I send the data to the controller, the JSON automatically converts it to ISO and the date received by the controller is 6 hours in advance.
I understand a little bit the context about GMT-0006 (my current timezone is 6 hours more than the 0 timezone), and the fact that my controllers received the date in ISO format because when I converted to ISO format is the same problem
date.toISOString() = "2021-05-25T23:06:01.861Z" (6 hours in advance)
so my question is, there is a way to create a date that allows me to use .toISOString() and keep the same?
or create a date with my current hour but -0000 so when I convert it to toISOString keeps the same?

DatePicker Error in Angular JS due to UTC

I have selected the 12th of September 2014 in the UI.
Following is the code
ctrl.$formatters.push(function (modelValue) {
console.log(modelValue);
var dt = new Date(modelValue);
dt.setMinutes(dt.getMinutes() + dt.getTimezoneOffset());
console.log(dt)
return dt;
});
The two console logs i see are the following.
09/11/2014
Wed Sep 10 2014 18:30:00 GMT+0530 (IST)
Am not sure why the conversion from UTC to local is not carried out correctly.
Thanks in advance.
Its not clear what you are trying to do. The input does not have a time. Do you want to add the current time of the day to the arbitrary date? Or do you just want a local representation of the date? I'm geussing the latter.
Instead of dt.setMinutes(...) and the following two lines, replace all three lines with:
return dt.toLocaleDateString();
If you ARE trying to set the time to now on whatever date is input (I don't know why...) but you might try:
dt.setTime( new Date().getTime() );
instead of the setMinutes(...) line.
then you can
return dt.toLocaleString;
All date objects are stored as miliseconds since, like 1972. It is best to use the built in Date object methods to get what you want from it. Here are the docs for reference.

format just a time for use with ui-bootstrap timepicker

I have a server returning a time value like so
14:00
The reason for this is it represents the start time of say a task that happens repetively say every monday at 14:00 so the date is irrelevant. I want to display this value to the user when they are editing the task so that they can change it with ui-bootstraps timepicker.
The timepicker requires either an epoch, an rfc2822 or ISO 8601 date so I need to just add a random date that I can discard later for the timepicker to be able parse and display the value (which seems ridiculous seen as it is a time picker not a time on a specific day picker but whatever)
so either using the javascript date object or moment.js how can I take that value and create a valid date object with it?
As you requested a moment.js solution also:
var date = moment("14:00", "HH:mm").toDate();
// assume returned is the hours and minutes you get in this format: 14:00
hourData = returned.split(':');
var date = new Date();
date.setHours(hourData[0]);
date.setMinutes(hourData[1]);
date will be something like Sat Jul 12 2014 14:00:13 GMT+0300 (EEST)

manipulating javascript date object

I know with a java calendar, you can go back to a previous date, but how do I do that with a javascript date? Lets say I want to go backwards three months, how do I do that? I'm assuming that there has to be some logic to do that, and not just do a setMonth(), since rolling back 3 months may take you back to the previous year, and so the year needs to be updated too.
Why don't you use one of the date libraries such as date.js
http://datejs.com
Date.add(-3).month();
Any rollover date manipulation to a new period (ie new year, month, week, day, etc) is handled automatically
var d = new Date();
-> Tue Oct 01 2013 14:12:21 GMT+1000 (EST)
d.setMonth(d.getMonth() - 3);
-> Mon Jul 01 2013 14:13:43 GMT+1000 (EST)
d.setMonth(d.getMonth() - 10);
-> Sat Sep 01 2012 14:14:31 GMT+1000 (EST)
Using get month you can get the value from 0-11,so if you want to go back to 3 months just chekc if month no. is greater than 3 ,if it is greater than 3 no need to change the year,else decrement the year by 1
MomentJS is a JavaScript library that is great for date manipulation. Using MomentJS, you could do something like:
// Subtract 3 months from the current moment (now)
moment().subtract('months', 3);
If you must use the JavaScript Date object, you can use the setMonth() but it can be unreliable (as you mentioned). As an example:
// Get the next and previous month from now (first day of the month)
var now = new Date();
var futureMonth = now.setMonth(now.getMonth() + 1, 1);
var pastMonth = now.setMonth(now.getMonth() - 1, 1);
Note that you need to specify the second parameter to set the day to 1. This will prevent the "next" month from skipping a month (e.g. adding a month to January 31, 2014 will result in March 3rd, 2014 if you omit the second parameter).
No, you don't need to worry about roll backing the year. Just set the month and remaining it with JS rendering machine.
var date = new Date();
date.setMonth(-10); //+ increase the month or - decrease
alert(date);
JSFiddle

Unable to validate double digit month using Javascript

I have an HTML form where I am allowing users to enter a date to print out a report. However, if that date is within 3 days of the current date, I have it set to tell the user that they must wait 3 days. For some reason the code works when I enter something like "09/30/2012" but when I enter "10/01/2012", the error check skips. It seems at though, if it's a double digit month (10, 11, and 12), it complete skips the error check. Please let me know if you have any ideas. Thanks
JS Code:
var date = myForm.SC_date.value;
var d = new Date(date);
var varBegin = (d.getMonth()+1) + "-" + (d.getDate()-3) + "-" + d.getFullYear()
re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
if (myForm.SC_date.value == "")
window.alert("Please enter the requested date of variance. NOTE: Date must be 3 days prior to today's date.")
//Here is where I am having issues
/*else if(new Date(date) > new Date(varBegin))
window.alert("Invalid date. You must wait at least 3 days before you can request a report.")*/
else if(!myForm.SC_date.value.match(re))
window.alert("Invalid date. Please enter the date as follows: mm/dd/yyyy.")
HTML Code:
<td>Date of Variance </td>
<td colspan="2"><input name="SC_date:*" id="SC_date" type="text" tabindex="06">
</textarea><b><span class="style3">*</span> </b><span class="style2">(mm/dd/yyyy)</span>
</td>
I don't think you want to construct your "3 days ago" date by manipulating a string. I.e., this snippet here:
var varBegin = (d.getMonth()+1) + "-" + (d.getDate()-3) + "-" + d.getFullYear()
First, I'm not sure why you're using hyphens as delimiters here, when you are using forward-slashes as delimiters in your input field?
In any case, that's not a reliable way to construct the date. When you feed a string into the constructor of a Date object, you are effectively calling Date.parse(). That behaves differently on different browsers.
Check this out:
> new Date('1-1-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('01-01-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('2012-1-1');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
Looks pretty good, right? But that's on Chrome.
Now check out what happens in an up-to-date version of Firefox, with the exact same calls:
> new Date('1-1-2012');
Date {Invalid Date}
> new Date('01-01-2012');
Date {Invalid Date}
> new Date('2012-1-1');
Date {Invalid Date}
> new Date('2012-01-01');
Date {Sat Dec 31 2011 16:00:00 GMT-0800 (PST)}
Furthermore, look at this behavior, in both browsers:
> new Date('2012-01-01');
Sat Dec 31 2011 16:00:00 GMT-0800 (PST)
Simply prepending zeroes to the month and date digits causes a time warp! You have to set the time and a timezone (for me, PST) to make that go away:
> new Date('2012-01-01T00:00:00-08:00')
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
Basically, dealing with date string parsing is a headache. You don't want to have to digest and account for specs like this, this, and this.
So, here's a better alternative -- pass the year, month, and date values (in that order) to the constructor of the Date object. That will reliably create the date for you, so your comparisons are valid.
Like this, for your specific example:
var WARNING_PERIOD_IN_DAYS = 3;
// Extract month, day, year from form input, 'trimming' whitespace.
var re = /^\s*(\d{1,2})\/(\d{1,2})\/(\d{4})\s*$/;
var match = re.exec(inputVal); // from "myForm.SC_date.value".
if (match) {
var month = parseInt(match[1]) - 1; // Zero-indexed months.
var date = parseInt(match[2]);
var year = parseInt(match[3]);
var inputDate = new Date(year, month, date);
var currentDate = new Date();
var threeDaysAgo = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDay() - WARNING_PERIOD_IN_DAYS);
console.log((inputDate > threeDaysAgo) ? 'Within warning period' : 'No warning needed');
}
Speaking of specs, there's one cool thing to note here, which is that in JavaScript, you can "wrap" the date value (it can be too large, or negative), and the resulting Date will still be valid and correct. Here's why:
From the ECMAScript 262 spec, here's what happens when you call setDate():
**15.9.5.36 Date.prototype.setDate (date)**
1. Let t be the result of LocalTime(this time value).
2. Let dt be ToNumber(date).
3. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
4. Let u be TimeClip(UTC(newDate)).
5. Set the [[PrimitiveValue]] internal property of this Date object to u.
6. Return u.
This is the key bit: MakeDay(YearFromTime(t), MonthFromTime(t), dt)
MakeDay gets the year and the month from the current time value of the Date object (in milliseconds of epoch time), and does this:
**15.9.1.12 MakeDay (year, month, date)**
The operator MakeDay calculates a number of days from its three arguments, which must be ECMAScript Number values. This operator functions as follows:
1. If year is not finite or month is not finite or date is not finite, return NaN.
2. Let y be ToInteger(year).
3. Let m be ToInteger(month).
4. Let dt be ToInteger(date).
5. Let ym be y + floor(m /12).
6. Let mn be m modulo 12.
7. Find a value t such that YearFromTime(t) == ym and MonthFromTime(t) == mn and DateFromTime(t) == 1;
but if this is not possible (because some argument is out of range), return NaN.
8. Return Day(t) + dt - 1.
This looks rather involved, but basically it's:
The floor, modulo, and date==1 bits handle month rollovers (months that are negative or greater than 12).
The resulting instant in epoch time is converted to a number of days.
Your date value is added to that number of days. If your date value is negative, that's fine, it will just be subtracted.
The result is passed back to setDate().
setDate calls MakeDate(), which converts the number of days plus the intra-day time into milliseconds in epoch time.
The Date object's internal time is set to this new epoch time.
That's why you can do stuff like this (comments taken from the MakeDay() function in the V8 JS engine project):
// MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
// MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
// MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
Ok, so that was almost certainly too much detail for this particular problem... but I just wanted to make clear what's really going on behind the scenes. Thanks for your patience.
And... just one last thing...
You have a random </textarea> hanging out in that HTML snippet. If there is an opening <textarea> somewhere before it, then it's incorrectly enclosing some of your other elements. If there is no opening <textarea>, then delete it.
If you don't care about the time of the day, I recommend you do the following:
var dUser = new Date(date); //just like you did before
var dVarBegin = new Date("10/05/2012"); //here you do whatever is the date you are setting.
var diff = dVarBegin.getTime() - dUser.getTime();
//now diff is the difference in milliseconds!
I don't fully understand your requirements in relation to the 3 days. However, if what you needed was to compare dates, now you can! I hope this works for you. If you need something more, please ellaborate a little bit on the 3 days thing.
Use a library that lets you control the date formats accepted, e.g. Globalize.js or Date.js. Then define the exact test you wish to carry out especially whether time of the day is significant and whether the test should be relative to current time in user’s system (which is what you get with new Date() without arguments). You can then e.g. calculate a time difference as outlined by #Mamsaac and convert milliseconds to days with simple arithmetic.
It is illogical to use Date() and then, without checking the result, start doing pattern matching on the input. Moreover, Date() is by definition system-dependent and should seldom be used. There is no guarantee that it will accept a format like mm/dd/yyyy at all.

Categories