Display div based on remote timezone and dates - javascript

I'm trying to display a chat div that displays between the hours of 8am-6pm Monday to Friday "Online" or show nothing if offline, based on the Eastern Time Zone (NYC), so that customers from Beijing will see Online or Offline based on these hours.
Simply need to show() or hide() the div. So far I have the hours, but I'm not sure how to get them to be in relation to the user time-zone.
$(document).ready(function () {
var start = new Date();
var end = new Date();
var time = new Date().getTime();
if (time > start.setHours(8,00) && time < end.setHours(18,00)) {
$('.online').show();
}
else {
$('.offline').hide();
}
});

The previous answer (seen in edit history) was to use the offset from UTC, however that isn't going to be an option if you want to support Daylight Savings; which is an important thing to do.
As such, the modification to the previous suggestion completely removes the use of UTC. To support daylight savings, the only proper way to get the time from EST is going to be to set the locale to that location, read the time, set up a new date object (which will technically be set up in the client local, but all we really want from it are the day and hour response from the Date object so we will ignore that technicality).
This is done by passing an object with the toLocaleString call which specifies the timezone, and then constructing a new date with the result of that.
var NYDate = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
var NYHour = NYDate.getHours();
var NYDay = NYDate.getDay()
if (NYHour >= 8 && NYHour <= 18 &&
NYDay > 0 && NYDay < 6) {
$('.online').show();
}else {
$('.online').hide();
}
.online {
display: none;
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="online">Online</div>

No JavaScript needed. You should do this from the server side. (The customer doesn’t tell the store when it’s open, the store tells the customer!)
Assuming your HTML is being generated by some server-side language (PHP, Ruby, etc), set the program to use New York time, and simply calculate if you’re within the “open” times. If you’re open, generate the Chat div. if you’re closed... don’t.
(Or alternately, show/hide it via CSS and classes)

Turns out that this is not a completely trivial task using JavaScript (as noted in the answer from #StephenR, this may be easier to deal with server side). And as noted in some of the comments, using a library may be the better js approach.
That said, after thinking a bit about the comments from #RobG regarding varying browser support for options like timeZone in toLocaleString, I was curious what it would take to solve this another way (makes me grateful for the various js date libraries). Snippet below...
const getOffset = (month, date, day, hour) => {
// assume EST offset
let offset = 5;
// adjust to EST offset as needed
if ((month > 2 && month < 10) || (month === 2 && date > 14)) {
offset = 4;
} else if (month === 2 && date > 7 && date < 15) {
if ((day && date - day > 7) || (day === 0 && hour - offset >= 2)) {
offset = 4;
}
} else if (month === 10 && date < 8) {
if ((day && date - day < 0) || (day === 0 && hour - offset < 1)) {
offset = 4;
}
}
return offset;
};
const isOnline = () => {
const dt = new Date(); // current datetime
let year = dt.getUTCFullYear(); // utc year
let month = dt.getUTCMonth(); // utc month (jan is 0)
let date = dt.getUTCDate(); // utc date
let hour = dt.getUTCHours(); // utc hours (midnight is 0)
let day = dt.getUTCDay(); // utc weekday (sunday is 0)
let offset = getOffset(month, date, day, hour);
if (hour - offset < 0) {
hour = 24 + hour - offset;
day = day ? day - 1 : 6;
if (date === 1) {
if (!month) {
year -= 1;
month = 11;
} else {
month -= 1;
}
date = new Date(year, month + 1, 0).getDate();
} else {
date -= 1;
}
} else {
hour -= offset;
}
if (day > 0 && day < 6 && hour > 7 && hour < 19) {
return true;
}
return false;
};
if (isOnline()) {
console.log('online'); // handle online
} else {
console.log('offline'); // handle offline
}

Related

Changing Dates so They Are Within Business Hours

In a JavaScript step in Pentaho Data Integration, I want calculate the time in hours which passes between one date and another.
After following along with this this blog post, I realize that I need to adjust the startDate and endDate values in the function below which fall outside business hours so that they're within business hours so the function doesn't return zero. The dates are in the format 09/27/2018 18:54:55.
Here's my attempt so far:
var Approve_Gap;
var created_at_copy;
var approved_at_copy1;
// Function that accepts two parameters and calculates
// the number of hours worked within that range
function workingHoursBetweenDates(startDate, endDate) {
// Store minutes worked
var minutesWorked = 0;
// Validate input
if (endDate < startDate) { return 0; }
// Loop from your Start to End dates (by hour)
var current = startDate;
// Define work range
var workHoursStart = 8;
var workHoursEnd = 17;
var includeWeekends = true;
// bring dates into business hours
if(current.getHours() > workHoursEnd) {
current = current - (current.getHours() - workHoursEnd);
}
else if(current.getHours() < workHoursStart) {
current = current + (workHoursStart - current.getHours())
}
if(endDate.getHours() > workHoursEnd) {
endDate = endDate - (endDate.getHours() - workHoursEnd);
}
else if(endDate.getHours() < workHoursStart) {
endDate = endDate + (workHoursStart - endDate.getHours())
}
// Loop while currentDate is less than end Date (by minutes)
while(current <= endDate){
// Is the current time within a work day (and if it
// occurs on a weekend or not)
if(current.getHours() >= workHoursStart && current.getHours() < workHoursEnd && (includeWeekends ? current.getDay() !== 0 && current.getDay() !== 6 : true)){
minutesWorked++;
}
// Increment current time
current.setTime(current.getTime() + 1000 * 60);
}
// Return the number of hours
return minutesWorked / 60;
}
Approve_Gap = workingHoursBetweenDates(created_at_copy, approved_at_copy1);
I got the dates into business hours by adjusting copies of the dates as shown below:
if(created_at_copy.getHours() >= workHoursEnd) {
created_at_copy.setDate(created_at_copy.getDate() + 1);
created_at_copy.setHours(8);
created_at_copy.setMinutes(0);
created_at_copy.setSeconds(0);
} else if(created_at_copy.getHours() < workHoursStart) {
created_at_copy.setHours(8);
created_at_copy.setMinutes(0);
created_at_copy.setSeconds(0);
}
if(approved_at_copy1.getHours() >= (workHoursEnd)) {
approved_at_copy1.setDate(approved_at_copy1.getDate() + 1);
approved_at_copy1.setHours(8);
approved_at_copy1.setMinutes(0);
created_at_copy.setSeconds(0);
} else if(approved_at_copy1.getHours() < workHoursStart) {
approved_at_copy1.setHours(8);
approved_at_copy1.setMinutes(0);
created_at_copy.setSeconds(0);
}

round carbon date to closest previous 6 hour mark

i have an application that executes a cron job every 6 hours:
00:00, 06:00, 12:00, 18:00
How do i round the current time to the lowest matching hour of the above?
So if its 13:05 now, it should return 12:00
edit: i meant in javascript, not in php. updated my question
You can use this function and it is without moment.js
function getRoundedTime(){
var d = new Date();
var now = d.getHours();
if(now > 6){
var roundedTime = now - (now % 6);
var stringTime = roundedTime.toString().concat(":00");
return stringTime;
}
if(now < 6){
return "00:00";
}
if(now % 6 === 0) {
return "0" + now.toString().concat(":00");
}
}
getRoundedTime();
Or if you want moment.js then import moment and inside function declare now like this var now = moment().hour();

How to calculate month from number of days in JavaScript

So basically I have done a calculation that increments a clock time:
function Clock(year,month,day,hours,minutes,seconds){
if(seconds !== null){
this.seconds = seconds;
}
if(minutes !== null){
this.minutes = minutes;
}
if(hours !== null){
this.hours = hours;
}
if(day !== null){
this.day = day;
}
if(month !== null){
this.month = month;
}
if(year !== null){
this.year = year;
}
}
function incrementClock(){
clock.seconds++;
if (clock.seconds >=60) {
clock.seconds = 0;
clock.minutes++;
if (clock.minutes >=60) {
clock.minutes = 0;
clock.hours++;
if (clock.hours >=24) {
clock.hours = 0;
clock.days++;
}
}
}
}
function showClock(){
//prints clock in format yyyy/mm/dd hh:mm:ss
}
This would increment the seconds, minutes, hours and days accordingly...
So if I call print the clock each second it would look like this:
var c = new Clock(2014,04,01,12,13,01);
showClock();
2014/4/1 12:13:1
I get stuck on the month part...
My question is how would I go about checking if a month has passed as there are different amount of days each month?
EDIT
I am creating my own minified Date function... so please don't recommend using Date objects as I am trying to implement my own
Is this what you're looking for?
function incrementClock(){
clock.seconds++;
if (clock.seconds >=60) {
clock.seconds = 0;
clock.minutes++;
if (clock.minutes >=60) {
clock.minutes = 0;
clock.hours++;
if (clock.hours >=24) {
clock.hours = 0;
clock.days++;
var months = [31,((clock.year%4==0)&&((clock.year%100!=0)||(clock.year%400==0)))?29:28,31,30,31,30,31,31,30,31,30,31];
if (clock.days>months[clock.month-1]){
clock.days = 0;
clock.months++;
}
}
}
}
}
This line:
var months = [31,((clock.year%4==0)&&((clock.year%100!=0)||(clock.year%400==0)))?29:28,31,30,31,30,31,31,30,31,30,31];
creates an array of the months and the days in each month. Thus it is easy to determine the amount of days per month like so:
days_in_jan = months[0]
days_in_feb = months[1]
...
days_in_dec = months[11]
You don't. You don't increment anything actually. If you want your own clock, that's fine, but you still need to access the current time using a Date object, so when you want to know how much time has elapsed, get a new Date object and figure it out:
pseudo structure:
Class Clock
- start date
- function timeElapsed
- elapsed = now - start date
In that function, compare the month, day, etc.
And honestly, if you don't like that answer you're on your own, as the answer to "how do I do this random thing as purely a thought exercise" is exactly that -- a thought exercise. There's no real point to it, so it shouldn't be asked or answered on SO.
As others have done, I would suggest using the Date object, or a date library like MomentJS, but it seems like you want to do the implementation yourself as an exercise. In that case, your code will need to know how many days are in each month if it is going to do the calculation correctly. Consider including in your code an array of the months' lengths:
var monthLengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
You'll also need a function to determine whether or not it's a leap year:
function isLeapYear(year) {
return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}
Armed with those, you should be able to tell if a date has exceeded its month by checking the array to know how many days are in that month, and (if it's February) using the leap year function to determine if you should count 29 days for February.

Javascript Time Comparisons

I have two issues I need to solve using javascript or jQuery.
1) I need to test whether the current time falls between 7am and 7pm.
var now = new Date();
if (now >= *7am* && now < *7pm*){} else {}
2) On document load, I need a function to run everyday at 7am and 7pm.
Any help is appreciated.
Resolved part 2 by running a time check every 15 minutes.
var checkTime = setInterval(myFunction(), 900000);
You can use var currentHour = (new Date()).getHours(); to retrieve the specific hour as an integer between 0 and 23, according to the local timezone of your environment:
var currentHour = (new Date()).getHours();
if (currentHour >= 7 && currentHour < 19) { /* stuff */ } else { /* other stuff }
If you need to get UTC, there is the .getUTCHours() method.
The documentation has more information if you're interested: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours
Look at Date.getHours
$(function(){
var now = new Date();
var hours = now.getHours();
if (hours >= 7 && now < hours < 19){} else {}
});

Will this JS time code work? Can I make it better?

I'm displaying a message between Saturday at 6pm and Sunday 4am. The last time I had to do this it didn't work because I didn't take into account UTC time going negative when changing it to NYC time.
I am doing the math right (displaying at the appropriate times)?Should I put the UTC conversion code into its own function? Is this the worst js you've ever seen?
-- jquery is called --
$(document).ready(function() {
var dayTime = new Date();
var day = dayTime.getUTCDay();
var hour = dayTime.getUTCHours();
//alert(day.toString()+" "+hour.toString());
if (hour >= 5){
hour = hour-5;
}
else{
hour = hour+19;
if(day > 0){
day--;
}
else{
day = 6;
}
}
//alert(day.toString()+" "+hour.toString());
if ((day == 6 && hour >= 18) || (day == 0 && hour < 4)){
}
else{
$('#warning').hide(); //Want this message to show if js is disabled as well
}
});
Why do you even need that UTC stuff? Just work with local time:
var day = dayTime.getDay();
var hour = dayTime.getHours();
And you can clean up that conditional a bit too:
if (!(day == 6 && hour >= 18) && !(day == 0 && hour < 4)) {
$('#warning').hide();
}
This should get you your server's time:
var dayTime = new Date();
localOffset = dayTime.getTimezoneOffset() * 60000;
serverOffset = 5 * 60 * 60000;
dayTime = new Date(dayTime.getTime() + (localOffset - serverOffset));
Play around with that "5" in the server offset; it's the hours. It may need to be a -5; I'm not really sure.
Also, that's going to break every daylight savings. You'll have to detect that somehow and modify serverOffset.

Categories