My goal is to make a time countdown component. I must show a difference of date from current date to user-entered date, in Year Month Day Hour Min Sec format.
I tried to minus the two dates but ended up with 00:00:00:00. Adding them gave me a result but minus gives me this 00.
Other answers do not satisfy requirements or explain why I get a difference of 0 when subtracting dates.
my code:
import "./App.css";
import Countdown from "react-countdown";
function App() {
console.log(Date.now());
return (
<div className="App">
<h1>Hello</h1>
<form>
<input type="date" />
<button>submit</button>
</form>
<Countdown date={new Date(2021, 6, 10) + Date.now()} />,
</div>
);
}
You can either do it manually as
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
or use moment js ( https://momentjs.com/ ) for operations
using moment.js, you can do it in this way:
const diffDates = (start, end) => {
let a = moment(start);
let b = moment(end);
return a.diff(b, "days");
};
Related
I want that the user can't choose previous dates, I'm using the .min function but it doesn't do anything. If you could help me.
function deshabilitarFechasAnterior(){
const inputFecha=document.querySelector('#fecha');
const fechaAhora= new Date();
const year=fechaAhora.getFullYear();
const mes=fechaAhora.getMonth()+1;
const dia=fechaAhora.getDate()+ 1;
const fechaDeshabilitar=`${year}-${mes}-${dia}`;
inputFecha.min=fechaDeshabilitar;
}
The format for min (and max) is yyyy-mm-dd ... since May is a single digit (5), the min is being ignored
you want min to be 2022-05-11 not 2022-5-11
Simplest fix to your code is by using toString and padStart for both month and day component
Note, added one day (like your code does) BEFORE getting year/month/day ... since your way of doing it would fail on the last day of the month for obvious reasons - since there is no 32nd of May for example!!
Of course, if "min" date is supposed to be today, simply DONT include that one line of code - your code implies it should be tomorrow (albeit done incorrectly) but your question states "previous dates", which implies TODAY is a valid choice - so, you must decide if that one line is included or not, since your question implies BOTH
function deshabilitarFechasAnterior() {
const inputFecha = document.querySelector('#fecha');
const fechaAhora = new Date();
// the next line makes the minimum date TOMORROW
fechaAhora.setDate(fechaAhora.getDate() + 1);
const year = fechaAhora.getFullYear();
const mes = (fechaAhora.getMonth() + 1).toString().padStart(2, '0');
const dia = (fechaAhora.getDate()).toString().padStart(2, '0');
const fechaDeshabilitar = `${year}-${mes}-${dia}`;
inputFecha.min = fechaDeshabilitar;
}
deshabilitarFechasAnterior();
<input type="date" id="fecha" />
Alternative - this is how I would go about it
Take advantage of the fact that fr-CA date string is yyyy-mm-dd
function deshabilitarFechasAnterior() {
const inputFecha = document.querySelector('#fecha');
const fechaAhora = new Date();
// the next line makes the minimum date TOMORROW
fechaAhora.setDate(fechaAhora.getDate() + 1);
inputFecha.min = fechaAhora.toLocaleDateString('fr-CA');
}
deshabilitarFechasAnterior();
<input type="date" id="fecha" />
Simply do:
const inputFecha = document.querySelector('#fecha')
deshabilitarFechasAnterior();
function deshabilitarFechasAnterior()
{
let dateMin = new Date()
dateMin.setMinutes(dateMin.getMinutes() - dateMin.getTimezoneOffset())
inputFecha.value = // to set default value too...
inputFecha.min = dateMin.toISOString().split('T')[0]
}
<input type="date" id="fecha" />
If you don't want to code anything with the time zone offset,
the Html5 do it for you:
const inputFecha = document.querySelector('#fecha')
deshabilitarFechasAnterior();
function deshabilitarFechasAnterior()
{
inputFecha.valueAsDate = new Date()
inputFecha.min = inputFecha.value
}
<input type="date" id="fecha" />
Using Javascript
function deshabilitarFechasAnterior() {
const inputFecha = document.querySelector('#fecha');
// To set a custom date as a minimum date, create date object for that date
// const fechaAhora = new Date("2022-05-11");
const fechaAhora = new Date(); // Default today's date
const year = fechaAhora.getFullYear();
const mes = (fechaAhora.getMonth() + 1).toString().padStart(2, '0');
const dia = (fechaAhora.getDate()).toString().padStart(2, '0');
const fechaDeshabilitar = `${year}-${mes}-${dia}`;
inputFecha.setAttribute("min", fechaDeshabilitar);
}
deshabilitarFechasAnterior();
<input type="date" id="fecha" />
Using HTML by adding min/max attributes.
<input id="fecha" type="date" min="2022-05-10" max="2022-05-25" />
I created a calendar using React and date-fns, following this tutorial - https://medium.com/#w.difulvio523/create-a-custom-hooks-calendar-in-react-e50bbba456e1
Then I added a functionality in cell function, where it creates and mapped the days in month,
to fetch the schedule from the mongoDB.
But the schedule renders on its actual day + 1, t.ex if the schedule is today, it will render on date tomorrow, in Europe/Berlin time zone.
But it will render correctly in Brazil time zone.
You can check it here in this codepen - https://codepen.io/luispaulopinto/pen/abNNmZa
this is how that cell function looks like
const cells = () => {
const monthStart = startOfMonth(currentDate)
const monthEnd = endOfMonth(monthStart)
const startDate = startOfWeek(monthStart, {weekStartsOn: 1})
const endDate = endOfWeek(monthEnd)
const dateFormat = "d"
const rows = []
let days = []
let day = startDate
let formattedDate = ""
while (day < endDate) {
for (let i = 0; i < 7; i++) {
formattedDate = format(day, dateFormat)
const cloneDay = day
//here get the schdules
//and render in cells.
//if the schduels.date is same as 'day' or 'clone day',
//render <Link/> to Exercise element with corresponding ID
// //split and reforamt the cloneDay to compare with schedule object's date
const formatCloneDay = day.toISOString().split('T')[0]
// console.timeLog(formatCloneDay)
const scheduleElements = exerciseScheduleArray.map(schedule => {
//reformat for the compare with formatCloneday
const formatScheduleDate = schedule.date.split('T')[0]
const hasMatchingDays = formatScheduleDate.toString() === formatCloneDay.toString()
if(hasMatchingDays) {
return (
<Link className="schedule-link" to={`/exercise/${schedule.exercise}`} key={schedule._id}>
<span>{schedule.bodySection} {schedule.duration}</span>
</Link>
)
}
})
days.push(
<div
className={`column cell ${
!isSameMonth(day, monthStart) ? "disabled" :
isSameDay(day, selectedDate) ? "selected" : "" }`}
key={day}
onClick={() => onClickDate(cloneDay)}
>
<span className="number">{formattedDate}</span>
<span className="bg">{formattedDate}</span>
{scheduleElements}
</div>
)
//this will increase the day value by 1 each time it iterates
day = addDays(day, 1)
}
rows.push(
<div className="row" key={day}> {days} </div>
)
//if 7 days has been pushed to the rows, delete the days
//so it could start a new row with new days
days = []
}
return <div className="body">{rows}</div>
}
I wonder what could be causing this issue?
And how can I get the correct result also in Europe time zone?
I searched and found this thread - https://github.com/date-fns/date-fns/issues/376
and also tried with moment.js to see if it works correctly, but it was the same result with
moment.js
My guess now is that
a. how the Date object is created, and its UTC format is resulting different behaviour based on the time zone.
b. day value is day + 1, inside of the if(hasMatching) statement. And I wonder if this also effects how it renders the schedule element.
How to check if time is the same for Moment objects with different dates?
For example I have object like
const endDate = moment().add(30, 'days').endOf('day');
and I want to check if some moment object is endOf day.
private isEndOfDay(dateTime: string) {
const m = moment().endOf('day');
return m.isSame(dateTime, 'minute');
}
const receivedDateFormat: string = 'YYYY-MM-DD hh:mm:ss';
this.isEndOfDay(this.endDate.format(this.receivedDateFormat))
But for this case, when I pass "minute" parameter, it will check minute, hour, day, month and year... which isn't what I want to check.
The part of the documentation that explains that behaviour is
When including a second parameter, it will match all units equal or larger. Passing in month will check month and year. Passing in day will check day, month, and year.
So, if you just want to compare the minutes, you'll need to do something like
endDate.minute() === startDate.minute()
To compare the time only, format() the dates
endDate.format('HH:mm:ss') === startDate.format('HH:mm:ss')
To compare only time part you can set a given date (year, month and day) to your input.
Please note that passing 'minute' to isSame will ignore seconds.
Here a live sample:
function isEndOfDay(dateTime) {
let m = moment().endOf('day');
let m2 = moment(dateTime);
m2.set({
y: m.year(),
M: m.month(),
D: m.date()
});
return m.isSame(m2, 'minute');
}
var endDate = moment().add(30, 'days').endOf('day');
const receivedDateFormat = 'YYYY-MM-DD hh:mm:ss';
var ret = isEndOfDay(endDate.format(this.receivedDateFormat))
console.log(ret);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Another way to to is checking only units that matter for you:
function isEndOfDay(dateTime) {
let m = moment().endOf('day');
let m2 = moment(dateTime);
if( m.hours() === m2.hours() &&
m.minutes() === m2.minutes() &&
m.seconds() === m2.seconds() ){
return true;
}
return false;
}
var endDate = moment().add(30, 'days').endOf('day');
const receivedDateFormat = 'YYYY-MM-DD hh:mm:ss';
var ret = isEndOfDay(endDate.format(this.receivedDateFormat))
console.log(ret);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
See Get + Set section of the docs to see how to get and set units of moment objects.
I know this question has been asked a thousand times, but im trying to get javascript to display me the days between two dates. I have seen this post:How do i get the number of days between two dates in javascript
From one of the comments I have used this code:
<input type="text" name="sod" class="startd" value="10/02/2016" />
<input type="text" name="dos" class="endd" value="12/02/2016" />
<script>
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
}
alert(daysBetween($('.startd').val(), $('.endd').val()));
</script>
The reulst from the javascript give 61 days, but I want it to read as dd/mm/yyyy not mm/dd/yyyy as it currently is, so the result should be 2 days.
I have tried removing the treatAsUTC parts but it then desont give any answer at all.
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return (endDate - startDate) / millisecondsPerDay;
}
alert(daysBetween($('.startd').val(), $('.endd').val()));
can any one help or guide me in the right direction?
Thanks in advance.
Ian
The reulst from the javascript give 61 days, but I want it to read as dd/mm/yyyy not mm/dd/yyyy as it currently is, so the result should be 2 days.
So you just need to parse the date correctly. The original was:
function parseDate(str) {
var mdy = str.split('/')
return new Date(mdy[2], mdy[0]-1, mdy[1]);
}
Which parses a date in m/d/y format, so to support d/m/y, just change the last line to:
return new Date(mdy[2], mdy[1]-1, mdy[0]);
Tidying up the code a bit, you might end up with something like:
// Parse a date in d/m/y format as UTC
function treatAsUTC(s) {
var b = s.split(/\D/);
return new Date(Date.UTC(b[2], b[1]-1, b[0]));
}
function daysBetween(startDate, endDate) {
startDate = treatAsUTC(startDate);
endDate = treatAsUTC(endDate);
return (endDate - startDate) / 8.64e7;
}
function calcDiff() {
document.querySelector('#result').value =
(daysBetween(document.querySelector('#sod').value,
document.querySelector('#dos').value));
}
<input type="text" id="sod" class="startd" value="10/02/2016" />d/m/y
<input type="text" id="dos" class="endd" value="12/02/2016" />d/m/y
<br>
<button onclick="calcDiff()">Calculate difference in days</button>
<input type="text" id="result" readonly>Days
But you don't actually need UTC, you can just round the result. If parsing dates, the milliseconds will only ever be out by the daylight saving change, rounding to the nearest whole day fixes that. But I guess it's nice using UTC as it doesn't need rounding.
I'm trying to get the current date without the time and store it in a variable, within JavaScript. It needs to be without time as I'm converting it to an epoch date, with which I will use to measure the past 24 hours (if date is within 24 hours then it will be displayed). The problem is that with the added time, it doesn't match as within the last 24 hours.
e.g. it returns the date as the following when converted to epoch: 1408704590485
I want it to be like 1408662000000
I'm not to sure how to do this.
Code - How the current days epoch date is currently being stored -
var epochLoggingFrom;
var epochLoggingTo;
$(document).ready(function () {
epochLoggingFrom = dateToEpoch(new Date());
epochLoggingTo = dateToEpoch(new Date());
}
dateToEpoch function -
function dateToEpoch(thedate) {
return thedate.getTime();
}
Try this:
function dateToEpoch(thedate) {
var time = thedate.getTime();
return time - (time % 86400000);
}
or this:
function dateToEpoch2(thedate) {
return thedate.setHours(0,0,0,0);
}
Example : http://jsfiddle.net/chns490n/1/
Reference: (Number) Date.prototype.setHours(hour, min, sec, millisec)
Try this:
var nowDate = new Date();
var date = nowDate.getFullYear()+'/'+(nowDate.getMonth()+1)+'/'+nowDate.getDate();
Note: Adjust format as you want, like reorder day, month, year, remove '/' and get combined date etc.
or use this:
dateToEpoch(new Date().toLocaleDateString())
I tried using javascript. this method returns the current date in "DD/MM/YYYY" format.
getCurrentDate() {
const t = new Date();
const date = ('0' + t.getDate()).slice(-2);
const month = ('0' + (t.getMonth() + 1)).slice(-2);
const year = t.getFullYear();
return `${date}/${month}/${year}`;
}