This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 5 years ago.
Really not sure where I'm going wrong here.
I have some JavaScript to sort a table by date value:
function sortByDate() {
if (jQuery("#web-orders .data-table tbody").length > 0) {
var tbody = document.querySelector("#web-orders .data-table tbody");
var rows = [].slice.call(tbody.querySelectorAll("tr"));
}
if (jQuery("#store-orders .data-table tbody").length > 0) {
var tbodyStore = document.querySelector("#store-orders .data-table tbody");
var rowsStore = [].slice.call(tbodyStore.querySelectorAll("tr"));
rowsStore.forEach(function (entry) {
rows.push(entry);
});
}
rows.sort(function (a, b) {
console.log("a.cells[2].innerHTML = " + a.cells[2].innerHTML);
console.log("b.cells[2].innerHTML = " + b.cells[2].innerHTML);
a = new Date(Date.parse(a.cells[2].innerHTML));
b = new Date(Date.parse(b.cells[2].innerHTML));
console.log("a = " + a);
console.log("b = " + b);
return a - b;
});
rows.forEach(function (v) {
tbody.appendChild(v); // note that .appendChild() *moves* elements
});
}
Now here is some of the console output with the invalid dates:
a.cells[2].innerHTML = 28/11/2017 1:49:37 PM
b.cells[2].innerHTML = 5/09/2017 6:27:35 AM
a = Invalid Date
b = Tue May 09 2017 06:27:35 GMT+0930 (Cen. Australia Standard Time)
a.cells[2].innerHTML = 28/11/2017 1:49:37 PM
b.cells[2].innerHTML = 24/09/2017 6:12:48 PM
a = Invalid Date
b = Invalid Date
Does anyone know why this might be happening? It's got me stumped.
Date.parse uses RFC 2822 formatting and doesn't allow to specify a custom format. Though, if your input is consistently in the DD/MM/YYYY h:m:s AM/PM format, then you can use split to do the parsing yourself and manually create a Date object.
parseDate(a.cells[2].innerHTML);
parseDate(b.cells[2].innerHTML);
function parseDate(str) {
// Split into date, time, and AM/PM
var parts = str.split(" ");
// Split and parse the day, month, and year
var date = parts[0].split("/");
var day = parseInt(date[0]);
var month = parseInt(date[1]) - 1;
var year = parseInt(date[2]);
// Split and parse the hours, minutes, and seconds
var time = parts[1].split(":");
var hour = parseInt(time[0]);
var minute = parseInt(time[1]);
var second = parseInt(time[2]);
// Add 12 hours to the time if it's in the afternoon
if (parts[2] == "PM") { hour += 12; }
// Build and return our Date object
return new Date(year, month, day, hour, minute, second);
}
As others have mentioned, you can also use Moment to make things easier.
Related
This question already has answers here:
Where can I find documentation on formatting a date in JavaScript?
(39 answers)
Closed 4 years ago.
I want to the current date/time formatted in this format:
year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second+':'+milli;
Currently I'm doing it as such. Is there a more elegant approach without the use of external libraries like moment.js?
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth()+1;
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
var milli = now.getMilliseconds();
if(month.toString().length == 1) {
var month = '0'+month;
}
if(day.toString().length == 1) {
var day = '0'+day;
}
if(hour.toString().length == 1) {
var hour = '0'+hour;
}
if(minute.toString().length == 1) {
var minute = '0'+minute;
}
if(second.toString().length == 1) {
var second = '0'+second;
}
if(milli.toString().length == 1) {
var milli = '0'+milli;
}
var m_session_startTime = year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second+':'+milli;
Leverage template literals instead of concatenation and padStart() to fill leading zeros.
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const day = String(now.getDate()).padStart(2, "0");
const hour = String(now.getHours()).padStart(2, "0");
const minute = String(now.getMinutes()).padStart(2, "0");
const second = String(now.getSeconds()).padStart(2, "0");
const milli = String(now.getMilliseconds()).padStart(4, "0");
const m_session_startTime = `${year}-${month}-${day} ${hour}:${minute}:${second}:${milli}`;
console.log(m_session_startTime);
You could use moment.js, it really helps you with formatting dates.
console.log(moment().format('YYYY-MMMM-DD h:mm:ss:SSS'));
<script src="https://momentjs.com/downloads/moment.min.js"></script>
This command does the job pretty well. moment() is a date object, when there are no arguments given like in this example it takes the current time but you can also use moment("2018-12-4") for specific dates.
You can then format the date according to your need,
YYYY is the full year (2018)
MMMM is the full month name (July)
(you can also use MMM for the short version of the month name)
DD is the day as a number (24)
(you can also use dddd for the full name of the day or ddd for the short name)
h is the hour as number (22)
mm is the minute as a number (23)
ss is the second as a number (as an example 22)
SSS is the millisecond as a number (example 245)
Try this?
let date = new Date();
let jsonDate = date.toJSON();
jsonDate = jsonDate.replace(/[TZ]/g, " ");
jsonDate = jsonDate.replace(/\./g, ":");
console.log(jsonDate);
> 2018-07-24 20:32:06:435
Alternatively, if you want to split the entire thing into substrings:
let date = new Date();
let jsonDate = date.toJSON();
jsonDate = jsonDate.replace(/[TZ]/g, " ");
jsonDate = jsonDate.replace(/\./g, ":");
let dateTime = jsonDate.split(" ");
let dt = dateTime[0].split("-");
let tt = dateTime[1].split(":");
let year = dt[0];
let month = dt[1];
let day = dt[2];
let hour = tt[0];
let minute = tt[1];
let second = tt[2];
let mili = tt[3];
console.log(jsonDate);
console.log(dateTime[0]);
console.log(dateTime[1]);
console.log([year, month, day, hour, minute, second, mili].join("~"));
console.log("Date: " + [year, month, day].join("-") + " Time: " + [hour, minute, second, mili].join(":"));
> 2018-07-24 21:03:05:706
> 2018-07-24
> 21:03:05:706
> 2018~07~24~21~03~05~706
> Date: 2018-07-24 Time: 21:03:05:706
As you might have noticed from this response, I work with databases. I have heavy bash, javascript, php, sql, golang background.
Use a moment.js. Great library that is designed to exactly what you would like. You can use the .format option.
var now = moment().format('YYYY-MM-DD HH:mm:ss.SSS');
$('#timeval').text(now);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Current Time: <br>
<a id="timeval"></a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
https://momentjs.com/
This question already has answers here:
Get String in YYYYMMDD format from JS date object?
(53 answers)
Closed 5 years ago.
Write a function that converts user entered date formatted as M/D/YYYY to a format required by an API (YYYYMMDD). The parameter "userDate" and the return value are strings.
For example, it should convert user entered date "12/31/2014" to "20141231" suitable for the API.
i tried:
function formatDate(userDate) {
// format from M/D/YYYY to YYYYMMDD
a = new Date(userDate);
y = a.getFullYear();
m = a.getMonth();
d = a.getDate();
return y.toString() + m.toString() + d.toString();
}
console.log(formatDate("12/31/2014"));
where is the problem??
The issue is that getMonth() returns a month index from 0 to 11, so December appears as 11 and not 12.
String#split() the date on / and then concat the generated date, month and year.
function AddLeadingZero(num) {
return (num < 10 ? '0' : '') + num;
}
function formatDate(userDate) {
var [month, day, year] = userDate.split('/');
return year + AddLeadingZero(month) + AddLeadingZero(day);
}
console.log(formatDate("12/31/2014"));
console.log(formatDate("10/1/2014"));
var convertDate = function(usDate) {
var dateParts = usDate.split(/(\d{1,2})\/(\d{1,2})\/(\d{4})/);
return dateParts[3] + dateParts[1] + dateParts[2];
}
var inDate = "12/31/2014";
var outDate = convertDate(inDate);
alert(outDate);
I need the date of last September with moment.js - but dynamically.
Current Date
currentDate:string = moment().format('YYYY-MM'); // This will be 2017-10
How to know when the last september was from the current date? I need somethink like this:
lastSteptember = moment(this.currentDate).getDateOfLast('september').format('YYYY-MM');
So the result from now would be:
2017-09
But 3 months ago the result would have been another:
2016-09
How do I can handle this with moment.js?
I dont know how to make it work with moment. But you can use my function to get last month by month number:
var getLastMonth = function(month){
if(month<1 || month>12) return undefined;
let year = (month<=moment().month())? (moment().year()) : (moment().year()-1);
return moment(month + "-" + year, "MM-YYYY");
}
Use it:
getLastMonth(11); //return 11-2016
getLastMonth(10); //return 10-2017
getLastMonth(9); //return 09-2017
I found a pretty solution and solved it like this:
currentYear: number = moment().year();
lastYear: number = moment().subtract(1, 'years').year();
nextYear: number = moment().add(1, 'years').year();
if(moment().isSameOrAfter(this.currentYear + '-09-01', 'month')) {
this.currentServiceYearStartDate = this.currentYear + '-09-01';
this.currentServiceYearEndDate = this.nextYear + '-08-31';
} else {
this.currentServiceYearStartDate = this.lastYear + '-09-01';
this.currentServiceYearEndDate = this.currentYear + '-08-31';
}
console.log('Startdate: ' + this.currentServiceYearStartDate);
console.log('Enddate: ' + this.currentServiceYearEndDate);
https://momentjs.com/docs/#/query/is-same-or-after/
This function will return the month of the previous year if the given month is lower than the current month, otherwise it will return the month with the current year.
function getMonthWithPresentOrPastYear(month, format) {
currentMonth = parseInt(moment().format('M'));
givenMonth = parseInt(moment().month(month).format('M'));
format = format || 'YYYY-MM';
return (givenMonth >= currentMonth) ?
moment().month(month).format(format) : // Present
moment().month(month).subtract(1, 'year').format(format); // Past
};
getMonthWithPresentOrPastYear('January'); // returns '2016-01'
getMonthWithPresentOrPastYear('September'); // returns '2016-09'
getMonthWithPresentOrPastYear('October'); // returns '2017-10'
getMonthWithPresentOrPastYear('December', 'YYYY/DD'); // returns '2017/12'
You can try the following :
Object.getPrototypeOf(moment()).getLast = function(month,format="YYYY-MM"){
var date;
if(this.diff("01 "+month+" "+this.year()) >= 0 || this.format("MMMM").toLowerCase() === month.toLowerCase)
date = moment(this).month(month);
else
date = moment(this).month(month).subtract(1,"years");
return date.format(format);
});
In the above JavaScript we check whether the month has passed in the current moment object.
This allows us to directly check from any moment object and of any month eg:
var customDate = moment("01 December 2001");
customDate.getLast("September"); //"2001-09"
Ive got a piece of JS that needs to validate and compare a start date and time against an end date and time.
So in other words end date & time cannot be less than start date and time.
Now the problem.
I originally only accepted the time in 24 hour(military) Format. but now let the user choose between 12 hour or 24 hour.
Example 13:00 or 1:00 PM
This piece of code work for 24 hour time format, but not for 12, its 12:00 PM that causes the problem.
So I need to adapt this piece of code to work for either 12 hour or 24 hour, but im not sure how to do this.
function validateStartEndTime() {
var date = document.getElementById("datepickerStart").value;
var dateEnd = document.getElementById("datepickerEnd").value;
if (!isValidDate(date)) {
alert("Not Valid Date");
return false;
}
var start = document.getElementById("timepicker").value;
var end = document.getElementById("timepickerEnd").value;
var stDate = new Date(parse(date +" "+ start));
var enDate = new Date(parse(dateEnd + " "+ end));
var compDate = enDate - stDate;
if (compDate >= 0)
return true;
else {
alert("End time must be greater than Start Time ");
return false;
}
}
You could write a function that converts time in 12 hour format to time in 24 hour format, something like:
function convertTo24HourFormatIfNeeded(timeString) {
var is12HourFormat = timeString.indexOf("M") !== -1;
if (is12HourFormat) {
var isPm = timeString.indexOf("PM") !== -1;
var timeStringNoSuffix = timeString.split(" ")[0];
if (isPm) {
var hoursAndMinutes = timeStringNoSuffix.split(":");
var hours = hoursAndMinutes[0];
var convertedHours = (Number(hours) + 12);
var minutes = hoursAndMinutes[1];
return convertedHours + ":" + minutes;
} else {
return timeStringNoSuffix;
}
} else {
return timeString;
}
}
Then use it in your code:
var start = convertTo24HourFormatIfNeeded(document.getElementById("timepicker").value);
var end = convertTo24HourFormatIfNeeded(document.getElementById("timepickerEnd").value);
If you're not adverse to using external libraries, i found MomentJs to be very handy working with dates, and among other things it allows to parse the date in a user-defined format, so you could build your date string accordingly to user selection of AM/PM or 24-hour format and feed it to moment js.
I am trying to compare two dates which are in Finnish time form like this: dd.mm.YYYY or d.m.YYYY or dd.m.YYYY or d.mm.YYYY.
I am having a hard time finding out how to do this, my current code won't work.
<script src="inc/date-fi-FI.js" type="text/javascript"></script>
<script type="text/javascript">
function parseDate() {
var date = $('#date').val();
var parsedDate = Date.parse(date);
alert('Parsed date: '+parsedDate);
}
function jämförMedIdag (datum) {
if (datum == null || datum == "") {
alert('Inget datum!');
return;
}
/*resultat = Date.compare(Datum1,Datum2);
alert(resultat); */
var datum = Date.parse(datum);
var dagar = datum.getDate();
var månader = datum.getMonth();
var år = datum.getYear();
var nyttDatum = new Date();
nyttDatum.setFullYear(år,månader,dagar);
var idag = new Date();
if(nyttDatum>idag) {
var svar = nyttDatum - idag;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
} else {
var svar = idag - nyttDatum;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
}
}
</script>
This code will try to calculate the difference between two dates, one of them being today. No success lolz.
Thanks in advance!
My final code (thanks RobG!):
function dateDiff(a,b,format) {
var milliseconds = toDate(a) - toDate(b);
var days = milliseconds / 86400000;
var hours = milliseconds / 3600000;
var weeks = milliseconds / 604800000;
var months = milliseconds / 2628000000;
var years = milliseconds / 31557600000;
if (format == "h") {
return Math.round(hours);
}
if (format == "d") {
return Math.round(days);
}
if (format == "w") {
return Math.round(weeks);
}
if (format == "m") {
return Math.round(months);
}
if (format == "y") {
return Math.round(years);
}
}
It is not fully accurate, but very close. I ended up adding some addons to it to calculate in day week month year or hour, anyone can freely copy and use this code.
If you are using Datejs, and the optional time.js module, you can run your calculations with the following code by creating a TimeSpan object:
Example
// dd.mm.YYYY or d.m.YYYY
// dd.m.YYYY or d.mm.YYYY
var start = Date.parse("20.09.2011");
var end = Date.parse("28.09.2011");
var span = new TimeSpan(end - start);
span.days; // 8
Of course the above could be simplified down to one line if you really want to be extra terse.
Example
new TimeSpan(Date.parse(end) - Date.parse(start)).days; // pass 'end' and 'start' as strings
Hope this helps.
If your dates are strings in the common form d/m/y or some variation thereof, you can use:
function toDate(s) {
var s = s.split('/');
return new Date(s[2], --s[1], s[0]);
}
You may want to validate the input, or not, depending on how confident you are in the consistency of the supplied data.
Edit to answer comments
To permit different separators (e.g. period (.) or hyphen (-)), the regular expression to split on can be:
var s = s.split(/[/\.-]/);
The date will be split into date, month and year numbers respectively. The parts are passed to the Date constructor to create a local date object for that date. Since javascript months are zero indexed (January is 0, February is 1 and so on) the month number must be reduced by one, hence --s[1].
/Edit
To compare two date objects (i.e get the difference in milliseconds) simply subtract one from the other. If you want the result in days, then divide by the number of milliseconds in a day and round (to allow for any minor differences caused by daylight saving).
So if you want to see how many days are between today and a date, use:
function diffToToday(s) {
var today = new Date();
today.setHours(0,0,0);
return Math.round((toDate(s) - today) / 8.64e7);
}
alert(diffToToday('2/8/2011')); // -1
alert(diffToToday('2/8/2012')); // 365
PS. The "Finnish" data format is the one used by the vast majority of the world that don't use ISO format dates.
Using the Date object:
var today = Date.today();
var dateToday = Date.parse(today.toString('MMMM d, yyyy'));
var prevMonthDate = dateToday.addDays(-30);
var difference = (dateToday - prevMonthDate)/86400000;
console.log(difference); //will give you the difference in days.