How to make two timepickers behave like google calendar? - javascript

I try to make my timepickers behave like the ones in google calendar. What I try to achieve is that if I set the start time from 10:00 to 11:00, the 2nd should follow from 11:00 to 12:00. If I set the 2nd picker from 11 to 13, the difference is now 2 hours and if I adjust the first one, the 2nd should move +2 or -2 hours depending if its earlier or later on the day.
My current jquery code is now
var d = new Date();
var start_time = $('#calendarentryform-start_time').val();
var end_time = $('#calendarentryform-end_time').val();
var diff = ( new Date('1970-01-01 ' + end_time) - new Date('1970-01-
01 ' + start_time) ) / 1000 / 60 / 60;
var new_end_time = start_time + diff;
$('#calendarentryform-start_time').on('change',function() {
$('#calendarentryform-end_time').val(new_end_time);
}
);
It manage to find for example the hour difference on 1 hour, like the calculation is correct. But when I try to add that hour for new_end_time it just post 12:001 instead of 13:00 or whatever the time is supposed to be set to. I also want it to be able to find 1,5 hours, 2,5 hours etc.
I just dont seem to get it right.

Related

Each day a different item in an array - javascript

I have this script that makes a button redirect to a whatsapp page, on the URL (a href) I need to insert the number that's gonna be contacted.
What I need to do is each day a different number fills this URL.
Example:
day1 - phonen1,
day2 - phonen2,
...,
day 13 - phonen13,
//(starts over)
day14 - phonen1,
day15 - phonen2,
...
<a id="whatsapp" target="_blank" href="https://api.whatsapp.com/send?phone=5519997820734">Link</a>
<script>
phones= ["phonen1", "phonen2", ..., "phonen13"];
document.getElementById("whatsapp").href = "https://api.whatsapp.com/send?phone=5519"+ phones[i] +"";
</script>
you can use the date object with for loop like this:
<a id="whatsapp" target="_blank" href="https://api.whatsapp.com/send?phone=5519997820734">Link</a>
<script>
phones= ["phonen1", "phonen2", ..., "phonen13"];
var d = new Date();
var todayDate = d.getDate();
for (var i = todayDate; i > 13; i= i-13) {
todayDate = todayDate - 13;
}
document.getElementById("whatsapp").href = "https://api.whatsapp.com/send?phone=5519"+phones[i] + todayDate;
</script>
Simple Answer:
You can do this using a Date to count the number of days since the unix epoch, and mod that count by the length of your phones array to get an index that moves to the next item every 24 hours:
let phones = ["phonen1", "phonen2", "phonen3", "phonen4"];
const ms_per_day = 24 * 60 * 60 * 1000;
// (new Date()).getTime() gets the number of ms since 1 January 1970 00:00:00 UTC
// we divide by ms_per_day and floor to get the number of 24-hour cycles (this will increment each UTC day)
let days_since_epoch = Math.floor((new Date()).getTime() / ms_per_day);
// we mod by the length of phones to get a number in the range [0, phones.length)
let phones_index = days_since_epoch % phones.length;
document.getElementById("whatsapp").href = "https://api.whatsapp.com/send?phone=5519" + phones[phones_index];
console.log("Set link to", document.getElementById("whatsapp").href);
<a id="whatsapp" target="_blank" href="https://api.whatsapp.com/send?phone=5519997820734"> Link </a>
Caveats:
Working with time is complicated. The above method doesn't get the number of days exactly:
Due to the differing lengths of days (due to daylight saving changeover), months and years, expressing elapsed time in units greater than hours, minutes and seconds requires addressing a number of issues and should be thoroughly researched before being attempted.
...and the crossover time is in UTC anyway, so it's non-obvious when the above code will switch numbers (it won't be at midnight). But it will do so once every 24 hours, which should be sufficient for the use case described in the post.
One other caveat is that the number won't actually change until the user refreshes the page and reruns the script.
Use the date object to create an index into your array
<a id="whatsapp" target="_blank" href="https://api.whatsapp.com/send?phone=5519997820734">Link</a>
<script>
var phones= ["phone1","phone2","phone3","phone4","phone5","phone6","phone7","phone8","phone9","phone10","phone11","phone12","phone13","phone14"];
var startOfDay1 = new Date('July 1, 2018 00:00:00');//be aware this is the client timezone
var diffFromNow = Date.now() - startOfDay1.getTime();//get the difference in ms between now and midnight of "day 1"
console.log(diffFromNow);
var diffFromNowDays = diffFromNow/(24*60*60*1000);//turn that into a day value
var daynum = Math.floor(diffFromNowDays % 14);//constrain to 14 days
console.log(daynum);//zero based index
document.getElementById("whatsapp").href = "https://api.whatsapp.com/send?phone=5519"+ phones[daynum] +"";
</script>
Ollin's answer is great, but you can use local midnight as follows if you wish. Use the remainder operator % with the number of whole days since a particular point in time, any epoch will do.
If you want to do the changeover at midnight local time, then use local midnight for the epoch and current day. Use Math.round to remove daylight saving effects.
The following will change the value returned from the array at local 00:00:00.001 each day:
// Number of whole local days since date to today
function daysDiff(date) {
// Copy date, set to start of day
var d = new Date(+date);
d.setHours(0,0,0,0);
// Get start of current day
var e = new Date();
e.setHours(0,0,0,0);
// Return whole day count
return Math.round((e - d)/8.64e7);
}
// Select item from array based on number of whole days
// from epoch to today. Default is 1 July 2018
function getFromArray(array, epoch) {
if (!epoch) {
// If not provided, use 1 July 2018
epoch = new Date(2018,6,1);
}
var d = daysDiff(epoch);
return array[d % array.length];
}
var nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
// On local date 12 July 2018 returns 12
console.log(getFromArray(nums));

Display a date fortnightly using javascript

This is my first time posting a question on here however I am a long term user of StackOverflow.
I am very new to Javascript and am currently trying to solve a few issues I am having on a website I am creating for my university course.
I am trying to make a little information box on the website's dashboard that simply tells you when your next rubbish bin collection day is. This is currently every 2 weeks on a Friday, the next being 1st April. I was wondering if there was a simple way for me to display the next bin collection date until it's the day of the bin collection, where the text would change to say 'bin collection today!' and after about 6pm it would change to the next collection date in a fortnight.
Sorry if this is extremely poorly worded! The website will only be used in the UK so I don't need to worry about time zones.
Any help would be very much appreciated!
Many thanks,
Emily
Below is some code to show how it might be done, hopefully there are sufficient comments.
As far as I know, some parts of the UK observe daylight saving but the following should not be affected by any change of timezone since it uses local date methods.
Any date can be used for the start of the cycle, I've chosen 10 June 2011 totally randomly. Also, any time of day can be used to change the message on the final day from "put your bins out today" to the standard "next cycle is in x days".
The algorithm is calculate the number of milliseconds to the next full fortnight from the start date by subtracting the number of milliseconds from the last full fortnight from the milliseconds per fortnight. Then the remainder is converted to full days.
To save ambiguity on the day before the cycle ends (in this case, a Thursday) the message says the cycle ends "tomorrow" rather than in 1 day, and on the day itself, up to 18:00 or 6 pm it says the cycle ends today. After that, it says the cycle ends in 14 days or less.
// Date objects are based on milliseconds (8.64e7 per day)
// Calculate milliseconds for a fortnight
var msPerFortnight = 8.64e7 * 14;
// Any date can be the start of the fortnightly cycle
// Make Friday 10 June 2011 first day of cycle,
// Cycles end on 25 March, 6 April 2016.
// Note months are zero based so June is 5
var firstDayOfCycle = new Date(2011, 5, 10);
// Time of day to stop showing "put bins out today" message on start/end day
// 18 is 6 pm
var endHour = 18;
// Get the day name for the cycle start/end
var dayName = ['Sunday','Monday','Tuesday','Wednesday','Thursday',
'Friday','Saturday'][firstDayOfCycle.getDay()];
// Convert end hour to convenient format with am/pm
var endHourNeat = (endHour % 12 || 12) + ' ' + (endHour < 12? 'am' : 'pm');
// Get a date for now
var now = new Date();
// Get milliseconds to next full fortnight by
// msPerFortnight minus milliseconds since last full fortnight
var m = msPerFortnight - ((new Date() - firstDayOfCycle) % msPerFortnight);
// Calculate time remaining full days
var daysLeft = Math.ceil(m / 8.64e7);
// Create a human friendly message
var message;
// If more then one day left, or after 18:00 on last day, show this message
if (daysLeft == 14 && now.getHours() < endHour) {
message = 'Today is ' + dayName + ', so please put your bins out before ' + endHourNeat + '!';
} else if (daysLeft > 1 ) {
message = 'Put your bins out on ' + dayName + ' in ' + daysLeft +
' day' + (daysLeft == 1?'':'s') + ' time.';
} else if (daysLeft == 1) {
message = 'Put your bins out tomorrow, on ' + dayName + '.';
}
document.write(message);
You can even add the date of the end of the cycle and add ordinal, so it might read "Put your bins out on Friday the 25th, in 3 days time". But I'll leave that up to you.
A possible solution is to use Unix epoch, because they give you your time in seconds from 1/1/1970. By using this we can find how far we are into a fortnight. I found that Math.floor(Date.parse("2016-04-01")/86400000)%14equals 8.
Then your code might be:
var days_into_fortnight=Math.floor(Date.now()/86400000)%14;
var string_to_show;
var days_to_collection;
if (days_into_fortnight==8){
string_to_show="Bin collection!";
}
else{
if(days_into_fortnight<8){
days_to_collection=8-days_into_fortnight;
}
else{
days_to_collection=22-days_into_fortnight;
}
string_to_show=days_to_collection.toString()+" day(s) to collection!";
}
Edit:spelling

Java script - invoice due date miscalculation

Apologies in advance for my (something less than) basic knowledge of java script.
Can someone explain in basic – but specific – terms how this script is calculating?
Here is the script:
var d = new Date(year, month, day);
var e = new Date(d.getTime() + offset * 24 * 60 * 60 * 1000);
var month_out = e.getUTCMonth();
var day_out = e.getDate();
var year_out = e.getUTCFullYear();
date_out = month_out + "-" + day_out + "-" + year_out;
year = 2013
month = 12
day = 01
offset = 15
The offset is the “payment terms” and the date is the invoice date. The output is supposed to be the invoice date plus the offset to arrive at “12-16-2013”
That is NOT what it is kicking out and I need to figure out how to fix it.
One customer is having dates show up as: 0-16-2014
I don’t know which string is wrong or how it should read in its place. This is one piece of an entire function that pulls an invoice date from an XML file, strips the time from the date and creates a new "Date_Due" using the offset. This script is the only area that is failing.
Can anyone help?
getUTCMonth() returns 0 based months - 0 is January, 1 is February, etc.
Add 1 to this value to make it more human readable.
See docs for more info.

javascript date object doesnt return result

i have this calendar table(its bunch of floated divs.. not <table>),
my user should be able to click anywhere on row to add new booking. problem is how to calculate the time where he clicked.
so i use:
$('day-column').click(function(e){
var posY = $(this).offset().top;//get offset of click
var pos=(e.pageY - posY)* 60 * 1000;//convert it into millisec (since 1px=1min)
var start=8 * 60 * 60 * 1000;//covert starting hour 8:00 into millisec
var d = new Date();//create date object
d.setMilliseconds((start+pos));//set obj millisec
console.log(d.getHours()+':'+d.getMinutes());//try to extract new hour and time
});
Why is this not working ?? am i doing something wrong ?
I suggest using :
http://momentjs.com/
will support on all browsers , simple , and you can have the format option.
which i think you will like.

How does weekly reminders work?

Is there an algorithm for weekly reminders ?
For example, I set a reminder for Thursday & I check the "weekly" option.
The Reminder is supposed to alert every Thursday then,but how is this done?
I thought about an idea, but I guess it's very stupid:
Get today's "day".
Get today's "date".
Get the wanted day number.
Subtract both days from each other.
using [4] get that day's date.
Increment the counter after every alert with 7.
I don't even know whether this will work or not, I'm sure there is a better way to do it, so I need your opinions before starting implementation.
PS: I use JavaScript so the functions are very limited.
It's not entirely clear what you're trying to do.
If your code needs to know whether it's Thursday, that's really easy using getDay, which gives you the day of the week:
if (new Date().getDay() === 4) {
// It's Thursday
}
The day numbers start with 0 = Sunday.
If your code needs to find the next Thursday starting on a given date:
var dt = /* ...the start date... */;
while (dt.getDay() !== 4) {
dt.setTime(dt.getTime() + 86400000)) // 86400000 = 1 day in milliseconds
}
or of course without the loop:
var dt = /* ...the start date... */;
var days = 4 - dt.getDay();
if (days < 0) {
days += 7;
}
dt.setTime(dt.getTime() + (days * 86400000));
If you have a Thursday already and you need to know the date for the next Thursday:
var nextThursday = new Date(thisThursday.getTime() + (86400000 * 7));

Categories

Resources