Date sort javascript - javascript

I have this code:
<script type="text/javascript">
function abc(objarray) {
objarray = objarray.sort(function (a, b) { return new Date(a).getTime() - new Date(b).getTime() });
alert(objarray);
}
objarray = ["16.08.1993 11:13", "16.08.1994 11:12", "13.08.1994 11:12", "13.08.1996 10:12", "08.08.1996 10:12"];
abc(objarray);
</script>
Date time format: dd.MM.yyyy HH:MM
I want to sort so that I can get the latest date first, but its not working.

You need to switch a and b and take another string for comparing, like
1993-08-16 11:13
the ISO 6801 data and time format, wich is comparable with String#localeCompare.
function abc(objarray) {
objarray = objarray.sort(function(a, b) {
function getISO(s) {
return s.replace(/(..).(..).(....) (.....)/, '$3-$2-$1 $4');
}
return getISO(b).localeCompare(getISO(a));
});
}
var objarray = ["16.08.1993 11:13", "16.08.1994 11:12", "13.08.1994 11:12", "13.08.1996 10:12", "08.08.1996 10:12"];
abc(objarray);
console.log(objarray);

Try this:
String.prototype.getCorrectDate = function () {
var date = this.split(' ')[0];
var hours = this.split(' ')[1];
var dateSplitted = date.split('.');
return new Date(dateSplitted[2] + '.' + dateSplitted[1] + '.' + dateSplitted[0] + ' ' + hours);
};
var dates = ["16.08.1993 11:13", "16.08.1994 11:12", "13.08.1994 11:12", "13.08.1996 10:12", "08.08.1996 10:12"];
var sorted = dates.sort(function(a, b) {
return b.getCorrectDate() - a.getCorrectDate();
});
alert('First from sorted: '+ sorted[0]);
alert('Last from sorted: '+ sorted[sorted.length - 1]);
https://jsfiddle.net/Lcq6wqhb/
Javascript's native method sort is used to sorting arrays, and we can pass callback function let's say sorting behavior(Sorting an array of JavaScript objects).
But before sorting we need to transform date strings to correct format, to be accepted new Date(dateString) as parameter, otherwise it gives error Invalid Date.
I'm transorming dd.mm.yyyy hh:MM to yyyy.mm.dd HH:MM using getCorrectDate method

Related

add leading zero to simple timestamp addition JavaScript function

I am trying to write a javascript function to sum up two timestamp strings, like 00:04:02 and 00:05:43
I have this function which works, but returns a value like: 0:9:45, I'm trying to improve it so there is a leading zero for the minutes section so it looks more like: 0:09:45 but im having trouble doing so and was wondering if anyone could help me:
function sum(date1, date2){
date1 = date1.split(":");
date2 = date2.split(":");
const result = [];
date1.reduceRight((carry,num, index) => {
const max = [24,60,60][index];
const add = +date2[index];
result.unshift( (+num+add+carry) % max );
return Math.floor( (+num + add + carry) / max );
},0);
return result.join(":");
}
console.log(sum('00:05:43', '00:04:02'))
Pad each digit?
return result.map(r => String(r).padStart(2, "0")).join(":");
If you use the built-in Date methods, you don't need to parse times or do math yourself.
'use strict';
function sumTimestamps(a, b) {
const [A, B] = [a, b].map((x) => new Date('1970-01-01T' + x + '.000Z'));
return new Date(A.getTime() + B.getTime()).toUTCString().split(' ')[4];
}
const sum = sumTimestamps('00:04:02', '00:05:43');
console.log(sum);
// => 00:09:45

How to format a String to Date in React Native?

I am getting a Date as a String in this format from the server yyyyMMdd:hhmmss.
Is there a generic way to format this string to a Date object?
EDIT
formatDate = (data) => {
return data.slice(6, 8) + "." + data.slice(4, 6) + "." + data.slice(0, 4) + " " + data.slice(9, 11) + ":" + data.slice(11, 13)
}
The way you're reformatting the string is fine, even though it seems like a lot of code for a small job, slice is pretty fast. Some alternatives (not necessarily "better", just different):
// Reformat yyyyMMdd:hhmmss as dd.mm.yyyy hh:mm:ss
function formatMatch(s) {
let b = s.match(/\d\d/g) || [];
return `${b[3]}.${b[2]}.${b[0]}${b[1]} ${b[4]}:${b[5]}:${b[6]}`;
}
function formatReplace(s) {
return s.replace(/(\d{4})(\d{2})(\d{2}):(\d{2})(\d{2})(\d{2})/, '$3.$2.$1 $4:$5:$6');
}
formatDate = (data) => {
return data.slice(6, 8) + "." + data.slice(4, 6) + "." + data.slice(0, 4) + " " + data.slice(9, 11) + ":" + data.slice(11, 13)
}
let s = '20200323:123445';
console.log(formatDate(s));
console.log(formatMatch(s));
console.log(formatReplace(s));
If you want to get an actual Date object, then instead of using the bits to create another string, just pass them into the constructor:
// Parse yyyyMMdd:hhmmss to Date object
function parseD(s) {
let b = s.match(/\d\d/g) || [];
return new Date(b[0]+b[1], b[2]-1, b[3], b[4], b[5], b[6]);
}
let s = '20200327:134523';
console.log(parseD(s).toString());
The use of || [] means that if there's no match, an empty array is returned so all the b[*] terms return undefined and the result is an invalid date.
The above uses match, but slice or substring can be used the same way.

Javascript Get Sequential Dates in Array cross week and month

I have an array with the following values (example):
[
1491408000000,
1491494400000,
1491753600000,
1493222400000,
1493308800000,
1493568000000
]
Where the index is a date time. The date time will always be at 12:00:00 on a date.
In this example, the first 3 dates are consecutive cross weekend (weekend is holiday so count as leave), then another group of 3 dates cross weekend and month.
Now, what I am trying to do is find sequential dates (cross week and month) and put them into an array as follows:
[
1491408000000,
1491494400000,
1491753600000
],
[
1493222400000,
1493308800000,
1493568000000
]
I have tried the following code to get the sequential dates but this cannot cross week and month, how to modify the code to get above result? Any help would be much appreciated!
var timeValue = new Date(dateReview).getTime();
valueCon.push(timeValue);
var k = 0;
sortedValue[k] = [];
valueCon.sort( function ( a, b ){
return +a > +b ? 1 : +a == +b ? 0: -1;
})
.forEach( function( v , i ){
var a = v,b = valueCon[i+1]||0;
sortedValue[k].push( +a );
if ( (+b - +a) > 86400000) {
sortedValue[++k] = []
}
return 1;
});
sortedValue.sort( function ( a,b ){
return a.length > b.length ? -1: 1;
});
This requires help from a function to test if two dates are in the same week. The following goes over the set of time values provided in an array and puts the first value into an array within the array. For each subsequent value, it tests if it's in the same week as the first value in each array within the outer array.
If it's in the same week as the first value in any existing array, it's pushed into that array. Otherwise, it's put in a new array and pushed into the outer array.
There may be a neater way to implement the algorithm, but I'll leave that for others.
Due to time zone differences, they are adjusted to the host time zone based on the original time values representing noon in the source time zone.
// Given 2 dates, return true if they are in the same week (Mon to Sun).
// Otherwise, return false
function sameWeek(a, b){
var e = new Date(+a);
// Week starts at 00:00:00.000 on Monday on or before date
var s = new Date(e.setDate(e.getDate() - ((e.getDay()||7) -1)));
s.setHours(0,0,0,0);
// Week ends at 23:59:59.999 the following Sunday
e.setDate(e.getDate() + 6);
e.setHours(23,59,59,999);
// Test b and return value
return b >= s && b <= e;
}
// Given time value for UTC-0400, adjust to same date and time
// in local time zone and return a date
function adjust(n) {
var d = new Date(n);
d.setMinutes(d.getMinutes() - 240 + d.getTimezoneOffset());
return d;
}
var result = [1491408000000,1491494400000,1491753600000,1493222400000,1493308800000,1493568000000
].reduce(function(acc, n) {
var d = adjust(n);
var used;
if (acc.length != 0) {
used = acc.some(function(arr) {
if (sameWeek(adjust(arr[0]), d)) {
arr.push(n);
return true;
}
});
}
if (!used || acc.length == 0) {
acc.push([n]);
}
return acc;
},[]);
// Result array
console.log(result);
// Printed as date strings adjusted to same host local time
result.forEach(arr => {
arr.forEach(n => console.log(adjust(n).toString()))
console.log('\n');
});
Manipulation of timestamps is a pain. JavaScript has a built-in Date type, as you know, and I would suggest you use it. Date#getUTCDay returns the day of the week as an integer (for reference, 4 is Friday, or the day before a weekend), while Date#setUTCDate and Date#getUTCDate together allow you to adjust the date in day increments (and have it overflow/underflow to the next/previous month). Thus, to determine whether a timestamp b follows "sequentially" (excluding weekends) after a, you can use:
function sequential (a, b) {
a = new Date(a)
return a.setUTCDate(a.getUTCDate() + (a.getUTCDay() === 4 ? 3 : 1)) === b
}
Grouping is just an exercise after that; the code above contains all of the real logic behind this solution.
Example Snippet
var dates = [
1491408000000,
1491494400000,
1491753600000,
1493222400000,
1493308800000,
1493568000000
]
function sequential (a, b) {
a = new Date(a)
return a.setUTCDate(a.getUTCDate() + (a.getUTCDay() === 4 ? 3 : 1)) === b
}
function groupSequential(dates) {
if (dates.length < 2) return [dates.slice()]
dates.sort(function(a, b) { return a - b })
var result = [], group
for (var i = 0; i < dates.length; i++) {
sequential(dates[i - 1], dates[i]) || result.push(group = [])
group.push(dates[i])
}
return result
}
console.log(groupSequential(dates))

How to retain leading zeroes when converting String to Number in javascript

How can I convert a string to number without loosing the trailing zeroes
var string1 = '02';
Number(string1); // == 2 - Default output
Number(string1); // == 02 - My requirement
The reason why I want this is: I am passing a date as value to the date HTML element. And the format is yyyy-MM-dd, month and date format is two digits and if I convert the date (string in my case) to number the leading zeroes are being removed.
You can't. A Number is a Number, period. You can make a helper object to have a number and a number leftpad method at your disposal. Something like:
document.querySelector("button").addEventListener("click", setDateValueExample);
var num = XNumber(3);
var result = {
el: document.querySelector("#result"),
log(str) {
this.el.textContent += str + '\n';
}
}
// XNumber usage example
result.log('XNumber(54).lpad(1000000): ' + XNumber(54).lpad(1000000));
// Datefield value from date field formatting example
var d = new Date(document.querySelector("#somedate").value);
result.log('Date formatted: ' +
[XNumber(d.getMonth()+1).lpad(),
XNumber(d.getDate()).lpad(),
d.getFullYear()].join('-'));
// Set date field value from string example
function setDateValueExample() {
document.querySelector("#somedate").value =
document.querySelector("button").getAttribute("data-dateString")
.split("/")
.reverse()
.map(function (v) {
return XNumber(v).lpad()
})
.join('-');
}
// The actual Number helper
function XNumber(num) {
return {
num: +num,
lpad (base) {
base = base || 10;
var len = (String(base).length - String(this.num).length)+1;
return len > 0 ? new Array(len).join('0')+this.num : this.num;
}
};
}
<input type="date" id="somedate" value="2017-02-01"/> a date
<button data-dateString="2/3/2017">Set value from string "2/3/2017"</button>
<pre id="result"></pre>
As commented, you can use ("00" + num).slice(-2).
You can try something like this:
function getParsedValue(date) {
var d = date;
if (typeof d === "string") {
d = new Date(date);
}
return [d.getFullYear(), getDoubleDigitString(d.getMonth() + 1), getDoubleDigitString(d.getDate())].join("-")
}
function getDoubleDigitString(num) {
return ("00" + num).slice(-2);
}
var date = new Date();
document.getElementById('txtDate1').value = getParsedValue(date)
document.getElementById('txtDate2').value = getParsedValue("1999/1/2")
<input type="date" id="txtDate1" />
<input type="date" id="txtDate2" />

Sort an array of arrays by date in Javascript

I have an array of arrays which the first field is a date (in string format). I want to sort them by the date (asceding), so I can use it for further calculations.
I identify two tasks on my problem. First, parse strings as dates and then sort.
a = new Date(Date.parse('1/11/2014 13:42:54'));
console.log(a)
Return 11th of January whereas I need 1st of November
Then, I the sorting should work like this:
function compare(a,b) {
if (a[0] < b[0])
return -1;
if (a[0] > b[0])
return 1;
return 0;
}
myarray.sort(compare);
So, how can I solve the problem with the dates to make it works on sorting function?
If your dates are in ISO format you can use such a code:
myarray.sort(function (a, b) {
return (new Date(a[0])).getTime() - (new Date(b[0])).getTime();
});
Just capture the date and month part, swap them and do Date.parse and new Date, like this
function getFormattedDate(dateString) {
var result = dateString.replace(/(\d+)\/(\d+)(.*)/, function (m, g1, g2, g3) {
return g2 + "/" + g1 + g3;
});
return new Date(Date.parse(result));
}
console.log(getFormattedDate('1/11/2014 13:42:54'));
// Sat Nov 01 2014 13:42:54 GMT+0000 (GMT)
Here, the regular expression, (\d+)\/(\d+)(.*) will capture three parts of the string, first (\d+) captures the date part followed by / (escaped as \/) and the month part with another (\d+) and the rest of the string is captured with (.*). Then we return a new string by swapping the positions of g2 and g1 (month and date part).
Note: If all you are trying to do is sorting, then you don't need to create a new Date object. You can simply use the result of Date.parse which is epoch time, like this
function getEpochTime(dateString) {
var result = dateString.replace(/(\d+)\/(\d+)(.*)/, function (m, g1, g2, g3) {
return g2 + "/" + g1 + g3;
});
return Date.parse(result);
}
function comparator(firstDate, secondDate) {
return getEpochTime(firstDate) - getEpochTime(secondDate);
}
and then sort like this
var arr = ['3/11/2014 13:42:54',
'2/11/2014 13:42:54',
'1/12/2014 13:42:54',
'1/11/2014 13:43:54'
];
arr.sort(comparator);
console.log(arr);
would give you
[ '1/11/2014 13:43:54',
'2/11/2014 13:42:54',
'3/11/2014 13:42:54',
'1/12/2014 13:42:54' ]
With moment.js you can create a moment object using the String+Format constructor
moment('1/11/2014 13:42:54', 'DD/MM/YYYY HH:mm:ss')
so, if you have an array of arrays which the first field is a date (in string format):
array_of_arrays = [
['1/11/2014 13:42:54', 'val'],
['2/11/2014 13:42:54', true]
];
for(array in array_of_arrays){
epoch = moment(array.shift,'DD/MM/YYYY HH:mm:ss').unix();
array.unshift(epoch);
}
now, you can just do new Date(epoch) as instead of complex date objects, we have Unix Epoch which can be easily sorted with inbuid Array.sort something like this
function Comparator(a,b){
if (a[0] < b[0]) return -1;
if (a[0] > b[0]) return 1;
return 0;
}
array_of_arrays.sort(Comparator);
so now you have array_of_arrays sorted as per date
Lastly, if you need more precise answer than this, please share some more sample code.
This is problem:
a = new Date(Date.parse('1/11/2014 13:42:54'));
console.log(a)
Return 11th of January whereas I need 1st of November`
Your date format is dd/mm/yyy; Date.parse('1/11/2014 13:42:54') accepts mm/dd/yyyy
Try a date parsing as following:
function parseDate(str) {
var ds = str.match(/(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)/);
// Convert to format: mm/dd/yyyy
return new Date(ds[3], ds[2] - 1, // month is 0-based
ds[1], ds[4], ds[5], ds[6]);
}
var arr = [parseDate('3/11/2014 13:42:54'),
parseDate('2/11/2014 13:42:54'),
parseDate('1/12/2014 13:42:54'),
parseDate('1/11/2014 13:43:54')
];
arr.sort();
Or:
function parseDate(str) {
var ds = str.match(/(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)/);
// Convert to format: mm/dd/yyyy
return new Date(ds[3], ds[2] - 1, // month is 0-based
ds[1], ds[4], ds[5], ds[6]);
}
var arr = ['3/11/2014 13:42:54',
'2/11/2014 13:42:54',
'1/12/2014 13:42:54',
'1/11/2014 13:43:54'
];
arr.sort(function(a, b) {
return parseDate(a) - parseDate(b);
})

Categories