Combining Date and Time input strings as a Date object - javascript

I have two input tags for picking date and time from user.
<p>Start Date</p><p> <input ng-model="sdate" type="date" ></p>
<p>Start Time</p><p> <input ng-model="stime" type="time" ></p>
These two values are passed to a function where I want to combine these two input values as a Date object:
new Date(y, m, d, hh, mm, a)
Which I can then use to plot an event's details in a Calendar. How can I combine these two values? I have tried:
start:new Date(sdate + stime)
start:new Date(sdate , stime)
start: new Date(sdate.getFullYear() + sdate.getMonth() + sdate.getDate() + stime.getHours + stime.getMinutes())
But none of what I have tried is working.
How do I achieve this when using AngularJS?

In angular it would go something like this:
Controller:
function exampleController($scope) {
$scope.title = "$Watch sample";
$scope.$watch('sdate', function() {
tryCombineDateTime();
});
$scope.$watch('stime', function() {
tryCombineDateTime();
});
function tryCombineDateTime() {
if($scope.sdate && $scope.stime) {
var dateParts = $scope.sdate.split('-');
var timeParts = $scope.stime.split(':');
if(dateParts && timeParts) {
dateParts[1] -= 1;
$scope.fullDate = new Date(Date.UTC.apply(undefined,dateParts.concat(timeParts))).toISOString();
}
}
}
}
HTML
<div ng-app ng-controller="exampleController">
<h2>{{title}}</h2>
<p>Start Date</p><p> <input ng-model="sdate" type="date" ></p>
<p>Start Time</p><p> <input ng-model="stime" type="time" ></p>
{{fullDate}}
</div>
You need to make use of the $watch listener on a variable when it changes, then call your function.
Note: it would be even better if you make a directive for this.
Fidle

A very naive approach to combine these two is to split date-components and time-components and make a string. Then make a new Date object using this string.
Input is taken from here:
<p>Start Date</p><p> <input ng-model="sdate" type="date" ></p>
<p>Start Time</p><p> <input ng-model="stime" type="time" ></p>
Then in script part, split date and time components as follows:
var dd = new Date(sdate).getDate();
var mm = new Date(sdate).getMonth()+1;
var yy = new Date(sdate).getFullYear();
var hh = new Date(stime).getHours();
var ms = new Date(stime).getMinutes();
Then Combine these components to form a string as required(in Calendar):
var x = yy + ',' + mm + ',' + dd + ' ' + hh + ':' + ms;
Now create a new Date object:
var finaldate = new Date(x);

You could do something like this, though this doesn't have anything to do with AngularJS and I can't test on older browsers. I am assuming that you are entering date/time as UTC and I am using Date to create an ISO8601 timestamp as an output. Also assumes that you are using a modern browser that supports HTML5 and ECMA5, otherwise you will need to modify the code.
HTML
<p>Start Date</p><p> <input id="myDate" ng-model="sdate" type="date" ></p>
<p>Start Time</p><p> <input id="myTime" ng-model="stime" type="time" ></p>
<div id="myIso"></div>
Javasceipt
var myIso = document.getElementById('myIso'),
dateParts,
timeParts;
function joinPartsAsDate() {
if (dateParts && dateParts.length === 3 && timeParts && timeParts.length === 2) {
// dateParts[1] -= 1; could be done here
myIso.textContent = new Date(Date.UTC.apply(undefined, dateParts.concat(timeParts))).toISOString();
} else {
myIso.textContent = '';
}
}
document.getElementById('myDate').addEventListener('change', function (e) {
dateParts = e.target.value.split('-');
if (dateParts[1]) { // this could be done in joinPartsAsDate, here for clarity
dateParts[1] -= 1;
}
joinPartsAsDate();
}, false);
document.getElementById('myTime').addEventListener('change', function (e) {
timeParts = e.target.value.split(':');
joinPartsAsDate();
}, false);
On jsFiddle

After testing all stuff described here, i found a very simple solution.
In my view i have
<input type="date" ng-model="tsc.untilDate">
<input type="time" ng-model="tsc.untilTime">
In my Angular Controller both model elements are objects from type Date by default.
With input type="date" the time of this Date object is always 00:00.
With input type="time" the date part of the Date object ist allways set to today.
So i just read the daytime (if it is set) of the TimeDate Object and set it on the DateObject.
if(tsc.untilTime)
{
tsc.untilDate.setHours(tsc.untilTime.getHours());
tsc.untilDate.setMinutes(tsc.untilTime.getMinutes());
}

For those looking for a compact version install the momentjs library.
npm install moment --save
Add it to your file header.
import * as moment from 'moment';
Then just compose the dateTime object with the fluent interface.
let dateTime = moment(this.sdate)
.startOf('day')
.set('hour', this.sTime.getHours())
.set('minute', this.sTime.getMinutes() )
.toDate();

Try this
const timeAndDate = moment(this.sdate + ' ' + this.sTime.getHours() + ' ' + this.sTime.getMinutes());
console.log(timeAndDate.toDate());

Related

Display date as dd-mm-yyyy format for input type=date

I have my code :
<input type="date" class="form-control" id="training_date"
name="training_date" placeholder=" select" value=""
onfocus="(this.type='date')"
onfocusout="(this.type='date')" max=<?php echo date('Y-m-d'); ?>>
I need to display my date in following date-format dd-mm-yyyy format in the textbox.
What I would recommend is to make a array with the 12 months of the year (because the will never change)
_currentDate() {
var date = new Date();
for (var i = 0; this.months.length > i; i++) {
if (date.getMonth() === i) {
var displayMonth = this.months[i].month;
}
}
var displayDate = date.getDate() + ' ' + displayMonth + ' ' + date.getFullYear();
return displayDate;
}
Use the value that you return in your function you just need to insert where you want to display it so in your case your input
Hope this helps :)
Please note: <input type="date"> is not supported in IE and Firefox. Hence, it's not good idea to implement it in as it's against robust UI/UX design, and might invite later bugs.
You should use jquery's datepicker, moment.js or combination of both to achieve your requirement.
To close the question and provide what can be done and tested. Here is implementation.
In this example:
I am assigning today's date to <input type="date"> by forming a date string in yyyy-mm-dd format and setting attribute value
whenever I am changing the the date in #datepicker, I am forming a date string in dd-mm-yyyy format and providing it as value to #textbox
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var d = new Date();
function twoDigitDate(d){
return ((d.getDate()).toString().length == 1) ? "0"+(d.getDate()).toString() : (d.getDate()).toString();
};
function twoDigitMonth(d){
return ((d.getMonth()+1).toString().length == 1) ? "0"+(d.getMonth()+1).toString() : (d.getMonth()+1).toString();
};
var today_ISO_date = d.getFullYear()+"-"+twoDigitMonth(d)+"-"+twoDigitDate(d); // in yyyy-mm-dd format
document.getElementById('datepicker').setAttribute("value", today_ISO_date);
var dd_mm_yyyy;
$("#datepicker").change( function(){
changedDate = $(this).val(); //in yyyy-mm-dd format obtained from datepicker
var date = new Date(changedDate);
dd_mm_yyyy = twoDigitDate(date)+"-"+twoDigitMonth(date)+"-"+date.getFullYear(); // in dd-mm-yyyy format
$('#textbox').val(dd_mm_yyyy);
//console.log($(this).val());
//console.log("Date picker clicked");
});
});
</script>
</head>
<body>
<div style="width: 50%;height:50px; float:left;">
Enter your Birthday!!:<br>
<input id="datepicker" type="date" name="bday" style="margin-bottom: 200px;"></br><br>
</div>
<div style="width: 50%;height:50px; float:right;">
Date chosen(dd-mm-yyyy):<br>
<input id="textbox" type="text" value="dd-mm-yyyy"></input>
</div>
</br></br></br></br></br></br>
<p><strong>Note:</strong> type="date" is not supported in Firefox, or Internet Explorer 11 and earlier versions.</p>
</body>
</html>
You can use the below code to achieve this.
<input type="date" class="form-control" id="training_date" name="training_date" placeholder=" select" value="" onfocus="(this.type='date')" onfocusout="(this.type='date')" pattern="\d{1,2}/\d{1,2}/\d{4}" >

Add one day to date string in javascript

I am setting the min of checkOut as the value of checkIn. My problem comes that i need to add one day to firstdate. (Should not be able to check out on or before the check in day.)
<script>
function updatedate() {
var firstdate = document.getElementById("checkIn").value;
document.getElementById("checkOut").value = "";
document.getElementById("checkOut").setAttribute("min",firstdate);
}
</script>
Check In
<input type="date" id="checkIn" onchange="updatedate();" name="checkin">
Check out
<input type="date" id="checkOut" min="" name="checkout">
It's sort of do-able but it only works in Chrome since that's the only browser that supports a date input at the moment. Oh, and this solution uses momentjs because parsing a date and correctly adding 1 day to it is way harder that it sounds.
function updatedate() {
var checkin = document.getElementById("checkIn").value;
checkin = moment(checkin);
var checkout = checkin.add(1, 'd');
document.getElementById("checkOut").setAttribute("min", checkout.format('YYYY-MM-DD'));
}
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet"/>
<div class="container">
Check In
<input type="date" id="checkIn" onchange="updatedate();" name="checkin">Check out
<input type="date" id="checkOut" min="" name="checkout">
</div>
A momentless solution is to parse the checkinDate into a JS date and and then create a new date whilst adding one day to the checkinDate. Though yeah, momentJS is the goto library when dealing with dates.
JSfiddle here:
https://jsfiddle.net/xugajae5/
There was a bit of a hack in getting the min format that the input expected:
var checkoutDateFormat = checkoutDate.toISOString().split('T')[0];
Not all browsers in use support input type date, so you'll need to deal with that to start with.
Then, you can convert the value of firstdate to a Date object, add a day, then get back a date in the required format. Your issue however is that the value of the date input (which is an ISO 8601 format date string) is treated as local, but the Date constructor will treat it as UTC.
So you need to parse the string as a local date, then add the day, then get back a string in the right format. The code below is just an example, you may wish to use a library for the date manipulation. Just remember not to parse the date string with the Date constructor.
function getTomorrow(el) {
var form = el.form;
var start = parseISOAsLocal(form.start.value);
// Check if input date was valid
if (!start.getTime()) {
form.tomorrow.value = '';
form.start.value = 'Invalid date';
return;
}
start.setDate(start.getDate() + 1);
form.tomorrow.value = formatISODate(start);
}
function parseISOAsLocal(s) {
var b = s.split(/\D/);
var d = new Date(b[0], --b[1], b[2]);
return d && d.getMonth() == b[1]? d : new Date(NaN);
}
function formatISODate(date) {
return ('000' + date.getFullYear()).slice(-4) + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2);
}
<form>
Start (yyyy-mm-dd):
<input type="date" name="start" value="2016-08-31"><br>
Tomorrow: <input type="date" name="tomorrow" readonly><br>
<input type="button" onclick="getTomorrow(this)"
value="Show tomorrow">
</form>
<script>
function updatedate(){
var checkInValue = document.getElementById("checkIn").value;
var checkInDate = Date.parse(checkInValue);
var minDate = new Date(checkInDate + 24 * 3600 * 1000);
document.getElementById("checkOut").setAttribute("min", minDate.toDateString());
}
</script>

Firefox date format

I have created a webpage which calculates the weeks and days between two dates.
In chrome this page works and gives me the output of 4 weeks and two days for the dates 01/01/2016 and 01/31/2016 but firefox gives me the output of 130 weeks and two days.
How would I got about changing this to get the output of chrome.
Many thanks
<html>
<head>
<title>Time Between Dates Calculator</title>
<script src="dateCalc.js"></script>
</head>
<body>
<h1>Calculate the Amount of Time Between Dates:</h1>
<form>
Enter Date 1 (mm/dd/yyyy): <input type="date" id="date1" name="date1" required> <br />
Enter Date 2 (mm/dd/yyyy): <input type="date" id="date2" name="date2" required> <br />
<input type="submit" onclick="datecalc()" Value="Get Weeks and days">
</form>
</body>
</html>
***********************************************************************
function datecalc()
{
firstDate = document.getElementById("date1").value;
secondDate = document.getElementById("date2").value;
/*window.alert(firstDate);
window.alert(secondDate);*/
firstDateMs = new Date(firstDate).getTime();
secondDateMs = new Date(secondDate).getTime();
msPerDay = 24 * 60 * 60 * 1000;
msLeft = (secondDateMs - firstDateMs);
daysLeft = Math.round(msLeft/msPerDay);
weeksLeft = Math.round(daysLeft/7);
total = (daysLeft-(weeksLeft*7))
window.alert("The difference between these days is: " + weeksLeft + " weeks and " + total + " days.");
}
one solution is to use .split("/") on your input strings, then use the
new Date(year, month, day); constructor.
Also January is 0 and December is 11 in Javascript date
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date
this will remove any ambiguity from possible string interpretation of the date.
firstDate = document.getElementById("date1").value;
secondDate = document.getElementById("date2").value;
/*window.alert(firstDate);
window.alert(secondDate);*/
firstDate.split("/");
secondDate.split("/");
firstDateMs = new Date(parseInt(firstDate[2]), parseInt(firstDate[0]) - 1, parseInt(firstDate[1])).getTime();
secondDateMs = new Date(parseInt(secondDate[2]), parseInt(secondDate[0]) - 1, parseInt(secondDate[1])).getTime();
The submit listener should be on the form, not the submit button, since the form can be submitted without clicking the button. Also, the date strings should be manually parsed to dates and since they depend on user input, the values validated. It can also make life easier if a reference to the form is passed by the handler so controls are accessed by name rather than getElementById.
Input type date is not well supported and creates more issues than it solves for now, so better to use type text (or use your own date picker). The following uses input type text and manually parses and validates the string in m/d/y format.
For a real form, it would be better to validate each date separately and put an error message for the one(s) that are invalid, also to echo the parsed date to the screen so the user can see that the code is using the date as they expect (e.g. 1/2/2016 comes out as 2 January not 1 February).
Some codeā€¦
function datecalc(form) {
var d1 = parseMDY(form.date1.value);
var d2 = parseMDY(form.date2.value);
var msDay = 8.64e7;
var msWeek = msDay * 7;
var result;
// Deal with in valid input
if (isNaN(+d1) || isNaN(+d2)) {
result = 'Invalid date';
} else {
// Get weeks and days
var diff = d2 - d1;
result = (diff/msWeek | 0) + ' weeks ' +
Math.round((diff % msWeek)/msDay | 0) + ' days';
}
// Should return an array of say [weeks, days] and leave formatting
// to some other function.
form.result.value = result;
}
function parseMDY(s) {
var b = s.split(/\D/);
var d = new Date(b[2], --b[0], b[1]);
return d && d.getMonth() == b[0]? d : new Date(NaN);
}
<form onsubmit="datecalc(this); return false;">
Enter Date 1 (mm/dd/yyyy): <input type="text" name="date1" value="3/1/2016"><br>
Enter Date 2 (mm/dd/yyyy): <input type="text" name="date2" value="3/23/2016"><br>
<input type="reset"> <input type="submit" Value="Get Weeks and days"><br>
<input type="text" name="result" readonly>
</form>
I guess you're rounding the days to remove daylight saving errors, be careful with that. An alternative is to get the difference in days from the date values and not create date objects at all. That removes any issues with DST (but validating the dates takes about 3 lines more code).

PHP: Date range selection automatically

I have 3 input fields all together.
Contract period: 1 years(for example)
start date : 30 - 1- 2012 (for example)
end date : ????
(Can we get the end date automatically according to the contract period mentioned, which mean if the date after 1 year is 30-1-2013 can we get it automatically in the third field after mentioning the first and second field).
Possible, using onSelect option of jQuery datepicker.
1) get the value of contract year and parse it as integer.
var addYears = parseInt($('#contract').val(), 10);
2) Split the selected date in startDate, as below
var t = date.split('/');
3) Now add the years and parse it as Date object.
var fin = new Date(parseInt(t[2], 10) + addYears, --t[0], t[1]);
Finally,
HTML:
In years only:
<input id="contract" type="text" />
<input id="start" type="text" />
<input id="end" type="text" />
JS:
$('#end').datepicker();
$('#start').datepicker({
onSelect: function (date, args) {
var addYears = parseInt($('#contract').val());
var t = date.split('/');
var fin = new Date(parseInt(t[2], 10) + addYears, --t[0], t[1]);
$('#end').datepicker("setDate", fin);
}
});
JSFiddle

How to auto format textbox inputs

<tr>
<td><label>Birthdate</label>
<input type="text" placeholder="mm/dd/yyyy" name="birthdate" maxlength="10"/>
</td>
</tr>
Well, my code is working but I want my "input type text" to auto format like a date (html 5 input type=date) because in my Servlet I convert it to Age.
The problem is that, if I use the "input type=date" the conversion is error so I decided to use "input type=text" and it's working. So is it possible to auto put "/" in this format "mm/dd/yyyy"? For example, if the user input 2 character an "/" will auto input etc.
Servlet for birthdate to Age
String birthdate = request.getParameter("birthdate");
int monthDOB = Integer.parseInt(birthdate.substring(0, 2));
int dayDOB = Integer.parseInt(birthdate.substring(3, 5));
int yearDOB = Integer.parseInt(birthdate.substring(6, 10));
DateFormat dateFormat = new SimpleDateFormat("MM");
java.util.Date date = new java.util.Date();
int thisMonth = Integer.parseInt(dateFormat.format(date));
dateFormat = new SimpleDateFormat("dd");
date = new java.util.Date();
int thisDay = Integer.parseInt(dateFormat.format(date));
dateFormat = new SimpleDateFormat("YYYY");
date = new java.util.Date();
int thisYear = Integer.parseInt(dateFormat.format(date));
int calAge = thisYear - yearDOB;
if (thisMonth < monthDOB) {
calAge = calAge - 1;
}
if (thisMonth == monthDOB && thisDay < dayDOB) {
calAge = calAge - 1;
}
String age = Integer.toString(calAge);
Update in the form
<tr>
<td><label for="inputName">Birthdate</label>
<input type="text" placeholder="mm/dd/yyyy" id="input_date" name="birthdate" maxlength="10" />
</td>
</tr>
Update in the source
<script src="../scripts/formatter.js"></script>
<script src="../scripts/formatter.min.js"></script>
<script src="../scripts/jquery.formatter.js"></script>
<script src="../scripts/jquery.formatter.min.js"></script>
Added Script
<script>
$('#input_date').formatter({
'pattern': '{{99}}/{{99}}/{{9999}}',
'persistent': true
});
</script>
I also tried the javascript but it's not working...
I've been watching a project on GitHub (and providing feedback to improve it) for just such kind of formatting called formatter.js http://firstopinion.github.io/formatter.js/demos.html This might be just the thing you're looking for.
This wouldn't stop you from typing in dates like the 53rd of May... but it will help you format.
new Formatter(document.getElementById('date-input'), {
'pattern': '{{99}}/{{99}}/{{9999}}',
'persistent': true
});
or
$('#date-input').formatter({
'pattern': '{{99}}/{{99}}/{{9999}}',
'persistent': true
});
I have an alternative that works with a jquery-ui datepicker, without formatter.js. It is intended to be called from the keyup and change events. It adds zero padding. It works with various supported date formats by constructing expressions from the dateFormat string. I can't think of a way to do it with fewer than three replaces.
// Example: mm/dd/yy or yy-mm-dd
var format = $(".ui-datepicker").datepicker("option", "dateFormat");
var match = new RegExp(format
.replace(/(\w+)\W(\w+)\W(\w+)/, "^\\s*($1)\\W*($2)?\\W*($3)?([0-9]*).*")
.replace(/mm|dd/g, "\\d{2}")
.replace(/yy/g, "\\d{4}"));
var replace = "$1/$2/$3$4"
.replace(/\//g, format.match(/\W/));
function doFormat(target)
{
target.value = target.value
.replace(/(^|\W)(?=\d\W)/g, "$10") // padding
.replace(match, replace) // fields
.replace(/(\W)+/g, "$1"); // remove repeats
}
https://jsfiddle.net/4msunL6k/
use datepicker api from jquery
here is the link Datepicker
and here is the working code
<tr>
<td><label>Birthdate</label>
<input type="text" placeholder="mm/dd/yyyy" name="birthdate" id="birthdate" maxlength="10"/>
</td>
</tr>
<script>
$(function() {
$( "#birthdate" ).datepicker();
});
</script>
EDIT
$("input[name='birthdate']:first").keyup(function(e){
var key=String.fromCharCode(e.keyCode);
if(!(key>=0&&key<=9))$(this).val($(this).val().substr(0,$(this).val().length-1));
var value=$(this).val();
if(value.length==2||value.length==5)$(this).val($(this).val()+'/');
});
this is the code that you may need
here is the fiddled code
user2897690 had the right idea but it didn't accept Numpad numbers. So took their javascript and modified it to work.
Here is my interpretation of their code with the added feature.
$("input[name='birthdate']:first").keyup(function(e){
var chars = [48,49,50,51,52,53,54,55,56,57,96,97,98,99,100,101,102,103,104,105];
var key=chars.indexOf(e.keyCode);
console.log(key);
if(key==-1)$(this).val($(this).val().substr(0,$(this).val().length-1));
var value=$(this).val();
if(value.length==2||value.length==5)$(this).val($(this).val()+'/');
});

Categories

Resources