UTC live clock, not working with negative timezone - javascript

In my application, I need to create live clock according to different timezones which are stored into database.
I have almost succeeded it.
But now I'm facing negative time in clock, and I'm out of ideas to figure out a solution.
I'm getting UTC time with the help of new Date() and calculating time with provided timezone from database.
Case 1: 0:31 (UTC time) + 5:30 (timezone) = '06:01'
Case 2: 06:31 (UTC time) - 6:30 (timezone) = '00:01'
Case 3: 5:0 (UTC time) - 7:0 (timezone) = '-02:00'
Case 1 and 2 is working properly but I'm getting negative value in 3rd case which is wrong.
I have tried to add comments in code to have better understanding of what I'm doing here. I hope it helps.
Any help will be highly appreciated.
function runClock() {
setInterval(function() {
//debugger
var time = new Date();
// take timezone from HTML element
// ex: +:5:30
var getTimezone = "-:7:0" //$("#timeZone").text();
// split into array to get oparator (Positive and Negative Timezone)
var oparator = getTimezone.split(":")[0];
var timezone = getTimezone.split(":")[1] + ":" + getTimezone.split(":")[2];
// get UTC hours
var hours = 5 //time.getUTCHours();
var minutes = 0 //time.getUTCMinutes();
var UTCTIME = timeStringToFloat(hours + ":" + minutes);
var TIMEZONEOFFSETTIME = timeStringToFloat(timezone);
var finalTime = "";
// Convert time folloed by Colon into decimals
// ex: 1:45 = 1.75
function timeStringToFloat(time) {
var hoursMinutes = time.split(/[.:]/);
var hh = parseInt(hoursMinutes[0], 10);
var mm = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
return hh + mm / 60;
}
// Convert time folloed by float into Colon
// ex: 1.75 = 1:45
function floatToTime(FT) {
var splittedTime = FT.toString().split(".");
var hh = splittedTime[0];
var mm = "";
if (splittedTime[1]) {
mm = Math.round((splittedTime[1] / 100) * 60);
} else {
mm = "0";
}
finalTime = hh + ":" + ((mm < 10) ? ("0" + mm) : mm);
}
// Calculate time (UTC + or - Timezone)
// Ex: 00:15 (UTC) + 5:30 = 5:45
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
}
}
// Parse Seconds
function seconds() {
var j = "";
if (time.getUTCSeconds() < 10) {
j = "0" + time.getUTCSeconds();
} else {
j = time.getUTCSeconds()
}
return j;
}
CalcTime(UTCTIME, TIMEZONEOFFSETTIME);
$("#clockTime").text(finalTime + ":" + seconds());
}, 1000);
}
runClock();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<b id="clockTime"></b>

You should just be "looping back" to 23:59 when you go negative. You can just add something to check if it goes negative then just re-add the missing time:
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME;
// Offset any negative times;
if (FT < 0) {
FT += 24;
}
FT = FT.toFixed(2);
floatToTime(FT);
}
}
But ideally you really don't want to be handling these kinds of Timezone issues as other libraries are already handling it, i.e. moment.js
function runClock() {
setInterval(function() {
//debugger
var time = new Date();
// take timezone from HTML element
// ex: +:5:30
var getTimezone = "-:7:0" //$("#timeZone").text();
// split into array to get oparator (Positive and Negative Timezone)
var oparator = getTimezone.split(":")[0];
var timezone = getTimezone.split(":")[1] + ":" + getTimezone.split(":")[2];
// get UTC hours
var hours = 5 //time.getUTCHours();
var minutes = 0 //time.getUTCMinutes();
var UTCTIME = timeStringToFloat(hours + ":" + minutes);
var TIMEZONEOFFSETTIME = timeStringToFloat(timezone);
var finalTime = "";
// Convert time folloed by Colon into decimals
// ex: 1:45 = 1.75
function timeStringToFloat(time) {
var hoursMinutes = time.split(/[.:]/);
var hh = parseInt(hoursMinutes[0], 10);
var mm = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
return hh + mm / 60;
}
// Convert time folloed by float into Colon
// ex: 1.75 = 1:45
function floatToTime(FT) {
var splittedTime = FT.toString().split(".");
var hh = splittedTime[0];
var mm = "";
if (splittedTime[1]) {
mm = Math.round((splittedTime[1] / 100) * 60);
} else {
mm = "0";
}
finalTime = hh + ":" + ((mm < 10) ? ("0" + mm) : mm);
}
// Calculate time (UTC + or - Timezone)
// Ex: 00:15 (UTC) + 5:30 = 5:45
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME;
// Offset any negative times;
if (FT < 0) {
FT += 24;
}
FT = FT.toFixed(2);
floatToTime(FT);
}
}
// Parse Seconds
function seconds() {
var j = "";
if (time.getUTCSeconds() < 10) {
j = "0" + time.getUTCSeconds();
} else {
j = time.getUTCSeconds()
}
return j;
}
CalcTime(UTCTIME, TIMEZONEOFFSETTIME);
$("#clockTime").text(finalTime + ":" + seconds());
}, 1000);
}
runClock();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<b id="clockTime"></b>

You want to recover/display the time for a given timezone offset? Unless you like doing this for a hobby, stay away from string methods and use the date functions, no?
var offsetMS = -5.5 * 3600000
var myDate = new Date()
var dateWithOffset = new Date( myDate.getTime() + offsetMS )
var formatted = dateWithOffset.toLocaleString("en-GB",{timeZone:"UTC",hour:"numeric",minute:"numeric"})
console.log(formatted)
Even manipulating timezone offset directly is to be avoided. If you can, use toLocaleString with a real timezone name, then issues like daylight saving will be handled for you. Modern browsers support all iana timezones, so let them do the work.

Add 24 to your FT value and take division remain of 24:
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME + 24;
FT = FT % 24;
}
FT = FT.toFixed(2);
floatToTime(FT);
}
Working sample: https://codepen.io/anon/pen/VqQqoo

If you do not want to use a library like moment.js that comes with time zone handling and simply need to add/subtract hours from a given date, how about converting them to a common time unit and operating on that?
const timezoneString = '-:12:30';
const parts = timezoneString.split(':');
const timezone = (parts[0] === '-' ? -1 : 1) * (parseInt(parts[1]) + (parseInt(parts[2]) / 60.0));
const timeZoneMillis = timezone * 3600 * 1000;
const now = new Date();
const inZone = new Date(now.getTime() + timeZoneMillis);
console.log(now, inZone);
Something like this would convert them to a millisecond timestamp and subtract that many hours and convert it back to a date.

Related

Get System time, localstorage, compare dates and performe an action

I need to get the system time once, then store it on localStorage, then compare this stored value with a further system date and then perform an action if the future date is equal or greater than the one which is stored. I have tried but I am stucked in making the function which gets the system time the first time to run only once so I can get a future date to compare.
This is my code
console.log(formatTime());
function formatTime() {
var date = new Date();
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
var ampm = hours >= 12 ? "PM" : "AM";
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
minutes = minutes < 10 ? "0" + minutes : minutes;
return (strTime = date.getDay() + "/" + date.getMonth() + "/" + date.getFullYear() + " " + hours + ":" + minutes + ":" + seconds + " " + ampm);
}
document.getElementById("currentdt").innerHTML = strTime;
var strTime1 = formatTime();
var timeString = JSON.stringify(strTime1);
localStorage.setItem("strTime1", timeString);
var timeStringFromLocalStorage = localStorage.getItem("strTime1");
var timeFromLocalStorage = JSON.parse(timeStringFromLocalStorage);
document.getElementById("time").innerHTML = strTime1;
console.log(timeStringFromLocalStorage);
function compare(dateTimeA, dateTimeB) {
var momentA = moment(dateTimeA, "strTime1");
var momentB = moment(dateTimeB, "strTime");
if (momentA > momentB) return 1;
else if (momentA < momentB) return -1;
else return 0;
}
alert(compare("strTime1", "strTime"));
The function below will check if there has been a value set in localStorage. If there is no value set, it will set its first and stop the function.
If there is a value, then it will be turned into a moment instance and compared with the current date. If a difference in days is equal or larger to than specified it will redirect the page.
function redirectWhenOlderThan(days, url) {
const storedValue = localStorage.getItem('first-visit');
const now = moment();
/**
* If nothing is stored yet, then storedValue will be null.
* Here you will set the first localStorage item for the first time.
* Instead of a full date, store the timestamp.
* Then stop the function.
*/
if (storedValue === null) {
localStorage.setItem('first-visit', now.valueOf().toString());
return;
}
/**
* If there is a stored value then it will be a timestamp as a string.
* First parse it into a number before putting it into moment.
* Then check the difference in days between the dates.
*/
const then = moment(Number(storedValue));
const difference = now.diff(then, 'days');
/**
* If the difference is higher or equal to the given days, redirect.
*/
if (difference >= days) {
location.href = url;
}
}
Call the function with amount of days that should have passed since the first visit and the URL to redirect to.
redirectWhenOlderThan(15, 'https://example.com');
I hope this is what you meant.
Sidenote: dive into moment.js if you have the time. It has a lot of features that could spare you some time, like your formatTime() function, it can be written in a single line with moment.
moment().format('DD/MM/YYYY h:mm:ss A');
Now the final code goes like this
function formatTime() {
var date = new Date();
return strTime = date.getDay() + '/' + date.getMonth()+'/'+date.getFullYear();
}
document.getElementById("currentdt").innerHTML = strTime;
function redirectWhenOlderThan(days, url) {
const storedValue = localStorage.getItem('first-visit');
const now = moment();
if (storedValue === null) {
localStorage.setItem('first-visit', now.valueOf().toString());
return;
}
const then = moment(Number(storedValue));
const difference = now.diff(then, 'days');
if (difference >= days) {
location.href = url;
}
else {
window.location.href= 'app/phr.html';
}
}
setTimeout(function () {
redirectWhenOlderThan(1, 'app/licences.html');
}, 3000);

How to convert UTC to CST using Javascript or Jquery

I would like to convert the below time to CST. How can I achieve it using Jquery or Javascript? It should always display as a CST timezone.
var date = new Date();
var dd = date.getDate();
var mm = date.getMonth() + 1;
var yy = date.getFullYear();
var hh = date.getHours();
var minutes = date.getMinutes();
if (minutes < 10)
minutes = "0" + minutes;
var suffix = "AM";
if (hh >= 12) {
suffix = "PM";
hh = hh - 12;
}
if (hh == 0) {
hh = 12;
}
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
var valsss = (mm) + "/" + dd + "/" + yy + hh + " " + ":" + minutes + " " + suffix;
$("#printDate").text(valsss);
<p id= "#printDate"></p>
Please check this below like can convert
d = new Date();
localTime = d.getTime();
localOffset = d.getTimezoneOffset() * 60000;
utc = localTime + localOffset;
offset = -5;
cst = utc + (3600000 * offset);
nd = new Date(cst);
newdate = (nd.toLocaleString());
$('#printDate').text(newdate + ' CST');
You have to consider that the browser will change the displayed date to the user's timezone. I wrote this to grab a date in a kendo grid by a class on a td and set it to CST. In this case the server is in CST and I wanted the time say 12:00 to display as 12:00 for a user in MST not as 11:00 in MST. Hope it helps...
Checks User / Browser's timezone offset.
Get difference in hours from server timezone offset.
Looks at a column on the Kendo Grid with class .dbDate.
Grabs the grid date (displayedTime).
Uses Moment.js to Convert (convertedTime) it based on the difference (diff)
in hours we pass it.
Formats convertedTime to the desired format i.e. 02/08/18 23:57.
Passes the Grid back the updated date and time.
Must Run Last on load.
function dateOffset() {
var date = new Date();
var offset;
var diff;
offset = date.getTimezoneOffset()
if (offset > 360) { //360 = CST
diff = +(offset - 360) / 60
} else if (offset < 360) {
diff = -(360 - offset) / 60
} else {
diff = 0
}
$(".dbDate").each(function (i) {
var grid = $('#Grid').data('kendoGrid');
var displayedTime = grid.dataSource.data()[i].TicketDateTime
var convertedTime = new moment(displayedTime).add(diff, 'hours').toDate();
var originalTime = moment(convertedTime).format("MM/DD/YY HH:mm");
i + 1
$(this).html(originalTime)
})
}

JS/TypeScript Generate times between hours

So let's say we have two times:
7:30 - 12:00
So my question is how can I generate an array with times like this:
7:30, 8:00, 8:30, 9:00, 9:30, 10:00, 10:30, 11:00, 11:30
I need this for a booking, so let's say the business will open at 7:30 and every booking that you can make will be 30 min(this time can change, could be one hour or more)
Whats the best way to generate something like this in JS?
Little verbose utility, you can use it..
var getTimeIntervals = function (time1, time2, slotInMinutes, workingHourStart, workingHourEnd) {
time1.setMinutes(0); time1.setSeconds(0);
var arr = [];
var workingHoursStart = workingHourStart;
var workingHourEnds = workingHourEnd;
var workingHourStartFloat = parseFloat("7:30");
var workingHourEndFloat = parseFloat("12:00");
while(time1 < time2){
var generatedSlot = time1.toTimeString().substring(0,5);
var generatedSlotFloat = parseFloat(generatedSlot);
time1.setMinutes(time1.getMinutes() + slotInMinutes);
if(generatedSlotFloat >= workingHourStartFloat && generatedSlotFloat < workingHourEndFloat){
var generatedObject = {
slot: time1.toTimeString().substring(0,5),
timeStamp: new Date(time1.getTime())
};
arr.push(generatedObject);
}
}
return arr;
}
var today = new Date();
var tomrorow = new Date().setDate(today.getDate()+1);
console.log(getTimeIntervals(today, tomorrow, 30, "7:30", "12:00"));
Function getTimeIntervals expects startDate, endDate, slotDurationInMinutes, workingHoursStart and workingHourEnd.
Why I am returning object is because you may need the timestamp of selected slot in your further application use.
Fiddle - https://jsfiddle.net/rahulrulez/t8ezfj2q/
As the comment in the code says, you can remove the 0 before the hours if you don't want it, by removing that line.
If you don't want the end in the array just replace the <= by <in the for loop
function timeArray(start, end){
var start = start.split(":");
var end = end.split(":");
start = parseInt(start[0]) * 60 + parseInt(start[1]);
end = parseInt(end[0]) * 60 + parseInt(end[1]);
var result = [];
for ( time = start; time <= end; time+=30){
result.push( timeString(time));
}
return result;
}
function timeString(time){
var hours = Math.floor(time / 60);
var minutes = time % 60;
if (hours < 10) hours = "0" + hours; //optional
if (minutes < 10) minutes = "0" + minutes;
return hours + ":" + minutes;
}
console.log(timeArray("7:30", "12:00"));
A shorter version:
timeArray = [];
....
let i = 0;
let hour = 8;
let odd: boolean;
do {
odd = false;
if (i % 2 === 0) {
odd = true;
hour--;
}
this.timeArray.push(hour.toString() + (odd ? ":30" : ":00"));
i++;
hour++;
} while (i < 12);
....
Demo

Find time difference of 24 hr format

How do I get the time difference of two values of 24hr format?
For example
var time1 = 22:30:00,
time2 = 06:30:00;
Difference should come as 08:00:00
You are much better off to do this type of maths with full date objects, otherwise you have to make guesses about the time values such as if the finish is less that the start, it must be on the next day.
The following includes a couple of helper functions and a main function to get the difference.
// Convert h:m:s to seconds
function hmsToSecs(s) {
var b = s.split(':');
return b[0]*3.6e3 + b[1]*60 + +b[2];
}
// Convert seconds to hh:mm:ss
function secsToHMS(n) {
function z(n){return (n<10? '0':'') + n;}
var sign = n < 0? '-' : '';
n = Math.abs(n);
return sign + z(n/3.6e3|0) + ':' + z(n%3.6e3/60|0) + ':' + z(n%60);
}
// Calculate time difference between two times
// start and finish in hh:mm:ss
// If finish is less than start, assume it's the following day
function timeDiff(start, finish) {
var s = hmsToSecs(start);
var f = hmsToSecs(finish);
// If finish is less than start, assume is next day
// so add 24hr worth of seconds
if (f < s) f += 8.64e4;
return secsToHMS(f - s);
}
console.log(timeDiff('22:30:00','06:30:00')); // 08:00:00
console.log(timeDiff('06:30:00','22:30:00')); // 16:00:00
Using full date objects, you can do:
var start = new Date(2014,5,5,22,30); // 22:30:00 on 5 June 2014
var finish = new Date(2014,5,6,6,30); // 06:30:00 on 6 June 2014
// Subtract dates to get difference in ms, convert to seconds and format
console.log(secsToHMS((finish - start)/1000)); // 08:00:00
console.log(secsToHMS((start - finish)/1000)); // -08:00:00
I Suggest that you should use jquery date.js library and then you can use its Timespan class like below:
var future = Date.parseExact("22:30:00", "hh:mm:ss");
var past = Date.parseExact("06:30:00", "hh:mm:ss");
var span = new TimeSpan(future - now);
and your difference in hours is as below:
span.getHours() + ":" span.getMinutes() + ":" span.getSeconds()
If you want Diff function in C#;
DateTime oldDate= "06/01/2014 12:00:00 AM";
TimeSpan timeDiff = DateTime.Now - oldDate;
int diff =Convert.ToInt32(timeDiff.TotalHours);
if you want it in JavaScript thats a script block should help you;
function diffDateTime(startDT, endDT) {
if (typeof startDT == 'string' && startDT.match(/^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}[amp ]{0,3}$/i)) {
startDT = startDT.match(/^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}/);
startDT = startDT.toString().split(':');
var obstartDT = new Date();
obstartDT.setHours(startDT[0]);
obstartDT.setMinutes(startDT[1]);
obstartDT.setSeconds(startDT[2]);
}
else if (typeof startDT == 'string' && startDT.match(/^now$/i)) var obstartDT = new Date();
else if (typeof startDT == 'string' && startDT.match(/^tomorrow$/i)) {
var obstartDT = new Date();
obstartDT.setHours(24);
obstartDT.setMinutes(0);
obstartDT.setSeconds(1);
}
else var obstartDT = new Date(startDT);
if (typeof endDT == 'string' && endDT.match(/^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}[amp ]{0,3}$/i)) {
endDT = endDT.match(/^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}/);
endDT = endDT.toString().split(':');
var obendDT = new Date();
obendDT.setHours(endDT[0]);
obendDT.setMinutes(endDT[1]);
obendDT.setSeconds(endDT[2]);
}
else if (typeof endDT == 'string' && endDT.match(/^now$/i)) var obendDT = new Date();
else if (typeof endDT == 'string' && endDT.match(/^tomorrow$/i)) {
var obendDT = new Date();
obendDT.setHours(24);
obendDT.setMinutes(0);
obendDT.setSeconds(1);
}
else var obendDT = new Date(endDT);
var secondsDiff = (obendDT.getTime() - obstartDT.getTime()) > 0 ? (obendDT.getTime() - obstartDT.getTime()) / 1000 : (86400000 + obendDT.getTime() - obstartDT.getTime()) / 1000;
secondsDiff = Math.abs(Math.floor(secondsDiff));
var oDiff = {}; // object that will store data returned by this function
oDiff.days = Math.floor(secondsDiff / 86400);
oDiff.totalhours = Math.floor(secondsDiff / 3600); // total number of hours in difference
oDiff.totalmin = Math.floor(secondsDiff / 60); // total number of minutes in difference
oDiff.totalsec = secondsDiff; // total number of seconds in difference
secondsDiff -= oDiff.days * 86400;
oDiff.hours = Math.floor(secondsDiff / 3600); // number of hours after days
secondsDiff -= oDiff.hours * 3600;
oDiff.minutes = Math.floor(secondsDiff / 60); // number of minutes after hours
secondsDiff -= oDiff.minutes * 60;
oDiff.seconds = Math.floor(secondsDiff); // number of seconds after minutes
return oDiff;
}
usage;
var objDiff = diffDateTime('06/01/2014 12:00:00 AM', 'now');
var dtdiff = objDiff.days + ' days, ' + objDiff.hours + ' hours, ' + objDiff.minutes + ' minutes, ' + objDiff.seconds + ' seconds';
Important: You have to remember that DateTime format must be in en-US format dd/MM/yyyy hh:mm:ss.

Time Duration problem for 12 hrs format

I am getting the time duration correctly for 24 hrs format but for 12 hrs format I am getting error if i give 11:00 am to 1:00 pm. If I give 10:00 am to 11:00 am it will correctl and if I give 6:00 pm to 7:00 pm it will give correctly only in am to pm i m facing problem.
function autoChangeDuration() {
var diff1 = "00:00";
var start = document.getElementById("startTime").value;
var end = document.getElementById("endTime").value;
if (start > end) {
document.getElementById("duration").value = diff1;
} else {
var space1 = start.split(' ');
var space2 = end.split(' ');
s = space1[0].split(':');
e = space2[0].split(':');
var diff;
min = e[1] - s[1];
hour_carry = 0;
if (min < 0) {
min += 60;
hour_carry += 1;
}
hour = e[0] - s[0] - hour_carry;
diff = hour + ":" + min;
document.getElementById("duration").value = diff;
}
function toDate(s) {
// the date doesn't matter, as long as they're the same, since we'll
// just use them to compare. passing "10:20 pm" will yield 22:20.
return new Date("2010/01/01 " + s);
}
function toTimeString(diffInMs) {
// Math.max makes sure that you'll get '00:00' if start > end.
var diffInMinutes = Math.max(0, Math.floor(diffInMs / 1000 / 60));
var diffInHours = Math.max(0, Math.floor(diffInMinutes / 60));
diffInMinutes = diffInMinutes % 60;
return [
('0'+diffInHours).slice(-2),
('0'+diffInMinutes).slice(-2)
].join(':');
}
function autoChangeDuration()
{
var start = document.getElementById("startTime").value;
var end = document.getElementById("endTime").value;
start = toDate(start);
end = toDate(end);
var diff = (end - start);
document.getElementById("duration").value = toTimeString(diff);
}
Why don't you just use javascript's Date class?
http://www.w3schools.com/jsref/jsref_obj_date.asp

Categories

Resources