Set custom start date in html - javascript

I would like to set a custom start date for a calendar. So instead of the Gregorian calendar's start at 0, 2016 years ago. I would like to start at something like 1980 and a custom month and day too.
So instead of a new year at January 1st, I would like November 5th to be the new year instead (but it's still called January 1st, but compared to the Gregorian calendar, it's November 5th).
Which means, when we (with the Gregorian calendar) have the date 2016-02-10, the calendar I make, I would like it to be year 36 (2016-1980), month April (as November is now first instead of January according to the Gregorian calendar), and day 15 (10+5). So 2016-02-10 would be 30-04-15.
I have this code, but I don't know how to get it to work. Is it possible to do or will I have write code for everything that can happen?
<script type="text/javascript">
var tmonth=new Array("November","December","January","February","March","April","May","June","July","August","September","October");
function GetClock(){
var d=new Date();
//d.setFullYear(1980,0,3);
var nmonth=d.getMonth()
ndate=d.getDate(),nyear=d.getYear();
if(nyear<1000) nyear+=1900;
nyear-=1962;
d.setFullYear(nyear,nmonth,ndate);
var nhour=d.getHours(),nmin=d.getMinutes(),nsec=d.getSeconds(),ap;
if(nhour==0){ap=" AM";nhour=12;}
else if(nhour<12){ap=" AM";}
else if(nhour==12){ap=" PM";}
else if(nhour>12){ap=" PM";nhour-=12;}
if(nmin<=9) nmin="0"+nmin;
if(nsec<=9) nsec="0"+nsec;
document.getElementById('clockbox').innerHTML=""+tmonth[nmonth]+" "+ndate+", "+nyear+" "+nhour+":"+nmin+":"+nsec+ap+"";
}
window.onload=function(){
GetClock();
setInterval(GetClock,1000);
}
</script>
<div id="clockbox"></div>

If i was going to do something like this i'd probably get the difference between now and November the 5th (last year) in milliseconds which is: 8592904550
This means, you can subtract that number from the current timestamp to get the date that amount of seconds ago. I'd then take the current year and -1980 to get the year number.
$(function(){
var el = $('.clockbox');
var dateNow = new Date();
var newDateStamp = dateNow-8592904550;
var newDate = new Date(newDateStamp);
el.text(newDate.getMonth()+1 + "-" + newDate.getDate() + "-" + (dateNow.getFullYear()-1980));
})
You can see a fiddle using jQuery here: https://jsfiddle.net/fpmes8y3/1/
remember the getMonth is zero indexed so you need to +1 to get the true number.
Sorry if i've misunderstood your question.

Related

Javascript and setMonth behaving unexpectedly

I am doing datObj.setMonth(1), but the month is being set to March? Isn't 1 supposed to be February? I'm using Chrome 79.
Here's part of code meant to parse dates such as YYYY-MM-DD HH:MM:SS (because safari can't do that natively)
var date = "2020-02-02 23:59:00"
if (typeof date == 'string')
{
var dateParts = date.split(/[:-\s]+/);
if (dateParts.length == 6)
{
dateObj = new Date();
dateObj.setYear(dateParts[0]);
var m = dateParts[1] - 1;
console.log('m= ' + m);
dateObj.setMonth(m);
console.log('after setmonth, date= ' + dateObj);
dateObj.setDate(dateParts[2]);
dateObj.setHours(dateParts[3]);
dateObj.setMinutes(dateParts[4]);
dateObj.setSeconds(dateParts[5]);
}
}
console.log(dateObj);
alert(dateObj);
Your problem, as you figured, is that you're setting the month while the day is still 30. While you could work around that by using setFullYear and pass year, month and day at once, you really should just construct the whole Date object with the right values in the first place:
dateObj = new Date(dateParts[0], dateParts[1]-1, dateParts[2], dateParts[3], dateParts[4], dateParts[5]);
or rather using UTC as the timezone:
dateObj = new Date(Date.UTC(dateParts[0], dateParts[1]-1, dateParts[2], dateParts[3], dateParts[4], dateParts[5]));
Just figured this out before I submitted. Today is January 30th, 2020. I can't change the month to February, because there is no February 30th. So, the code breaks either on the 29th or the 30th day of the month.
In JavaScript, it is advisable to do
dateObj.setMonth(monthNum -1, dayNum)
to set the day and month at the same time to avoid this problem

How to use moment to find first monday 18 month ago

I am writing some javascript and came across moment library.I would like to use the moment to get the first Monday of 18 Month ago. How would I do it?
I know 18 months ago it is
moment().subtract(18, 'months');
But how would I know the first Monday of that time.
Thanks ahead of time!
You can do this in one line.
moment().subtract(18,'months').startOf('month').add(6 - moment().day("Monday").day() ,'days').startOf('week').day(1);
Find the moment 18 months ago, get the start date of that month, add 6 days since in worst case the first of that month is a tuesday(results in a date which is in the week that includes the first monday) and then get the start of that week.
Voila, all in one line.
1st edit: corrected the calculation to be locale independent and always return a Monday and not beginning of week since that is locale dependent.
2nd edit: locales makes it a bit more complicated. Adding 6 days to a Monday with a locale where the week ends on Saturday will move into another week thus we need to adapt the algorithm to take the Monday week number into consideration, i.e. subtract moment().day("Monday").day() which gives the locale dependent week day number of a Monday(0 or 1). Changed in the code above.
cleaner and more reusable IMHO ;)
var monday = moment().day('Monday').weekday();
var searchFirstMonday = moment().subtract(18, 'months').startOf('month');
while (searchFirstMonday.weekday() !== monday){
searchFirstMonday.add(1, 'day');
}
If you go back 18 months, get the first day of that month, then the Monday of that week, you'll get close:
moment().subtract(18, 'months').startOf('month').day(1)
To make sure the Monday is in the right month, you need to break that down a bit:
var month = moment().subtract(18, 'months');
var firstMonday = month.startOf('month').day(1);
if (firstMonday.month() != month.month()) {
firstMonday = firstMonday.add(7, 'days');
}
If anyone wants to do the same without any libraries.
Not sure if this is the best way to do it :P
var now = new Date();
//Get year and month
var month = now.getMonth();
var year = now.getFullYear();
//Months to go back
var monthsIntoPast = 18;
//Day of week we're looking for
var firstWeekDay= 2;
//Loop for one week
for(var x = 0; x < 7; x++) {
//Go back 18 months to first day + x of the month
var past = new Date(year, month - monthsIntoPast, 2 + x);
//First monday
if(past.getDay() == firstWeekDay) {
//First monday 18 months ago
alert(past.toUTCString())
break;
}
}
You use the following code to get what you need:
// Subtract 18 months from the current date, then get the first day of the month
var date = moment().subtract(18, 'months').startOf('month');
// Get current month
var month = date.month();
// Get monday of the first week of the month
var firstMonday = moment(date).weekday(0);
// Check if the first day of the month is not Monday
// and first monday of first week is in the desired month
if( date.weekday() != 0 && firstMonday.month() != month ){
// Add 1 week if needed
firstMonday.add(1, 'weeks');
}
The example above consideres Monday as the first day of the week. If Monday is not the first day of the week (day with index 0), you can get the correct index using moment.weekdays()
var moment = require('moment');
date = moment().subtract(18, 'months').startOf('month');
First we get the the current date and subtract 18 months. Then we find the start of the month, which as of today is
_d: Tue Jul 01 2014 00:00:00 GMT-0800 (AKDT),
So now we need to adjust for the next Monday. We get the current day of the week with date.day() which will give us a number between 0-7 with 0 being last Sunday and 7 being next Sunday. In this case, the first is on a Tuesday.
>date.day();
2
So we take the offset of the day of the week and subtract it from 8. Why 8 you say? Because if you count every number including 0 and 7 there are 8 numbers. (Think arrays)
//since it's not monday we add the offset
date = date.add(8-date.day(), 'days');
In your code you'd want to check if the First day returned actually IS a Monday so as to not get the second Monday of the month. So the whole thing might look like
date = moment().subtract(18, 'months').startOf('month');
if(date.day() > 1){ //check if it's Monday
//since it's not monday we add the offset
date = date.add(8-date.day(), 'days');
}
returns
_d: Mon Jul 07 2014 00:00:00 GMT-0800 (AKDT),

Javascript add days to a existing calendar object off by one month

I'm trying to read a date from a Calendar object and add a specific amount of days to it (i.e. 7)
Here is the code that I have:
var daysFromBeginDate = parseInt($("#policyDuration").val()) * 7
alert(daysFromBeginDate)
var beginDate = new Date("2015-04-24");
alert(beginDate)
var endDate = new Date("2015-05-08");
alert(beginDate.getDate() + daysFromBeginDate)
endDate.setDate(new Date(beginDate.getDate() + daysFromBeginDate));
alert(endDate.toString())
and I am getting Sun May 31 2015 17:00:000 GMT as my answer. It should be that with one less month, where is the extra month getting added?
JavaScript using the below call, I found out that the month argument counts starting from zero.
new Date(2015, 3, 1); // that's the 1st April 2015!
And what is causing the issue is the below code snippet in your code:-
endDate.getMonth() + 1
That is possibly the reason for your issue..
EDIT:
if the below code
var endDate = new Date("2015-05-08");
is changed to
var endDate = new Date();
you will get correct output..
it is because setDate sets the day of the month and April has only 30 days so it is rolled over and you get it as May and you get 31 because 24+7 is 31..

moment.js thinks that 2013-12-31 is week 1, not week 53

The moment.js library is awesome, and I use it almost all the time, but I recently ran into something interesting. I'm trying to plot data by week of the year, and one of the data points was 2013-12-31, moment.js tells me this is week 1? Is there a better way to handle this? either with 53, null, -1, or something?
moment('2013-12-31').week()
(returns) 1
I thought maybe using isoWeek or format would get around this, but they all return the same value of 1, despite the documentation saying it goes to 53.
moment('2013-12-31').isoWeek()
(returns) 1
+moment('2013-12-31').format('w')
(returns) 1
Anyone have any ideas on this? (short of making a test whether the week computed has a min/max date that covers the date value I passed it)
It is because the week from the 30th december 2013 is considered to be the 1st week of 2014 as you may see on this page epoch converter
And according to momentjs documentation:
The week with January 1st in it is the first week of the year.
I had a problem at my work where we used .format('YYYY WW') for some comparison logic.
That doesn't really make sense, as you should probably use .format('gggg WW') in such cases.
moment('2013-12-31').format('YYYY w'); // Returns 2013 1
moment('2013-12-31').format('gggg w'); // Returns 2014 1
https://momentjs.com/docs/#/displaying/format/
This is expected behavior. According to the ISO 8601 standard, 2013 is not a year with 53 weeks.
The long years, with 53 weeks in them, can be described by any of the following equivalent definitions:
any year starting on Thursday (dominical letter D or DC) and any leap year starting on Wednesday (ED)
any year ending on Thursday (D, ED) and any leap year ending on Friday (DC)
years in which 1 January and 31 December (in common years) or either (in leap years) are Thursdays
(source)
2013 started and ended on a Tuesday so therefore it is not a "long year" and 2013-12-31 is considered part of the first week of 2014.
If you want that week to be the 53rd, you'll have to write custom code for it as the ISO standard won't agree with you!
Moment.js docs aren't that straightforward with this I had to move from WW-YYYY to WW-GGGG
moment(2019-12-30T00:20:53.380Z).format(WW-YYYY) // Gave me 01-2019 incorrectly
moment(2019-12-30T00:20:53.380Z).format(WW-GGGG) // Gave me 01-2020 correctly
Findings
If your doing locale weeks, use ww & gggg
If your doing ISO weeks, use WW & GGGG
A mix of w/W & Y is incorrect usage
I had the same problem with the calculation of the week number, starting from the date of Sunday.
Finally I was able to solve the problem by calculating the week number starting not from Sunday but from Monday.
moment(date).isoWeekday(1).week()
Better right a custom method which will convert date into week and that can be customized easily.
//value : (MMM DD YYYY format)
function getEpiWeek(value) {
Date.prototype.getWeek = function () {
var target = new Date(this.valueOf());
// ISO week date weeks start on monday, so correct the day number
var dayNr = (this.getDay() + 7) % 7;
// Set the target to the thursday of this week so the
// target date is in the right year
target.setDate(target.getDate() - dayNr + 3);
// ISO 8601 states that week 1 is the week with january 4th in it
var jan4 = new Date(target.getFullYear(), 0, 4);
// Number of days between target date and january 4th
var dayDiff = (target - jan4) / 86400000;
if (new Date(target.getFullYear(), 0, 1).getDay() < 4) {
return 1 + Math.ceil(dayDiff / 7);
}
else { // jan 4th is on the next week (so next week is week 1)
return Math.ceil(dayDiff / 7);
}
};
var weekNumber = new Date(value).getWeek()
var year = getYear(value, weekNumber);
return weekNumber + ' ' + year;
}
function getYear(value, weekNumber) {
var year = parseInt(value.split(' ')[2]);
if (value.split(' ')[0] == 'Jan') {
if (weekNumber > 40) {
year = year - 1;
}
}
if (value.split(' ')[0] == 'Dec') {
if (weekNumber < 2) {
year = year + 1;
}
}
return year.toString();
}
Personally solved my ordering issue using :
if(d.month()==0) {
week = d.week();
}else{
week=d.isoWeek();
}

JS time calculation - How many times a date has occurred between two dates

I really need some assistance with a time calculation in JS.
Put basically I need to calculate how many times a day of a month has occurred between two dates.
For Example -
A date of 15th of the month between 1st February 2014 to 14 May 2014 would be 3
A date of 15th of the month between 1st February 2014 to 16 May 2014 would be 4
I've looked at moment Jquery library but it estimates that a month is 30 days so I wouldn't be exact and take into consideration leap years - months with 28 days etc..
It really needs to be exact because its for a chargeable event calculation. The dates can spare many years so could lead to in-accuries because of the 30 day thing.
Any help would be appreciated
There are probably a million ways to do this... here's a brute force way:
// add a "addDays() method to Date"
Date.prototype.addDays = function(days)
{
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
// provide two dates and a day ordinal you want to count between the two
function numOrdinalsBetweenDts(Date1, Date2, theOrdinal) {
var temp;
if(Date2 < Date1) { // put dates in the right order (lesser first)
temp = Date1;
Date1 = Date2;
Date2 = temp;
}
var workDate = Date1;
var ctr = 0;
while(workDate < Date2) { // iterate through the calendar until we're past the end
if(workDate.getDate() == theOrdinal) // if we match the ordinal, count it
ctr++;
workDate = workDate.addDays(1); // move the calendar forward a day
}
return ctr;
}
var result = numOrdinalsBetweenDts(new Date("July 21, 1901"), new Date("July 21, 2014"), 2);
console.log(result);
alert(result);
There is a slightly counter-intuitive behavior in the Javascript Date constructor where if you create a new Date with the day set to 0, it will assume the last day of the month. You can the use the following function get the number of days in a month:
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
The Javascript date object is leap-year aware, so you can use this function reliably.
You then just need to count the number of months between the start and end date and check each one to make sure the day number is actually present in the month. You can short-circuit this check if the day is less than or equal to 28.

Categories

Resources