We are accessing an API that allows us to schedule date/time. We need to check scheduled things so we do NOT double book on the same hour. The API is returning a time as just HH in military. However, it is using UTC HH. So if we schedule something at 1PM it is coming back 18.
I am trying to use Moment.js to change the UTC 18 back to CST (local time). I am failing horribly.
In the example below I am getting 18 from the API and my function below tries to turn to local time (happens to be CST). But the function is just converting or leaving it to 18. Help?
function changeTakenHoursFromUTC (taken) {
if(taken) {
for (var i = 0, len = taken.length; i < len; i++) {
// construct a moment object with UTC-based input
var utchour = taken[i].send_hour + ":00:00";
console.log( "Hour before change " + utchour);
var h = moment.utc(utchour);
// convert using the TZDB identifier for US Central time
h.tz('America/Chicago');
h.local();
console.log( "Hour before change " + h._i );
var s = h.format("HH");
taken[i].send_hour = s._i;
console.log( "Taken hour back in taken is " + taken[i].send_hour );
count += 1;
if(i == len-1 && count > 0) {
//
return;
}
} // end for
} // end IF
} // end changeTakenHoursFromUTC
you are just missing a format string in your moment.utc(utchour, "HH")
I created this function to kind of help as an example:
function changeTakenHoursFromUTC (taken) {
// construct a moment object with UTC-based input
console.log( "Hour before change " + taken);
var h = moment.utc(taken, "HH");
console.log(h.format("HH"));
h.local();
console.log( "Hour after change " + h.format("HH"));
}
changeTakenHoursFromUTC(18);
Related
Environment: Win 10 Pro, Chrome 85, luxon 1.25.0
What I am trying to achieve eventually is this: in an ASP.Net/c# application show to the user continuously the amount of time until a session time out will occur. Because server and client may be in different time zones I need the UTC offset of each. The client's offset is easy to get. To find the server's offset (with reference to the code snippet below): the server code puts the page last loaded time into lblLastLoaded. Object dto receives the parsed date parts, including dto.offset which, I gather, is supposed to be expressed in minutes. The subsequent call to luxon.DateTime.fromObject(dto) fails: pst is left undefined. When I do not set dto.offset (by commenting out 4 lines in the code below) pst gets the server time successfully, but without the offset; it appears that luxon uses the offset of my local system which is -7 hours.
<script>
function r4onload() {
// Get server time:
var st = document.getElementById('lblLastLoaded').innerHTML;
// Date Time Offset
// st has form YYYY/MM/dd HH:mm:ss -HH:mm
// 1 2
// 012345678901234567890123456
// For Example 2020/09/29 10:31:56 -07:00
let dto = {};
dto.year = Number(st.substring(0, 4));
dto.month = Number(st.substring(5, 7));
dto.day = Number(st.substring(8, 10));
dto.hour = Number(st.substring(11, 13));
dto.minute = Number(st.substring(14, 16));
var offsetHour = Number(st.substring(20, 23)); // works if these 4 lines are commented out
var offsetMinutes = Number(st.substring(24, 26)); // works if these 4 lines are commented out
dto.offset = offsetHour * 60 + Math.sign(offsetHour) * offsetMinutes; // works if these 4 lines are commented out
// dto.offset is correctly calculated to -420 minutes // works if these 4 lines are commented out
var pst = luxon.DateTime.fromObject(dto);
// pst is undefined at this point -- why??
// If I do not include anything about offset above (comment out the 4 lines
// containing offsetHours, offsetMinutes, and dto.Offset, then pst comes out like this:
// 2020-09-29T10:31:00.00000-07:00
// i.e., luxon used the offset -07:00 of my local system, not the one contained in variable st.
document.getElementById('Parsed').innerHTML = pst;
r4startTime();
}
function r4startTime() {
var dt = luxon.DateTime.local();
var h = dt.hour;
var m = dt.minute;
var s = dt.second;
m = r4checkTime(m);
s = r4checkTime(s);
document.getElementById('CurrTime').innerHTML =
h + ":" + m + ":" + s;
var t = setTimeout(r4startTime, 2000);
}
function r4checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
A complete Visual Studio 2017 project DemoLuxon with the above code snippet in file Site.Master is here: https://1drv.ms/u/s!AvoFL8QrGVaTsQvbaB8-Zh7GdloV?e=ODjZW5
If the above approach is awkward, I would be grateful for suggestions of more elegant ways of determining the client/server offset difference.
I devised a workaround as follows below, but the original problem has not been answered:
<script>
function r4onload() {
var st = document.getElementById('lblLastLoaded').innerHTML;
// Date Time Offset
// st has form YYYY/MM/dd HH:mm:ss -HH:mm
// 1 2
// 012345678901234567890123456
// For Example 2020/09/29 10:31:56 -07:00
// Transform to ISO format:
st = st.substring(0, 4) + '-' + st.substring(5, 7) + '-' + st.substring(8, 10)
+ 'T' + st.substring(11, 19) + ".000" + st.substring(20);
document.getElementById('Xformed').innerHTML = st;
var pst = luxon.DateTime.fromISO(st, { setZone: true });
document.getElementById('Parsed').innerHTML = pst;
r4startTime();
}
function r4startTime() {
var dt = luxon.DateTime.local();
var h = dt.hour;
var m = dt.minute;
var s = dt.second;
m = r4checkTime(m);
s = r4checkTime(s);
document.getElementById('CurrTime').innerHTML =
h + ":" + m + ":" + s;
var t = setTimeout(r4startTime, 2000);
}
function r4checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
i.e., put the date-time first into ISO format and then use luxon.DateTime.fromISO. Variable pst gets the correct date-time value including the offset. The problem with luxon.DateTime.fromObject with an offset remains unresolved.
I have a variable that stores a time value.
var cabtime = ["09:30:00"];
Variable time value is in 24-hour clock. That means 02:30:0PM will come as 14:30:00.
I want to check if the variable time falls under 08:00AM to 10:00AM window. If yes then I'll do an action.
Any pointers in this regard?
You could parse the time into seconds since midnight using:
var cabtime = ["HH:MM:SS"] // in 24hr time
function parseTime (string) {
parts = string.split(':').map(x => parseInt(x))
seconds = parts[0] * 3600 + parts[1] * 60 + parts[0]
return seconds
}
Then you can parse the time and the upper/lower bounds, and test using:
time = parseTime(cabtime[0])
lower = parseTime('08:00:00')
upper = parseTime('10:00:00')
if (time >= lower && time <= upper) {
print('Inside the range')
}
You can solve it easily by converting your strings to Date objects and compare them than.
var cabtime = ["09:30"];
function checkTimeRange(time, from, to, reldate) {
if (undefined === reldate) {
reldate = '0000T'; // the date the time strings are related to
}
let dtime = new Date(reldate + time);
let dfrom = new Date(reldate + from);
let dto = new Date(reldate + to);
return dfrom <= dtime && dtime <= dto;
}
checkTimeRange(cabtime[0], '08:00', '10:00'); // returns true
If you have full dates (e.g. '2019-07-25T09:30:00') instead of just the clock time you should provide for the parameter `reldate' an empty string.
* update: changed the wrong date format to standard format
* update: changed the date format again to be more fancy
I need to do the simplest thing, take an input date/time and write out the hours:minutes:seconds until that time. I haven't been able to figure it out. I even tried using Datejs which is great, but doesn't seem to have this functionality built in.
The time is going to be somewhere in the range of 0 mins -> 20 minutes
Thanks!
Don't bother with a library for something so simple. You must know the format of the input date string whether you use a library or not, so presuming ISO8601 (like 2013-02-08T08:34:15Z) you can do something like:
// Convert string in ISO8601 format to date object
// e.g. 2013-02-08T02:40:00Z
//
function isoToObj(s) {
var b = s.split(/[-TZ:]/i);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5]));
}
function timeToGo(s) {
// Utility to add leading zero
function z(n) {
return (n < 10? '0' : '') + n;
}
// Convert string to date object
var d = isoToObj(s);
var diff = d - new Date();
// Allow for previous times
var sign = diff < 0? '-' : '';
diff = Math.abs(diff);
// Get time components
var hours = diff/3.6e6 | 0;
var mins = diff%3.6e6 / 6e4 | 0;
var secs = Math.round(diff%6e4 / 1e3);
// Return formatted string
return sign + z(hours) + ':' + z(mins) + ':' + z(secs);
}
You may need to play with the function that converts the string to a date, but not much. You should be providing a UTC timestring anyway, unless you can be certain that the local time of the client is set to the timezone of the supplied datetime value.
Instead of Date.js, try Moment.js.
I followed this tutorial, but I wanted to just be able to set a date and have it countdown to that date.
Even so, it would just base it off my computer's time; how can I make it so it's standard for everyone?
He mentioned setUTCDate() but I have no idea how to implement it?
Here's some code to get you started. It gets the UTC time and alert's it, formatted:
// By default, JS does not pad times with zeros
function checkTime(i) {
if(i<10) i='0'+i;
return i;
}
// Set current UTC time
var d = new Date();
var now = checkTime(d.getUTCHours()) + ':' +
checkTime(d.getUTCMinutes()) + ':' +
checkTime(d.getUTCSeconds());
// Output
alert(now);
Here's a JSFiddle.
Remember: UTC != GMT (read on if you want this to always match the UK time).
BST (when the clocks go forward) will need to be factored in for anyone in the UK wanting to use this solution.
Here's a function I wrote earlier:
// Function returning 0 or 1 depending on whether BST is in effect
function isBSTinEffect()
{
var d = new Date();
// Loop over the 31 days of March for the current year
for(var i=31; i>0; i--)
{
var tmp = new Date(d.getFullYear(), 2, i);
if(tmp.getDay() == 0) { lSoM = tmp; break; }
}
// Loop over the 31 days of October for the current year
for(var i=31; i>0; i--)
{
var tmp = new Date(d.getFullYear(), 9, i);
if(tmp.getDay() == 0) { lSoO = tmp; break; }
}
if(d < lSoM || d > lSoO) return 0;
else return 1;
}
To factor in BST, put that function before // Set current UTC time and change checkTime(d.getUTCHours()) to checkTime(d.getUTCHours()+isBSTinEffect())
So I am storing times as '01:30:00'. I have a start time and a date time dropdown. I want the dropdown to be set to the start time + 1hr. Is there a way to add the time via javascript or jquery?
Here's my current code:
$(".start_time").change(function(){
$(".end_time").val($(this).val());
});
Try this:
find the selected index of the start time
bump it up by 2 to find your end time index (given that you've got half hour increments)
use the mod operator % to wrap back to index 0 or 1 (for 00:00 and 00:30 respectively)
$(".start_time").change(function(){
var sel =$(this).attr('selectedIndex');
var endIdx = (sel + 2) % 48; // 47 is 23:30, so 48 should go back to index 0
$(".end_time").attr('selectedIndex', endIdx);
});
Try it out on JSBin.
There are two separate problems here: the first is parsing out the time from your .start_time input, and the second is incrementing it to be an hour later.
The first is really a string-manipulation exercise. Once you have parsed out the pieces of the string, e.g. via a regex, you could either turn them into a Date instance and use setHours, or you could just manipulate the components as numbers and them reassemble them into a string in the format you desire.
An example of this might be as follows:
var TIME_PARSING_REGEX = /([0-9]{2}):([0-9]{2}):([0-9]{2})/;
function padToTwoDigits(number) {
return (number < 10 ? "0" : "") + number;
}
$(".start_time").change(function () {
var stringTime = $(this).val();
var regexResults = TIME_PARSING_REGEX.exec(stringTime);
var hours = parseInt(regexResults[1], 10);
var newHours = (hours + 1) % 24;
var newHoursString = padToTwoDigits(newHours);
var minutesString = regexResults[2];
var secondsString = regexResults[3];
var newTimeString = newHoursString + ":" + minutesString + ":" + secondsString;
$(".end_time").val(newTimeString);
});
Basic example...
var date = new Date();
var h = date.getHours() + 1;
var m = date.getMinutes();
var s = date.getSeconds();
alert('One hour from now: ' + h + ':' + m + ':' + s);
Demo: http://jsfiddle.net/fBaDM/2/
After you parse you date/time string, you can use methods such as .setHours in your date object (more info at Mozilla Developer Center).
I highly recommend the DateJS library for working with date and time. I'm sure it'll be very handy for you.
protip: try to avoid replacing JavaScript with "jQuery markup"; it's all JS, after all. :)