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');
Related
I have a model in my database that contains an array called "AvailableDays" [0...6]. 0 = Sunday & 6 = Saturday. I am looking to convert this day number of the week to the date of day in the current week.
For example, this is the logic broken down
Retrieve the list of available days (const availableDays = [0,2,4,6])
Get the current DATE (const today = new Date('2021-08-20');)
Covert day numbers to dates (output =['15-08-2021', '17-08-2021', '19-08-2021', '21-08-2021'])
What you can do is get the day-of-the-week from the given Date instance and work out the offset from your available day.
Then subtract that offset in days from the given date to produce your result.
const transformDate = (date, day) => {
const offset = date.getDay() - day
const d = new Date(date)
d.setDate(d.getDate() - offset)
return d
}
const availableDays = [0,2,4,6]
const today = new Date("2021-08-20")
console.log(availableDays.map(day => transformDate(today, day)))
Was able to solve this myself. I am now able to wrap this into a availableDates.map() and return an array of dates using the below logic.
var availableDay = 0
var d = new Date(),
day = d.getDay(), // 0 ... 6
calcAvailableDay = day-availableDay,
diff = d.getDate() - calcAvailableDay,
output = new Date(d.setDate(diff));
console.log(output)
You can generate all the days in weeks and then get the dates using availableDays.
const getWeekDays = (current) => {
current.setDate((current.getDate() - current.getDay() - 1));
return Array.from({ length: 7 }, (_, i) => {
current.setDate(current.getDate() + 1)
return new Date(current).toLocaleDateString('en-CA');
});
},
today = new Date('2021-08-20'),
weekDays = getWeekDays(today),
availableDays = [0, 2, 4, 6],
availableDates = availableDays.map(day => weekDays[day]);
console.log(availableDates);
JavaScript getDay method returns the day of the week for the specified date according to local time, where 0 represents Sunday.
So what you have to do is connect this index with your availableDays values.
Logic
Get current date, month, year and the index of todays date.
Loop through the availableDays array, and create new dates with the difference between the current day calculated with getDay value and the day value specified in your array.
Make use of some logic to reperesent those date object in specified format. I took support from this post to format your date string.
const availableDays = [0,2,4,6];
const today = new Date();
const currentDay = today.getDay();
const currentDate = today.getDate();
const currentMonth = today.getMonth();
const currentYear = today.getFullYear();
formatDateToString = (date) => String(date.getDate()).padStart(2, '0') + '-' + String(date.getMonth() + 1).padStart(2, '0') + '-' + date.getFullYear();
const output = availableDays.map((day) => formatDateToString(new Date(currentYear, currentMonth, currentDate - (currentDay - day))));
console.log(output);
I have a date range suppose 2000-01-01 to 2021-06-01. I want to check whether a particular month with a given year falls in this range or not (E.g., month = March and year = 2021) using JavaScript.
Create a reusable function isDateInRange that accepts your three date Strings arguments.
Than you can simply compare your Date Objects using the needed operands:
const isDateInRange = (date, from, to) => {
const d = new Date(date);
const f = new Date(from);
const t = new Date(to);
return (d >= f && d < t);
};
console.log(isDateInRange("2001-01-31", "2000-01-01", "2021-06-01")) // true
console.log(isDateInRange("2050-01-01", "2000-01-01", "2021-06-01")) // false
Here is a solution passing month and year (not a date) as you requested.
const lowerRange = new Date('2000-01-01');
const upperRange = new Date('2021-06-01');
// If month and year are numbers
const monthYearInRange = (year, month) => {
if (typeof month !== 'number') throw new Error('Month should be number');
if (typeof year !== 'number') throw new Error('Year should be number');
// We do this to make sure it is 2 chars.
const mth = month < 10 ? `0${month}` : month;
// Set it to first of the month
const checkVal = new Date(`${year}-${mth}-01`);
if (isNaN(checkVal)) throw new Error(`Year: ${year} and Month: ${month} are not valid.`);
return checkVal <= upperRange && checkVal >= lowerRange;
}
console.log(monthYearInRange(2000, 2)); // true
console.log(monthYearInRange(2030, 2)); // false
console.log(monthYearInRange(2021, 6)); // true
console.log(monthYearInRange(2021, 10)); // false
Just a note on this solution - because ultimately we convert the year/month into a date, when doing this we have to instantiate the date using the ISO format YYYY-MM-DD. If checkVal gets instantiated with a month that is a single character (1 instead of 01) it will still work in most cases - but you will get edge cases breaking because the Date() constructor will add timezone values to the date.
Update: Added NaN check - per #RobG
I tried the following approach and it worked:
function isBetween(n, a, b) {
return (n - a) * (n - b) <= 0
}
var startDate = '2021-03-15';
var endDate = '2021-06-01';
var checkFor = '2021-05-31';
D_1 = startDate.split("-");
D_2 = endDate.split("-");
D_3 = checkFor.split("-");
//console.log(D_1+" "+D_2+" "+D_3);
var startNumber = D_1[0]*100 + D_1[1];
var endNumber = D_2[0]*100 + D_2[1];
var checkNumber = D_3[0]*100 + D_3[1];
var check = isBetween(checkNumber, startNumber, endNumber);
console.log(check);
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);
}
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
$.each(data[i].replies, function(m, n) {
var currentdate = new Date();
console.log(n.entry.date_entered);
check = moment(n.entry.date_entered, 'YYYY/MM/DD');
check1 = moment(currentdate, 'YYYY/MM/DD');
console.log(check);
console.log(check1);
var month = check.format('M');
var day = check.format('DD');
var year = check.format('YYYY');
var month1 = check1.format('M');
var day1 = check1.format('DD');
var year1 = check1.format('YYYY');
get = moment([year, month, day]);
get1 = moment([year1, month1, day1]);
g = get1.from(get);
});
Sample n.entry.date_entered : 2014-07-28 12:23:43
For all the dates i am getting a few seconds ago don't know why
I think your problem is the format mask that you pass in to moment.
In your sample you use - as the delimiter but in your format mask you use /. This way moment will not be able to parse the date and will give you the current date instead.
Try changing your format mask to "YYYY-MM-DD".