How to convert user timezone to UTC? - javascript

I'm using the TimeIt code on my site, it can be found here: http://codegen.in/timeit/
This is the direct link to the code: https://res.cloudinary.com/vsevolodts/raw/upload/v1503371762/timeit.min.js
It looks like this:
//version 3. 2017-08-13
function timeit() {
var next_run_array = []; //array of dates/time on a page used to rerun function if a change should happen during the session
var curDate = new Date();
Date.prototype.yyyymmdd = function() {
var mm = this.getMonth() + 1;
var dd = this.getDate();
return [this.getFullYear(),
(mm > 9 ? '' : '0') + mm,
(dd > 9 ? '' : '0') + dd
].join('-');
};
var curDateYMD = curDate.yyyymmdd();
$('.timeit').each(function() {
var end = $(this).data('end'),
start = $(this).data('start');
//check if date or time value has valid format and push it to the list of refresh anchors
var startDate = checkdate(start, this);
var endDate = checkdate(end, this);
nextrun(startDate);
nextrun(endDate);
//add a datetime when the page needs to be refreshed (now+24 hrs time span only)
function nextrun(date) {
var nextruntimeout = date - curDate;
if (nextruntimeout < 1000 * 60 * 60 * 24 && nextruntimeout > 1000) {
next_run_array.push(nextruntimeout);
}
}
// Main Function
//check if the evend outside of a desired time span
if (((startDate < endDate) && (startDate > curDate || endDate < curDate)) ||
((startDate > endDate) && (startDate >= curDate) && (endDate <= curDate))
) {
$(this).addClass('hidden');
} else {
$(this).removeClass('hidden');
}
//Support Functions
//correct data creation from a string. accepted format YYYY-MM-DD HH:MM
function parseISO8601(d) {
var isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)?.(\d\d)?.(\d\d)\s*$/,
date = new Date(NaN),
datenew,
month,
dateString=d.substr(0, d.indexOf(' '));
parts = isoExp.exec(d);
if(parts) {
month = +parts[2];
date.setFullYear(parts[1], month - 1, parts[3]);
if(month != date.getMonth() + 1) {
date.setTime(NaN);
}
date = new Date(parts[1], month - 1, parts[3], parts[4], parts[5])
}
return date;
}
//unification of the date string to the format YYYY-MM-DD HH:MM
function checkdate(date, obj) {
if (date) {
//check if only time is set (HH:MM); if so, add today's date
if (String(date).length < 6 && String(date).indexOf(":") > -1) {
date = curDateYMD + ' ' + String(date);
}
//check if only date is set; if so add 00:00 to the end of date
if (String(date).indexOf(":") == -1) {
date = date + ' 00:00';
}
//check if date is valid (avoid valid time)
var res = date.split(":"),
h = String(res.slice(0, 1)),
hours = h.substr(h.length - 2),
minutes = res.slice(1);
var timetest = (hours < 24 && minutes < 60) ? true : false;
//check if date is could be created from a value; if fails try to parse a string to a format
var returndate = new Date(date);
if (returndate == 'Invalid Date') {
var returndate = parseISO8601(date);
};
if (returndate == 'Invalid Date' || !timetest) {
//highlight the element if the is an error. use own \.error class if needed
$(obj).addClass("error").attr('title', '"' + date + '" date is incorrect; please use YYYY-MM-DD HH:MM format');
}
return returndate.getTime();
} else {
//if datetime is not set, just return current date-time
return curDate.getTime();
}
}
});
/* Schedule next runs */
if (next_run_array.length > 0) {
var nextruntime = Math.min.apply(null, next_run_array);
console.log("next run of timeit function is in " + nextruntime / 1000 + "seconds");
setTimeout(function() {
timeit();
}, nextruntime);
}
}
timeit();
(
Then you just put the embed code:
<div class="timeit" data-start="2019-02-15" data-end="2019-07-25 23:59">
This content will be shown between 2019-02-15 - 2019-07-25
</div>...<script src="/js/timeit.js"></script>
The idea is: my content is being shown between a certain period of time. I would like it to work with the UTC time zone, but right now the code is getting the date/hour info from the user's local time zone. So my content becomes available for example not at 8 AM UTC, but at 8 AM of the user's local time zone. I would like to change that.
I really, really tried to work this out on my own, but I guess this is beyond my skill set (which is pretty low). I'm confused by all the info about those ISO 8601, new Date, Date, I can't really find where it says "get the time from this source" to replace it with "get it from UTC". So - if any of you would just take a look at it and tell me what to put where, I would be extremely grateful.
Thank you all for your time!

Since you can't use server-side scripting because of Weebly... You will have to rely on the client's clock which can be tweeked. And the hidden class can easily be removed... But it seems you don't have the choice.
Now, I will suggest you to forget about the TimeIT plugin.
When it comes to dates in JavaScript/jQuery, I always recommand the use of moment.js which is really easy to use (you won't have to perform complex caluculations anymore) and fully documented, so you can do whatever you wish.
Here, content hiding based on start/end dates in data attributes would look like this:
$(document).ready(function(){
var utc_date = moment().utc().format("YYYY-MM-DD HH:mm"); // Client's date/time in UTC
$(".timeit").each(function(){
var start = moment($(this).data("start")).format("YYYY-MM-DD HH:mm");
var end = moment($(this).data("end")).format("YYYY-MM-DD HH:mm");
console.log((utc_date>start && utc_date<end)?"Content displayed":"Content hidden");
$(this).addClass("hidden"); // Hide content by default
if(utc_date>start && utc_date<end){
$(this).removeClass("hidden"); // Show content if now is between start/end dates
}
});
}); // ready
.hidden{
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<div class="timeit" data-start="2019-02-15" data-end="2019-07-25 23:59">
This content will be shown between the dates in data attributes
</div>
You can try it in CodePen... Change the start date and hit "Run". I left some console logs so you can understand what is going on.
For more, explore moment.js documentation.

Related

Date validation and relative delta between two dates in javascript

I have an interface where I receive a date in this format: Month/Year, ex: 11/2022.
I would like to verify that this is a valid date.
I use the datatables editor. The configuration (see below) of the field works well, but since the user can enter the date himself without going through the calendar, there is a risk that the date entered is incorrect. It doesn't work like an input mask. So i need to validate the date in the code.
{
type: "datetime",
label: "Date:",
name: "Date",
def: function () { return new Date(); },
format: 'MM/YYYY',
fieldInfo: 'Format: Month/Year (ex: 12/2022)',
keyInput: true
}
The date should not be accepted if the difference between this date and today's date is less than 3 months.
It means that, compared to today, all dates before July will have to be rejected.
Currently I can do this with the relativedelta method of the python dateutil module. But as the validation must be done on the client side, I would like to do this in javascript (which I know very little).
The example below shows how to do this. You should take advantage of the HTML 5 input types to validate your dates. You also need to calculate 3 months from now in myEpoch and then compare it to the date/time given
HTML:
<p>
Date & Time: <input id="foo" type="datetime-local" />
</p>
JavaScript:
var myEpoch = new Date();
myEpoch.setMonth(myEpoch.getMonth() + 3);
myEpoch = myEpoch.getTime();
var foo = document.getElementById("foo");
if (foo.value < myEpoch) {
//show a message saying this date is invalid
}
Since user is entering date in MM/yyyy format, so i'm assuming that you take 1 as a date into account, i.e., if input is 03/2020, you would consider it as: 01/03/2020. Right? If
so, then you can do the following to validate this date:-
function isValidDate(inputDate) {
// Unfortunately JS doesn't have any in-built function to validate date in MM/yyyy format. Hence regex comes to the rescue
var regex = /^([0-9]{1,2})\/([0-9]{4,4})$/;
var matches = regex.exec(inputDate);
if (!matches || matches.length != 3) {
throw new Error('Please provide date in MM/yyyy format');
}
var inputMonth = matches[1]; // Return month from input date
var inputYear = matches[2]; // Return year from input date
var finalDate = inputMonth+ '/01/' + inputYear;
// Check if entered date is valid or not
var parsedDate = Date.parse(finalDate);
if (isNaN(parsedDate)) {
throw new Error('Unable to parse date.');
}
// Check if it is less than 3 months or not.
var isValid = !isLessThan3Months(new Date(finalDate), new Date());
return isValid;
}
function isLessThan3Months(dateToCompare, currentDate) {
var diffYears = currentDate.getFullYear() - dateToCompare.getFullYear();
var diffMonths = currentDate.getMonth() - dateToCompare.getMonth();
var diffDays = currentDate.getDate() - dateToCompare.getDate();
var months = diffYears * 12 + diffMonths;
if (diffDays > 0) {
months += '.' + diffDays;
} else if (diffDays < 0) {
months--;
months +=
'.' +
(new Date(currentDate.getFullYear(), currentDate.getMonth(), 0).getDate() + diffDays);
}
return months < 3;
}
isValidDate('03/2020');
So now, by calling isValidDate with user's input date in MM/yyyy format, you should be able to check if it is valid or not.
For this, you won't need to use any third party javascript library. Just plain javascript is enough.
You should probably use Moment.js, because working with the raw Date object is fiddly.
If you would rather use plain JavaScript, then the following might be of use:
const moreThan3MonthsHence = ({ utcYear, utcMonth },
now = new Date,
target = new Date(Date.UTC(utcYear, utcMonth)),
threeMonthsHence = addMonths(new Date(now.valueOf()), 3)) =>
(target > threeMonthsHence)
const validate = (str,
[utcMonth, utcYear] = str.split('/'),
date = new Date(Date.UTC(+utcYear, (+utcMonth)-1))) =>
moreThan3MonthsHence({ utcYear: date.getUTCFullYear(), utcMonth: date.getUTCMonth() })
const addMonths = (date, months, d = date.getDate()) => {
date.setMonth(date.getMonth() + +months);
// If rolled over to next month, set to last day of previous month
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
// Note: input is one-based months
console.log(validate('07/2020')) // true
console.log(validate('06/2020')) // false
console.log(validate('12/2019')) // false
Notes
now is internally represented as the milliseconds since the Unix epoch. Note this includes the current time of day.
target is the milliseconds since the Unix epoch of midnight on the supplied UTC date.
threeMonthsHence is the milliseconds since the Unix epoch of now (including time of day), plus three months.
validate parses the input string.
addMonths is necessary because the built-in function can roll-over into a new month with unexpected behavior.
Finally to solve my problem I mixed the solutions proposed by #Sumit Parakh and #ControlAltDel.
function isValidDate(inputDate) {
var regex = /^([0-9]{1,2})\/([0-9]{4,4})$/;
var matches = regex.exec(inputDate);
var parsedDate = 0;
if (!matches || matches.length != 3) {
throw new Error('Please provide date in MM/yyyy format');
}
else {
var inputMonth = matches[1]; // Return month from input date
var inputYear = matches[2]; // Return year from input date
var finalDate = inputMonth+ '/01/' + inputYear;
// Check if entered date is valid or not
var parsedDate = Date.parse(finalDate);
if (isNaN(parsedDate)) {
parsedDate = 0;
//throw new Error('Unable to parse date.');
}
return parsedDate;
}
var myEpoch = new Date();
myEpoch.setMonth(myEpoch.getMonth() + 3);
myEpoch = myEpoch.getTime();
finalDate = isValidDate(date_peremption.val());
if (finalDate == 0){
date_received.error("This date is invalid");
}
else if(finalDate < myEpoch) {
date_received.error("The date must be more than three months last");
}
It's not very elegant, but it works. Thanks everyone

Javascript: how to check if a timestamp belongs to the current day?

I am trying to know if a certain timestamp belongs to today, but I'm getting lost in Javascripts date management.
Is there any way to check if a timestampo belongs to the current day?
Simple check 1st timestamp of both days and compare them.
var ts = 1564398205000;
var today = new Date().setHours(0, 0, 0, 0);
var thatDay = new Date(ts).setHours(0, 0, 0, 0);
if(today === thatDay){
console.log("*** Same day ***");
}
It seems nasty-ish to me however you could do something similar to:
function isInToday(inputDate)
{
var today = new Date();
if(today.setHours(0,0,0,0) == inputDate.setHours(0,0,0,0){ return true; }
else { return false; }
}
This assumes you've already set your input date as a JS date. This will check if the two dates occur on the same day, and return true if so and false if not.
I'm sure someone will come along with a neater way to do this or a case where this fails but as far as I can see this should do the trick for you.
you can really depend on ISO date string with a substr function to compare the two strings
var T=1479288780873; /*assume your timestamp value*/
var theDay=new Date(T);
var today=new Date;
theDay.toISOString().substr(0,10) == today.toISOString().substr(0,10) ? console.log("same day"):null;
You can do something like this :
var day = 24 * 60 * 60 * 1000; //nb millis in a day
var todayTimestamp = new Date(year, month, day).getTime(); // Be careful month is 0 start
//OR
var todayTimestamp = new Date().setHours(0,0,0,0).getTime();
var diff = myTimestamp - todayTimestamp;
if ( diff >= 0 && diff <= day ) {
console.log("timestamp is today");
else {
console.log("timestamp is not today");
}
var timestamp = '2016-11-16 03:14:07.999999';
var datestamp = timestamp.substring(0, 10);
Date.prototype.yyyymmdd = function() {
var mm = this.getMonth() + 1;
var dd = this.getDate();
return [this.getFullYear(), mm, dd].join('-');
};
var date = new Date();
date.yyyymmdd();
console.log(String(datestamp) === String(date.yyyymmdd()));
It depends what format your timestamp is in.
But here is the most basic way to achieve this:
var today = new Date(year, month, day);
var timestamp = //your timestamp;
if (timestamp == timestamp){ //make sure the date formats are the same
//your code
}
I hope this is what you were looking for, there are more methods with the javascript date reference, don't hesitate to look it up.

How to check whether the date is in past or not?and How to get difference between two dates? by input tag type date and type time

Restaurant app booking a table feature.
Date input by <input type="date"> and <input type="time">
What I need.
1.How check whether the given/input date and time is in past or not.If past not valid,if future valid for booking.
2.How to get difference between two dates and times.So that I can show time left for booked table,and the user is allowed to get a table within the booked date and time mentioned.(may be by setInterval())
HTML
<html>
<head>
</head>
<body>
<table id="tdatetime">
<tr><td>Select Date</td><td>Select Time</td></tr>
<tr><td><input type="date" id="bdate"></td><td><input type="time" id="btime"></td></tr>
</table>
<input type="button" id="bdtbtn" onclick="getbdtRL(this)" value="Book Now"></input>
</body>
</html>
JS
function getbdtRL(bookbtn)
{
var bdate=$("#bdate").val();
var btime=$("#btime").val();
var now = new Date();
var selectedDate=new Date(bdate);
var selectedTime=new Date(btime);
alert(btime);//returns for example- 2:00
alert(selectedTime);//returns Invalid Date
alert(selectedTime.toString());//returns Invalid Date
alert(selectedTime.toTimeString());//returns Invalid Date
alert(selectedTime.toDateString());//returns Invalid Date
//Date check is working
if(selectedDate<now)
{
alert("Selected Date is in Past");
}
else if(selectedDate>now)
{
alert("Selected Date is in Future");
}
else if(selectedDate==now)
{
alert("Selected Date is in Present");
}
//Time Check is not working by selectedTime
if(selectedTime<now)
{
alert("Selected Time is in Past");
}
else if(selectedTime>now)
{
alert("Selected Time is in Future");
}
else if(selectedTime==now)
{
alert("Selected Time is in Present");
}
//Time Check is not working by btime
if(btime<now)
{
alert("Selected Time is in Past");
}
else if(btime>now)
{
alert("Selected Time is in Future");
}
else if(btime==now)
{
alert("Selected Time is in Present");
}
}
//Date and Time Difference not working
var date=new Date();
var tempdate="2015-05-01";
var d1 = date;//tempdate;//
//alert("current date d1="+d1);
var d2 = RLArrBookDateSender;//receiving from db2 database data type is time which is already booked
//alert("booked date d2="+d2);
var DateDiff = {
inDays: function(d1,d2) {
var t2 = d2.getTime();
var t1 = d1.getTime();
return parseInt((t2-t1)/(24*3600*1000));
}
};
alert("diff="+DateDiff.inDays(d1,d2));//no alert executes
You need to get the value from the DOM element, new Date only accepts a String or a Number or a series of Numbers, not DOM elements. Try entering a value in your Date and Time fields and entering the below code into the console.
alert( new Date( bdate.value + ' ' + btime.value ) - new Date > 0? 'future' : 'past');
I apologize if you were looking for more to the answer...but if the following is right then it should make sense...
(It's late, but i believe the logic is right...)
To compare dates:
var now = new Date();
var selectDate = new Date(bdate);
var diff = now.getTime() - selectDate.getTime();
if(diff > 0 || diff == 0) {
// selected date is in the past or is our current time
// (which should be tough to match down to milliseconds)
}
else if (diff < 0) {
// selected date has not past
}
To get the time left until a future date:
var now = new Date();
var validFutureDate = new Date(bdate);
var diff = validFutureDate.getTime() - now.getTime(); // in milliseconds
var dayDiff = parseInt(diff/(1000*60*60*24));
You can check it that way: http://jsfiddle.net/IonDen/gt4tqca9/
var date_in_future = new Date("2015-10-20"),
date_in_past = new Date("2014-05-15");
function check (date) {
var now = new Date().getTime(),
target = date.getTime();
if (target <= now) {
return false;
} else {
return true;
}
}
function diff (date) {
var now = new Date().getTime(),
target = date.getTime();
return now - target;
}
console.log(date_in_future);
console.log(date_in_past);
console.log("future date? " + check(date_in_future));
console.log("future date? " + check(date_in_past));
console.log("diff: " + diff(date_in_future));
console.log("diff: " + diff(date_in_past));

Interpret user entered dates in JavaScript

I was looking for a convenient method to take a date entered by a user and do the following:
1) Determine if the Date entered is valid, and if it is valid, return an object with:
2) A JavaScript Date object
3) The date formatted in mySQL format (YYYY-MM-DD)
4) The date formatted in typical format (MM-DD-YYYY)
In the end I wrote my own function that uses Regex and can handle an input of YYYY-MM-DD, YYYY/MM/DD, MM-DD-YY, MM/DD/YY, MM-DD-YYYY or MM/DD/YYYY.
The reason that the function returns mySQL format and regular format in the object is simply for convenience. My web app needs the typical format to display in the field and the mysQL format to send to the server when saving data.
The code is shown below in my answer. I'm sure there are ways to optimize the code, but I wrote it in parts for the ease of reading. And even if it was set to run every time a user entered data in a date field, it wouldn't bog anything down. Hopefully this helps someone!
UPDATE: momentjs is much better.
The code and an example can be seen here on this jsfiddle.
function interpretDate(stringDate){
var mysqlF = "(\\d{4})[-/](\\d{1,2})[-/](\\d{1,2})";
var dispF = "(\\d{1,2})[-/](\\d{1,2})[-/]((?:\\d{4})|(?:\\d{2}))";
var dispNoYearF = "(\\d{1,2})[-/](\\d{1,2})";
var dateFormats = "(^"+mysqlF+"$)|(^"+dispF+"$)|(^"+dispNoYearF+"$)";
//Let's try to extract the data
data = stringDate.match(dateFormats);
var month = -1;
var day = -1;
var year = -1;
//Check to see if the verification failed
if (data == undefined){
//Invalid date
return {valid: false, date: null, mysqlDate:null, displayDate: ""};
}
//Extract the data based on the entry type
if (data[1] != undefined){//YYYY-MM-DD
month = parseInt(data[3]);
day = parseInt(data[4]);
year = parseInt(data[2]);
}else if (data[5] != undefined){//MM-DD-YYYY or MM-DD-YY
month = parseInt(data[6]);
day = parseInt(data[7]);
year = parseInt(data[8]);
if (year < 100){
var yearString = new String(new Date().getFullYear());
year = parseInt(yearString.substr(0,2) + year);
}
}else if (data[9] != undefined){//MM-DD
month = parseInt(data[10]);
day = parseInt(data[11]);
year = parseInt(new Date().getFullYear());
}
//If we are here, we have three numbers, let's see if they make a real date
var extractedDate = new Date(year, month-1, day);
if (extractedDate.getFullYear() != year || extractedDate.getDate() != day || extractedDate.getMonth() != (month-1)){
return {valid: false, date: null, mysqlDate:null, displayDate: ""};
}
//We have a valid date, let's add front zeros
var monthFixed = month;
if (monthFixed < 10) monthFixed = "0"+monthFixed;
var dayFixed = day;
if (dayFixed < 10) dayFixed = "0"+dayFixed;
//We are done
return {valid: true, date: extractedDate, mysqlDate:year+"-"+monthFixed+"-"+dayFixed, displayDate: month+"/"+day+"/"+year};
}

how to compare only time in javascript?

I want to compare only time on client side, means the start time should not be greater than end time. I have searched on net but not able resolve this problem. Please help me as soon as possible. Thanks in advance.
you can compare date in javascript
check following code
var x=new Date();
x.setFullYear(2100,0,14);
var today = new Date();
if (x>today)
{
alert("Today is before 14th January 2100");
}
else
{
alert("Today is after 14th January 2100");
}
For example lets say the time picked for example
var startTime = "09:15";
var endTime ="10:15";
if(parseInt(startTime.split(":")[0],10) > parseInt(endTime.split(":")[0],10))
alert("Start Time should not be greater than end time");
else
alert("Valid Time");
Hope this helps.
You'll need to use the Date object functions to pull out the hours minutes and seconds to get just the time from a Date:
var currentDate = new Date();
var hours = currentDate.getHours();
var minutes = currentDate.getMinutes();
var seconds = currentDate.getSeconds();
Using DateJS you can use the following method compareTo
var past = Date.today().add(-6).days();
var future = Date.today().add(6).days();
Date.today().compareTo(future); // -1
Date.today().compareTo(new Date().clearTime()); // 0
Date.today().compareTo(past); // 1
if you do not want to use a whole library here is the source code for the static compare method in DateJS
Date.compare = function (date1, date2) {
if (isNaN(date1) || isNaN(date2)) {
throw new Error(date1 + " - " + date2);
} else if (date1 instanceof Date && date2 instanceof Date) {
return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0;
} else {
throw new TypeError(date1 + " - " + date2);
}
};
This will work for time as well asuming that both dates (yyyy-MM-dd) are the same

Categories

Resources