I have an application in which I use a couple of date/time manipulation function to populate a couple of calendars. Basically, a user selects a month/year from a dropdown (say, March 2019) and I populate the calendars with 03/01/2019 and 03/31/2019.
I wanted to do this client side so tried to convert those function to javascript and I am getting strange results and can't see what I am doing wrong.
This is the original C# functions I defined and used:
public static DateTime FirstDayOfMonth(this DateTime dt)
{
return new DateTime(dt.Year, dt.Month, 1);
}
public static DateTime LastDayOfMonth(this DateTime dt)
{
DateTime dtFirstDayOfMonth = new DateTime(dt.Year, dt.Month, 1);
DateTime dtLastDayOfMonth = dtFirstDayOfMonth.AddMonths(1).AddDays(-1);
return dtLastDayOfMonth;
}
I called these like below:
DateTime dtSelected = DateTime.Today.AddMonths(int.Parse(ddlMonth.SelectedValue)).AddYears(-1);
dtStartDate = Utils.FirstDayOfMonth(dtSelected);
dtEndDate = Utils.LastDayOfMonth(dtSelected);
The dropdown list is populated like:
for (int i = 12; i >= 1; i--)
{
string s = DateTime.Now.AddYears(-1).AddMonths(i).ToString("Y");
ListItem li = new ListItem(s, i.ToString());
ddlMonth.Items.Add(li);
}
The dropdown entries would look like:
May, 2019 -- value of 12
April, 2019 -- value of 11
....
July, 2018 -- value of 2
June, 2018 -- value of 1
This is my attempt at translating to javacript:
function firstDayOfMonth(dt) {debugger
var year = dt.getFullYear();
var month = dt.getMonth();
var day = dt.getDate();
return new Date(year, month, 1);
}
function lastDayOfMonth(dt) {debugger
var year = dt.getFullYear();
var month = dt.getMonth();
var day = dt.getDate();
var firstDayOfMonth = new Date(year, month, 1);
var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1); --> shows error when called; Object doesn't support property or method 'AddMonths'
return lastDayOfMonth;
}
$(document).on('change', '#ddlMonth', function () {debugger
var monthID = this.value;
var ddlMonth = $('#ddlMonth');
var today = new Date();
var startDate = new Date();
var endDate = new Date();
var dtSelected = new Date();
if (ddlMonth.val() == "")
{
....
}
else
{debugger
dtSelected.setMonth(dtSelected.getMonth() + ddlMonth.val() + 1); -- this becomes "Wed Oct 12, 2360" if I select "March, 2019" from dropdown!
dtSelected.setFullYear(dtSelected.getFullYear() - 1);
dtStartDate = firstDayOfMonth(dtSelected);
dtEndDate = lastDayOfMonth(dtSelected);
}
you have some problem in your code, this for example:
dtSelected.setMonth(dtSelected.getMonth() + ddlMonth.val() + 1); -- this becomes August of 2036!
you take today's month which is the 5 then add to itsome value from your slect and add 1 more and this is a lot of monthes to add.
I think you need to changesome things and do this like this:
change the select values to be the date of the first day of each month and not just number:
for (int i = 12; i >= 1; i--)
{
DateTime date = DateTime.Now.AddYears(-1).AddMonths(i);
ListItem li = new ListItem(date.ToString("Y"), date.ToString("yyyy-MM-01"));
ddlMonth.Items.Add(li);
}
in this format you can use it on js with no problem.
now for your js function:
function lastDayOfMonth(dt) {debugger
var year = dt.getFullYear();
var month = dt.getMonth();
var day = dt.getDate();
var lastDayOfMonth = new Date(year, month, 1);
lastDayOfMonth.setMonth(lastDayOfMonth.getMonth() + 1);
lastDayOfMonth.setDate(lastDayOfMonth.getDate() - 1);
return lastDayOfMonth;
}
$(document).on('change', '#ddlMonth', function () {debugger
var ddlMonth = $('#ddlMonth');
dtStartDate = new Date(ddlMonth.val());
dtEndDate = lastDayOfMonth(dtStartDate);
}
Related
It's possible to do this to get the localized full month name using native javascript.
var objDate = new Date("10/11/2009"),
locale = "en-us",
month = objDate.toLocaleString(locale, { month: "long" });
But this only gets the month number for a given date. I'd simply like to get the month name corresponding to a month number. For example, if I do getMonth(2) it would return February. How can I implement getMonth using native javascript(no libraries like moment)?
You are already close:
var getMonth = function(idx) {
var objDate = new Date();
objDate.setDate(1);
objDate.setMonth(idx-1);
var locale = "en-us",
month = objDate.toLocaleString(locale, { month: "long" });
return month;
}
console.log(getMonth(1));
console.log(getMonth(12));
To get all the months of a year and days of the week, loop over a set of dates and use toLocaleString with appropriate options to get the required values:
function getLocalDayNames() {
let d = new Date(2000,0,3); // Monday
let days = [];
for (let i=0; i<7; i++) {
days.push(d.toLocaleString('default',{weekday:'long'}));
d.setDate(d.getDate() + 1);
}
return days;
}
console.log(getLocalDayNames());
function getLocalMonthNames() {
let d = new Date(2000,0); // January
let months = [];
for (let i=0; i<12; i++) {
months.push(d.toLocaleString('default',{month:'long'}));
d.setMonth(i + 1);
}
return months;
}
console.log(getLocalMonthNames());
The language default means toLocaleString uses the default language of the implementation that the code is running in.
Before I am using angularjs-DatePicker from this npm.
Here,I am able to select the date from the date picker.But now I have to fields as FromDate and ToDate which means the week StartDate and EndDate should show when any date pick in that week.
Ex: Like in Calender 01-08-2017 Start on Tue, So whenever Selects Any date from 01 to 05 then the two fields should show as FromDate as 01 and TODate as 06 and in the same whenever the user selects the 31-07-2017 the the Two fields should show as 30 and 31 of july.
I have an idea to achieve the ToDate from FromDate Calender control onchange event in DotNet as like below mentioned code
Convert.ToDouble(objstart.DayOfWeek)).ToString("dd-MM-yyyy")
But how to achieve this usecase in the angularjs.
Thanks
Ok, so what I'd do is to calculate different dates, and take the min/max depending on the start or end of the week.
Here:
//Use the date received, UTC to prevent timezone making dates shift
var pickedDate = new Date("08-03-2017UTC");
var startSunday = new Date(pickedDate);
startSunday.setDate(pickedDate.getDate() - pickedDate.getDay());
var startMonth = new Date(pickedDate);
startMonth.setDate(1);
var startDate = Math.max(startMonth,startSunday);
console.log("Start:" , new Date(startDate));
var endSaturday = new Date(pickedDate);
endSaturday.setDate(pickedDate.getDate() + (7-pickedDate.getDay()));
var endMonth = new Date(pickedDate);
endMonth.setMonth(pickedDate.getMonth()+1);//Add a month
endMonth.setDate(0);// to select last day of previous month.
var endDate = Math.min(endMonth,endSaturday);
console.log("End" , new Date(endDate));
The trick was to play with the dates, find all the possible start and end dates, then choose the right one with Math.min and Math.max which will compare the dates using their timestamp.
There is very good Library available in JavaScript to handle Date Manipulations.
https://github.com/datejs/Datejs
There is a method
Date.parse('next friday') // Returns the date of the next Friday.
Date.parse('last monday')
Using these method you can get the start and ending date of the week based on the current week.
I hope that it will help.
You can simply achieve this using the library moment. There are a lot of useful functions in this library.
var selectedDate = moment('Mon Aug 10 2017');
//If you want to get the ISO week format(Monday to Sunday)
var weekStart = selectedDate.clone().startOf('isoweek').format('MMM Do');
var weekEnd = selectedDate.clone().endOf('isoweek').format('MMM Do');
//If you want to get the Sunday to Saturday week format
var weekStart = selectedDate.clone().startOf('week').format('MMM Do');
var weekEnd = selectedDate.clone().endOf('week').format('MMM Do');
No need angular directive here, you could use the JavaScript extension which is below.
//get week from date
Date.prototype.getWeekNumber = function (weekstart) {
var target = new Date(this.valueOf());
// Set default for weekstart and clamp to useful range
if (weekstart === undefined) weekstart = 1;
weekstart %= 7;
// Replaced offset of (6) with (7 - weekstart)
var dayNr = (this.getDay() + 7 - weekstart) % 7;
target.setDate(target.getDate() - dayNr + 0);//0 means friday
var firstDay = target.valueOf();
target.setMonth(0, 1);
if (target.getDay() !== 4) {
target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
}
return 1 + Math.ceil((firstDay - target) / 604800000);;
};
//get date rance of week
Date.prototype.getDateRangeOfWeek = function (weekNo, weekstart) {
var d1 = this;
var firstDayOfWeek = eval(d1.getDay() - weekstart);
d1.setDate(d1.getDate() - firstDayOfWeek);
var weekNoToday = d1.getWeekNumber(weekstart);
var weeksInTheFuture = eval(weekNo - weekNoToday);
var date1 = angular.copy(d1);
date1.setDate(date1.getDate() + eval(7 * weeksInTheFuture));
if (d1.getFullYear() === date1.getFullYear()) {
d1.setDate(d1.getDate() + eval(7 * weeksInTheFuture));
}
var rangeIsFrom = eval(d1.getMonth() + 1) + "/" + d1.getDate() + "/" + d1.getFullYear();
d1.setDate(d1.getDate() + 6);
var rangeIsTo = eval(d1.getMonth() + 1) + "/" + d1.getDate() + "/" + d1.getFullYear();
return { startDate: rangeIsFrom, endDate: rangeIsTo }
};
Your code can be look like this
var startdate = '01-08-2017'
var weekList = [];
var year = startdate.getFullYear();
var onejan = new Date(year, 0, 1);//first january is the first week of the year
var weekstart = onejan.getDay();
weekNumber = startdate.getWeekNumber(weekstart);
//generate week number
var wkNumber = weekNumber;
var weekDateRange = onejan.getDateRangeOfWeek(wkNumber, weekstart);
var wk = {
value: wkNumber
, text: 'Week' + wkNumber.toString()
, weekStartDate: new Date(weekDateRange.startDate)
, weekEndDate: new Date(weekDateRange.endDate)
};
weekList.push(wk);
I guess there is no directive or filter for this, you need to create one for yourself. you can refer date object from date-time-object
I've a variable that has value of date in YYYYMM format. For example:
var givenDate = "201704"
How can I find out the last day of the given month and append to it. For example,
//last day of 2017 04 (April) is 30th so append value to givenDate + lastDate;
//that will be 20170430
var newFullGivenDate = "20170430";
const date = "201704";
const year = parseInt(date.substring(0, 4));
const month= parseInt(date.substring(4, 6));
const lastDay = (new Date(year, month, 0)).getUTCDate();
const newFullGivenDate = date + lastDay;
console.log(newFullGivenDate);
var givenDate = "201704";
var month = givenDate.substring(4, givenDate.length); // retrieves 04
var year = givenDate.substring(0, 4); // retrieves 2017
var d = new Date(year, month, 0);
alert(d.getDate());
Reference: MDN
To achieve expected result, use below option
last day of month - new Date(year,month ,0)
var givenDate = "201704";
var currDate = new Date(givenDate.substr(0,3),givenDate.substr(4) ,0)
var newFullGivenDate = givenDate + currDate.getDate();
console.log(newFullGivenDate)
Codepen URL for reference - https://codepen.io/nagasai/pen/OmgZMW
I would break it down into two functions:
// Get last day from year and month
let lastDayOf = (year, month) => (new Date(year, month, 0)).getDate();
// Add last day to string only if input is correct
let addLastDay = (input) => {
// In case you pass number (201705) instead of string ("201705")
if (Number.isInteger(input)) input = input.toString();
// Check if input is in correct format - 6 digit string
if (typeof input !== "string" || !input.match(/^\d{6}$/)) {
return input; // You can implement desired behavour here. I just return what came
}
const year = input.substr(0, 4);
const month = input.substr(4, 2);
return input + lastDayOf(year, month);
}
// Tests
console.assert(addLastDay("201704"), "20170430");
console.assert(addLastDay("201702"), "20170228");
console.assert(addLastDay("201202"), "20120229");
console.assert(addLastDay(201705), "20170531");
console.assert(addLastDay(20170), 20170); // Wrong input
// Interactive example
document.getElementsByTagName('button')[0].addEventListener('click', () => {
let input = document.getElementsByTagName('input')[0];
input.value = addLastDay(input.value);
});
<input type="text" value="201704"><button>Calculate</button>
If you are using moment js you can yry this:
var date = moment(newFullGivenDate ).format('YYYYMMDD');
date = date.add(-1 * parseInt(date.format('DD')), 'days').add(1, 'months');
I am using moment js to get the date five days into the future with this code
//current date
var cd = moment().format("DD-MM-YYYY");
//5 days into the future
var nd = moment(cd, "DD-MM-YYYY").add(5, 'days').format('DD-MM-YYYY');
//get all dates from today to 5 days into the future
and now i am attempting to get an array of days between current date and the future date which is five days later
//current date
var cd = moment().format("DD-MM-YYYY");
//5 days into the future
var nd = moment(cd, "DD-MM-YYYY").add(5, 'days').format('DD-MM-YYYY');
//get all dates from today to 5 days into the future
console.log("start",cd);
console.log("end",nd);
var getDates = function(startDate, endDate) {
var dates = [],
currentDate = startDate,
addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
while (currentDate <= endDate) {
dates.push(currentDate);
currentDate = addDays.call(currentDate, 1);
}
return dates;
};
// Usage
var dates = getDates(cd, nd);
dates.forEach(function(date) {
console.log(date);
});
This is the demo https://jsfiddle.net/codebreaker87/z9d5Lusv/67/
The code only generates the current date. How can i generate an array of all dates between?.
If you are using momentjs already, then you seem to be doubling its functinality by your own code.
Consider the following snip:
var getDates = function( cd, nd ){
var dates = [];
var now = cd.clone();
for(var i = 0; i < nd.diff(cd, 'days') ; i++){
// format the date to any needed output format here
dates.push(now.add(i, 'days').format("DD-MM-YYYY"));
}
return dates;
}
var r = getDates( moment(), moment().add(10, 'days'));
// r now contains
["04-11-2016", "05-11-2016", "07-11-2016", "10-11-2016", "14-11-2016", "19-11-2016", "25-11-2016", "02-12-2016", "10-12-2016", "19-12-2016"]
I managed to solve it like this
//current date
var cd = moment().format("YYYY-MM-DD");
//5 days into the future
var nd = moment(cd, "YYYY-MM-DD").add(5, 'days').format('YYYY-MM-DD');
//get all dates from today to 5 days into the future
var getDates = function(startDate, endDate) {
var dates = [],
currentDate = startDate,
addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
while (currentDate <= endDate) {
dates.push(currentDate);
currentDate = addDays.call(currentDate, 1);
}
return dates;
};
var dates = getDates(new Date(cd), new Date(nd));
dates.forEach(function(date) {
//format the date
var ald = moment(date).format("YYYY-MM-DD");
console.log(ald);
console.log(date);
});
I need something obvious pointing out to me in regard to JS functions.
The following code works, but I want to call upon it anywhere:
var pattern = /(\d{2})\-(\d{2})\-(\d{4})/;
var date = entry.date.split(' ');
var date = date[0];
var date = new Date(date.replace(pattern,'$3-$2-$1'));
var year = date.getYear();
var month = date.getMonth();
var day = date.getDay();
What would be the best practice to place this in a global function so I can just do adjustDate(string). Double points (Sadly, not in my power) to explain how I would then also have access to all the objects such as year, month, day.
Thanks in advance!
Can't you just declare the function?
function adjustDate(entry) {
var date = entry.date.split(' ');
date = date[0];
date = new Date(date.replace(/(\d{2})\-(\d{2})\-(\d{4})/, '$3-$2-$1'));
return {
year: date.getYear(),
month: date.getMonth(),
day: date.getDay()
};
}
I would just return a date without abstracting its existing methods
function AdjustedDate(dateString)
{
return new Date(dateString.split(' ')[0].replace(/(\d{2})\-(\d{2})\-(\d{4})/, '$3-$2-$1'));
}
var ad = AdjustedDate(entry.date);
alert(ad);
alert(ad.getDay());
Pass the entry into the function and then pass an object containing the information you want out. Then just access it like you would an ordinary JS object.
function adjustDate(entry) {
var pattern = /(\d{2})\-(\d{2})\-(\d{4})/;
var date = entry.date.split(' ');
var date = date[0];
var date = new Date(date.replace(pattern,'$3-$2-$1'));
var year = date.getYear();
var month = date.getMonth();
var day = date.getDay();
return { day: day, month: month, year: year }
}
var dateObject = adjustDate(/*entry*/)
dateObject.day // day
dateObject.month // month