Getting last 3 months using JavaScript - javascript

I need help in getting the last 3 months in javascript. I have generated an excel sheet in which the user has to populate month number in month column and year in year column.
I need to validate that the user has entered correct month and year combination based on current year.
User fill up the excel and upload it to node js fastify server. After that, I need to validate the month and year.
example:
If the current year is 2018 and the month is Jan(1). Users can enter 2017 in a year and 10 in a month.
The current year is 2019 and the month is 10. User can enter 8 in month
Please guide me. How can I achieve this?
const months = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'];
const getLastThreeMonths = () => {
const now = new Date();
const previousMonths = [];
for (let i = 0; i < 3; i += 1) {
previousMonths.push(`${months[(now.getMonth() - i)]}`);
}
return previousMonths;
};
console.log(getLastThreeMonths());

one working code sample is here ..You can change the content as per your requirement.
$(document).ready(function () {
var date = new Date();
var month = date.getMonth() + 1;
var year = date.getFullYear();
if (month == "1") {
year = date.getFullYear() - 1;
}
month = month - 2;
$("#month").on('change', function () {
if ($("#month").val() != month) { alert("not valid month"); }
});
$("#year").on('change', function () {
if ($("#year").val() != year) {alert("not valid year"); }
});
});
<input type="text" id="month" placeholder="put month here"/>
<input type="text" id="year" placeholder="put year here"/>

My Answer:
const dateValidator = (month, year) => {
const allowedRange = [];
for (let i = 1; i <= 3; i += 1) {
const current = new Date();
current.setMonth(current.getMonth() - i + 1);
allowedRange.push({ month: current.getMonth() + 1, year: current.getFullYear() });
}
return allowedRange.find(ar => ar.month === month && ar.year === year);
};

Related

Pikaday JS How to use full day and month names for input format without moment js

I'm using Pikaday.js like so:
new Pikaday({
field: document.getElementById('top-banner-datepicker'),
minDate: new Date()
I know that the answer lies in this example from the documentation:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
format: 'D/M/YYYY',
toString(date, format) {
// you should do formatting based on the passed format,
// but we will just return 'D/M/YYYY' for simplicity
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
return `${day}/${month}/${year}`;
},
parse(dateString, format) {
// dateString is the result of `toString` method
const parts = dateString.split('/');
const day = parseInt(parts[0], 10);
const month = parseInt(parts[1], 10) - 1;
const year = parseInt(parts[2], 10);
return new Date(year, month, day);
}
});
But I can't figure out how to use full day (Monday, Tuesday, Wednesday, etc) and full month names (January, February, etc) instead of the abbreviations (Mon, Tue, Wed... Jan, Feb, Mar... etc)
I don't want to use Moment.JS as it's a giant dependency.
Any help much appreciated!
Thank you
If you wish to format the datepicker field you could use toLocaleString().
For example if you want to get October instead of Oct:
date.toLocaleString('default', {
month: 'long' // use localestring month to get the long month
});
And if you want to get Sunday instead of Sun:
date.toLocaleString('default', { // use localestring weekday to get the long day
weekday: 'long'
});
Example snippet:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
firstDay: 1,
minDate: new Date(),
maxDate: new Date(2020, 12, 31),
yearRange: [2000, 2020],
format: 'D-M-YYYY',
toString(date, format) {
console.log(date.toLocaleString('default', {
weekday: 'short' // use localestring weekday to get the short abbv of day
}));
console.log(date.toLocaleString('default', {
month: 'short' // use localestring weekday to get the short abbv of month
}));
// you should do formatting based on the passed format,
// but we will just return 'D/M/YYYY' for simplicity
const day = date.getDate();
const daylong = date.toLocaleString('default', { // use localestring weekday to get the long day
weekday: 'long'
});
const month = date.getMonth() + 1;
const monthlong = date.toLocaleString('default', {
month: 'long' // use localestring month to get the long month
});
const year = date.getFullYear();
return `${daylong}, ${monthlong}, ${day} ${year}`; // just format as you wish
}
});
#datepicker {
width: 200px;
}
<link href="https://pikaday.com/css/pikaday.css" rel="stylesheet" />
<script src="https://pikaday.com/pikaday.js"></script>
<label for="datepicker">Date:</label>
<input type="text" id="datepicker">
Pikaday Parsing
It's usually pretty easy getting dates into the correct format, but the tricky part usually is getting a date from a string. There's this warning in the Pikaday Read Me:
Be careful, though. If the formatted string that you return cannot be
correctly parsed by the Date.parse method (or by moment if it is
available), then you must provide your own parse function in the
config. This function will be passed the formatted string and the
format:
parse(dateString, format = 'YYYY-MM-DD')
Using Date.parse, can yield irregular results. This is where moment.js comes in handy as it can handle a variety of formats. The parsing function is used when a person directly types into the input field and maybe elsewhere.
Two approaches could involve using lightweight alternative to moment.js, or a custom formatter.
Approach 1: Lightweight Alternatives
You can search for moment.js alternatives. I found this repo that lists a few. For this example, I chose luxon, as it seems to be pretty small. You can see all the token it supports here: https://moment.github.io/luxon/docs/manual/parsing.html#table-of-tokens
To help out with parsing, I added this bit, which strips out weekday parsing, just in case if the weekday doesn't match the actual date:
if (format.startsWith('EEEE ')) {
format = format.split(' ').slice(1).join(' ');
dateString = dateString.split(' ').slice(1).join(' ');
}
Here's a working snippet:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
format: 'EEEE LLLL d, yyyy',
toString(date, format) {
return luxon.DateTime.fromJSDate(date).toFormat(format);
},
parse(dateString, format) {
if (format.startsWith('EEEE ')) {
format = format.split(' ').slice(1).join(' ');
dateString = dateString.split(' ').slice(1).join(' ');
}
return luxon.DateTime.fromFormat(dateString, format).toJSDate();
}
});
div {
position: absolute;
bottom: 0;
}
#datepicker {
width: 250px;
}
<link href="https://pikaday.com/css/pikaday.css" rel="stylesheet" />
<script src="https://pikaday.com/pikaday.js"></script>
<script src="https://moment.github.io/luxon/global/luxon.min.js"></script>
<div><label for="datepicker">Date:</label>
<input type="text" id="datepicker">
</div>
Approach 2: Custom Formatter
For this answer I'll just use the format that you're asking for, but it gets tricky to parse a variety of formats.
Custom Names
To get custom names for months, you can just hard code them in:
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
Alternatively, since you want normal names, you can just programmatically generate them using Intl.DateTimeFormat. This is also useful if you want to have the months and weekdays show up in the user's locale:
var monthFormatter = new Intl.DateTimeFormat([], { month: 'long' });
var months = [... new Array(12)].map((d, i) => monthFormatter.format(new Date(2020, i, 1)));
var dayFormatter = new Intl.DateTimeFormat([], { weekday: 'long' });
var days = [... new Array(7)].map((d, i) =>dayFormatter.format(new Date(2020, 1, 2 + i)));
To access the names, you just use the corresponding index (remember that they're zero based though)
console.log(months[new Date().getMonth()]); // current month
console.log(days[new Date().getDay()]); // current day
Thus your custom format function looks something like this:
toString(date, format) {
// you should do formatting based on the passed format,
// but we will just return 'D/M/YYYY' for simplicity
const day = date.getDate();
const year = date.getFullYear();
const weekday = date.getDay();
const month = date.getMonth(); // remember, this is zero based!
return `${days[weekday]} ${months[month]} ${day}, ${year}`;
},
Date Parsing
Here's a custom tailored parsing function for the above format Weekday Month Day, Year:
parse(dateString, format) {
// split the string into the parts separated by a space
const parts = dateString.trim().split(' ');
var day, month, year, startIndex;
if (parts.length >= 3) {
if (parts.length >= 4) {
// if there's four parts, assume the first part is the weekday, which we don't need to use to convert it to a date
startIndex = 1; // skip the weekday
} else {
// if there's only three parts, assume that the weekday was omitted
startIndex = 0;
}
// look up the month from our prebuilt array. If it isn't found, it'll return -1, otherwise it will return the (zero based) numerical month.
month = months.indexOf(parts[startIndex]);
day = parts[startIndex + 1];
// if there's a comma after the day, remove it
if (day.endsWith(',')) {
day = day.substring(0, day.length - 1);
}
day = +day; // convert the string into a number
year = +parts[startIndex + 2]; // convert the string year into a number
}
if (parts.length < 3 // there is less than 3 parts
|| month === -1 // the month wasn't found
|| isNaN(day) // the day isn't a number
|| isNaN(year)) { // the year isn't a number
return Date.parse(dateString); // fall back to default Date parsing
}
return new Date(year, month, day);
}
All together, it looks like this:
var monthFormatter = new Intl.DateTimeFormat([], { month: 'long' });
var months = [... new Array(12)].map((d, i) => monthFormatter.format(new Date(2020, i, 1)))
var dayFormatter = new Intl.DateTimeFormat([], { weekday: 'long' });
var days = [... new Array(7)].map((d, i) =>dayFormatter.format(new Date(2020, 1, 2 + i)))
// Alternatively you can just hard code these:
// var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
// var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var picker = new Pikaday({
field: document.getElementById('datepicker'),
format: 'D/M/YYYY',
toString(date, format) {
// you should do formatting based on the passed format,
// but we will just return 'D/M/YYYY' for simplicity
const day = date.getDate();
const year = date.getFullYear();
const weekday = date.getDay();
const month = date.getMonth(); // remember, this is zero based!
return `${days[weekday]} ${months[month]} ${day}, ${year}`;
},
parse(dateString, format) {
// split the string into the parts separated by a space
const parts = dateString.trim().split(' ');
var day, month, year, startIndex;
if (parts.length >= 3) {
if (parts.length >= 4) {
// if there's four parts, assume the first part is the weekday, which we don't need to use to convert it to a date
startIndex = 1; // skip the weekday
} else {
// if there's only three parts, assume that the weekday was omitted
startIndex = 0;
}
// look up the month from our prebuilt array. If it isn't found, it'll return -1, otherwise it will return the (zero based) numerical month.
month = months.indexOf(parts[startIndex]);
day = parts[startIndex + 1];
// if there's a comma after the day, remove it
if (day.endsWith(',')) {
day = day.substring(0, day.length - 1);
}
day = +day; // convert the string into a number
year = +parts[startIndex + 2]; // convert the string year into a number
}
if (parts.length < 3 // there is less than 3 parts
|| month === -1 // the month wasn't found
|| isNaN(day) // the day isn't a number
|| isNaN(year)) { // the year isn't a number
return Date.parse(dateString); // fall back to default Date parsing
}
return new Date(year, month, day);
}
});
div {
position: absolute;
bottom: 0;
}
#datepicker {
width: 250px;
}
<link href="https://pikaday.com/css/pikaday.css" rel="stylesheet" />
<script src="https://pikaday.com/pikaday.js"></script>
<div><label for="datepicker">Date:</label>
<input type="text" id="datepicker">
</div>
Not going to write a book about it, because such default formats can be accomplished with Date, in particular method toLocaleDateString(), where long is the non-abbreviated weekday/month:
dateLocale: 'en-US',
dateOptions: {weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'},
toString(date, format) {
return date.toLocaleDateString(this.dateLocale, this.dateOptions);
},
Even if the formatting possibilities are rather limited alike that,
the advance still is, that supporting multi-locale is no problem.

clock.js, conditionally set eastern or central time

I have a perfectly functioning clock.js widget that I'm using to display date and time on multiple displays throughout our offices in several states.
The offices in the Eastern timezone have no issue, as this defaults to eastern time (our server running the screens for every display is eastern).
However, I want to add a conditional in here (say if $screenID == 3 {... so that on the screens in the Central time zone it shows the proper central time.
How should I go about adding a block in here for that condition to show central rather than eastern?
function startTime() {
var today = new Date();
var hr = today.getHours();
var min = today.getMinutes();
// var sec = today.getSeconds();
ap = (hr < 12) ? "<span>AM</span>" : "<span>PM</span>";
hr = (hr == 0) ? 12 : hr;
hr = (hr > 12) ? hr - 12 : hr;
//Add a zero in front of numbers<10
hr = checkTime(hr);
min = checkTime(min);
// sec = checkTime(sec);
document.getElementById("clock").innerHTML = hr + ":" + min + " " + ap;
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var curWeekDay = days[today.getDay()];
var curDay = today.getDate();
var curMonth = months[today.getMonth()];
// var curYear = today.getFullYear();
var date = curWeekDay+", "+curDay+" "+curMonth;
document.getElementById("date").innerHTML = date;
var time = setTimeout(function(){ startTime() }, 500);
}
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
Use timezones.
function startTime(screen, loc) {
var timeZone = "America/Chicago";
if (screen === 1)
timeZone = "America/New_York";
var dateOptions = { weekday: 'long', day: 'numeric', month: 'long', timeZone: timeZone };
var timeOptions = { hour: 'numeric', minute: 'numeric', timeZone: timeZone };
var dt = new Date();
document.getElementById("myclock" + loc).innerHTML = dt.toLocaleString("en-US", timeOptions);
document.getElementById("mydate" + loc).innerHTML = dt.toLocaleString("en-NZ", dateOptions);
}
startTime(0, 1);
startTime(1, 2);
<div id="myclock1">asdf</div>
<div id="mydate1">asdf</div>
<hr>
<div id="myclock2">asdf</div>
<div id="mydate2">asdf</div>

Fixed date to be use for date conversion

Is there a way I can have a fixed date that I will use for conversion.
as you can see, the code below states that it is the time in Manila, PH but when you open it given that you are in a different timezone to me it will give you different time. Date(); will just get the time in your computer.
Is there a way to get a date which will be use as a default date so that I can add or minus hours to get my desired conversion date even though it will be open in different timezones?
function showTime() {
var a_p = "";
var today = new Date();
var curr_hour = today.getHours();
var curr_minute = today.getMinutes();
var curr_second = today.getSeconds();
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var myDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var date = new Date();
var day = date.getDate();
var month = date.getMonth();
var thisDay = date.getDay(),
thisDay = myDays[thisDay];
var yy = date.getYear();
var year = (yy < 1000) ? yy + 1900 : yy;
if (curr_hour < 12) {
a_p = "<span>AM</span>";
} else {
a_p = "<span>PM</span>";
}
if (curr_hour == 0) {
curr_hour = 12;
}
if (curr_hour > 12) {
curr_hour = curr_hour - 12;
}
curr_hour = checkTime(curr_hour);
curr_minute = checkTime(curr_minute);
curr_second = checkTime(curr_second);
document.getElementById('clock-large1').innerHTML=curr_hour + " : " + curr_minute + " : " + curr_second + " " + a_p;
document.getElementById('date-large1').innerHTML="<b>" + thisDay + "</b>, " + day + " " + months[month] + " " + year;
}
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
setInterval(showTime, 500);
<div id="clockdate-full">
<div class="wrapper-clockdate1">
<div id="clock-large1"></div>
<div id="date-large1"></div>
<div id="timezone">Manila, PH</div>
</div>
</div>
Checkout moment .js
http://momentjs.com
You can specify the time zone of the date time
var timezone = 'America/Chicago'
moment().tz(timezone).format('hh:mm:ss z')
If you can't use an external link, you should try the code below:
var opt= {
timeZone: 'America/Chicago',
year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric'
},
formatDate = new Intl.DateTimeFormat([], opt)
formatDate.format(new Date())
Is there a way to get a date which will be use as a default date so that I can add or minus hours to get my desired conversion date even though it will be open in different timezones?
Yes, just specify the "fixed" date in a suitable format. Most browsers will parse ISO 8601 extended format strings like 2017-05-25T17:35:48+08:00. That represents 5:30pm in Manilla, which is UTC+08:00.
To get the equivalent time on the user's system:
var d = new Date('2017-05-25T17:35:48+08:00');
console.log(d.toString()); // equivalent local time
If you want to support browsers like IE 8, you'll need to parse the string manually or use a library with a parser, e.g. moment.js or fecha.js.

Show current day in the title of jquery datepicker

How can I show current full date in the title of jquery datepicker like this :
05 July 2015 because it show me just July 2015
You could use a function like this in onSelect
function showDateInTitle(picker) {
var span = picker.dpDiv[0].querySelector('.ui-datepicker-day'),
df, month;
if (span === null) {
month = picker.dpDiv[0].querySelector('.ui-datepicker-month');
if (!month) return;
span = document.createElement('span');
span.setAttribute('class', 'ui-datepicker-day');
df = document.createDocumentFragment();
df.appendChild(span);
df.appendChild(document.createTextNode('\u00a0'));
month.parentNode.insertBefore(
df,
month
);
}
span.textContent = picker.selectedDay;
}
Still looking through API for a handler for after the datepicker is shown before choice is made
You can implement an afterShow as described here with a slight modification to get the instance
$(function() {
$.datepicker._updateDatepicker_original = $.datepicker._updateDatepicker;
$.datepicker._updateDatepicker = function(inst) {
$.datepicker._updateDatepicker_original(inst);
var afterShow = this._get(inst, 'afterShow');
if (afterShow)
afterShow.apply((inst.input ? inst.input[0] : null), [inst]);
}
});
Now DEMO
I couldn't find a non-hacky way of doing it, but changing the defaults config to the text you want to show might do it for you:
var defaults = {
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]
};
var today = new Date();
var month = today.getMonth();
defaults.monthNames[month] = today.getDate() + ' ' + defaults.monthNames[month];
$.datepicker.setDefaults(defaults);
Here is a working plnkr: http://plnkr.co/edit/gfp95VOchd4fhQOktIL3?p=preview
Here is my solution, it is a simple jquery solution that append the day value to the current datepicker widget.
$('#datepicker').click(function(){
var $datePickerBox = $('#ui-datepicker-div');
//var $datePickerBox = $(this).closest('.ui-datepicker.ui-widget');
var $monthName = $datePickerBox.find('.ui-datepicker-month');
var currentDay = '';
if($(this).val().trim().length==0){
currentDay = $datePickerBox.find('.ui-datepicker-today').text();
} else {
currentDay = $datePickerBox.find('.ui-datepicker-current-day').text();
}
$monthName.text( currentDay + " " + $monthName.text() );
});
Code pen link
http://codepen.io/anon/pen/WvzKJo
If you want to always show the current date at the top and not the selected date, using #PaulS.'s code change
span.textContent = picker.selectedDay;
to
span.textContent = new Date().getDate();
Demo

How to find ordinal position of any given weekday in JavaScript

I'm trying to find the actual position of a weekday in constant time. I get it working with loop but trying to find out it with some Mathematics. I know it is like divide it by 7 but not getting it work.
Here is the code.
for(var ind=0; ind<=between.length; ind++){
if (new Date(between[ind]).getMonthWeek() === baseDtWk && new Date(between[ind]).getDay() === baseDtD) {
datesToBeMarked.push(between[ind]);
console.log(" :Date: " + between[ind] + " :Week: " + new Date(between[ind]).getMonthWeek());
console.log("Date entered : " + new Date(between[ind]));
}
}
I have done this few days back. It is as simple as the code below. :)
On fiddle.
Number.prototype.nth= function(){
var n= Math.round(this), t= Math.abs(n%100), i= t%10;
if(i<4 && (t<4 || t> 20)){
switch(i){
case 1:return n+'st';
case 2:return n+'nd';
case 3:return n+'rd';
}
}
return n+'th';
}
Date.prototype.nthofMonth= function(){
var today= this.getDate(),m=this.getMonth(),
day= ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday'][this.getDay()],
month= ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'][m];
return [(m+1)+'-'+today,'the ', Math.ceil(today/7).nth(), day, 'of', month, 'in', this.getFullYear()].join(' ');
}
var date=new Date().nthofMonth();
console.log(date);
You haven't shown how you want the result to look, I guess you want to know if a particular date is, say, the nth Tuesday, e.g.
// Add ordinal to a number
function addOrdinal(n) {
var ord = [,'st','nd','rd'];
var a = n % 100;
return n + (ord[a>20? a%10 : a] || 'th');
}
// Return the ordinal number of a day in the month
function ordinalDay(d) {
d = d || new Date();
var days = ['Sunday','Monday','Tuesday','Wednesday',
'Thursday', 'Friday','Saturday'];
return addOrdinal(Math.ceil(d.getDate()/7)) + ' ' + days[d.getDay()];
}
console.log(ordinalDay(new Date(2015,0,1))); // 1st Thursday
console.log(ordinalDay(new Date(2015,0,27))); // 4th Tuesday
console.log(ordinalDay(new Date(2015,0,31))); // 5th Saturday
console.log(ordinalDay(new Date(2015,11,25))); // 4th Friday

Categories

Resources