How to only show dates before character /? - javascript

I have an array of ISO 8601 dates intervals (start and end date). how do you only select the dates before slash with javascript (start dates)?
var dates = [
2019-12-31T23:45:00.000-03:00/2020-01-01T10:30:00.000+06:00,
2020-01-01T07:15:00.000+07:00/2019-12-31T16:00:00.000-10:00
]
I would like the result to be
[2019-12-31T23:45:00.000-03:00,2020-01-01T07:15:00.000+07:00]
I tried this string-replace method,
let result = dates.replace(/\/.*/g, '');
but it replaces everything after the first bracket.

The variables dates is an array, so you should iterate on this.
var dates = [
'2019-12-31T23:45:00.000-03:00/2020-01-01T10:30:00.000+06:00',
'2020-01-01T07:15:00.000+07:00/2019-12-31T16:00:00.000-10:00'
]
// [2019-12-31T23:45:00.000-03:00,2020-01-01T07:15:00.000+07:00]
let result = dates.map(date => date.split('/')[0]);
console.log(result);
But be carefull, in your question, your dates variable is not an array of type string. Maybe it's an array of type Date...

I prefer to String.prototype.split() instead of replace. Make an iteration over the array using map(), in every cycle of the iteration split the element (start date / end date) and capture the start date as you expected.
var dates = [
'2019-12-31T23:45:00.000-03:00/2020-01-01T10:30:00.000+06:00',
'2020-01-01T07:15:00.000+07:00/2019-12-31T16:00:00.000-10:00'
]
let results = dates.map(i => i.split('/')[0])
console.log(results)
Output:
[
"2019-12-31T23:45:00.000-03:00",
"2020-01-01T07:15:00.000+07:00"
]

Related

How to turn an array of miliseconds into date format mm-dd-yyyy

i have the next array of dates in miliseconds
const dates = date?.rangeOfDates
console.log(dates)
(4) [1661281243730, 1661454043730, 1661886043730, 1661713243730]
Im trying to turn it into Date format the next way:
const listOfDates = new Date(dates).toLocaleDateString()
It gives me an Invalid Date error in the console but when I try to change it manually in the next way it works good:
console.log(new Date(1661281243730).toLocaleDateString())
--> 8/23/2022
Just use an array map to convert it.
const array = [1661281243730, 1661454043730, 1661886043730, 1661713243730];
array.map(x => new Date(x).toLocaleDateString());
"new Date" will try to create a single date from a single value and "dates" is not a single value but an array.
Try this :
realDates = dates.map(d => new Date(d))
For each value in "dates" it will convert it to a date and you'll get "realDates" array.

How to get difference in dates between to dates in JavaScript

I have a split string lines="Ram Hue, 134, 20.5.1994, 20.4.2004"
and I want to get the difference in dates between to dates 20.5.1994 and 20.5.1994, I tried in JavScript but i'ts not working. Also when trying to extract both dates using
lines[2] lines[3] I'm getting wrong outputs
var date1 = new Date(lines[2])
var date2 = new Date(lines[3])
var diffDays = parseInt((date2-date1)/(1000*60*60*24),10)
console.log(diffDays)
Since lines is a string, lines[2] will just get you the character with index 2 within the string. Instead you need to split the string before:
const arr = lines.split(',');
Then you can access both date strings as arr[2] and arr[3]

Divide the date range given by moment js by weeks

I want to divide a given date range into months. And I want to separate these months according to weeks. I want to get the date from the start date to the end of the month at 7-day intervals. For example: (Like 15/12/2020, 22/12/2020, 29/12/2020 -newMonth- 05/01/2020)
It is difficult to understand with this explanation. After all I want to create a json like this.
Starting Date: 15/11/2020 - End Date: 20/01/2021
[
{
"dates": [
15, // Starting date(15/11/2020)
22, // 1 week later
29 // 1 week later
],
"firstDay": "15/11/2020"
},
{
"dates": [
6,
13,
20,
27
],
"firstDay": "06/12/2020"
},
{
"dates": [
3,
10,
17
],
"firstDay": "03/01/2021"
}
]
There are a few tricks that you can use to create the array structure you want:
Use a while loop, which keeps a current date that is constantly incremented by 7 days, to be compared against the end date. The current date should be initialized using the start date in the beginning of the loop.
To perform the "group by month" in your desired structure, you will need to using an object (which serves as a dictionary). The object will use the month + year combination as key, so that if your date ranges span over multiple years you won't collapse months from different years into the same entry.
For each iteration of the while loop, you construct the key from the current date, and then check if the key exists in your dictionary. If not, then we can push this object into your dictionary:
{
dates: [currentDate],
firstDate: currentDate
}
If it already exists, then you simply push the date into the dates array of the sub-object.
Finally, to convert your dictionary into the array strcuture you wanted, using ES6 Object.values() will work. See proof-of-concept below:
function generateRanges(startDate, endDate) {
let current = moment(startDate, 'DD/MM/YYYY');
const end = moment(endDate, 'DD/MM/YYYY');
// A dictionary to track unique month+year combinations
const daysByMonth = {};
while (current < end) {
// Construct key based on month+year
const key = `${current.month()}${current.year()}`;
const date = current.date();
// If key already exists, then we push into the `dates` array
if (key in daysByMonth) {
daysByMonth[key].dates.push(date);
}
// Otherwise we construct a brand new sub-object
else {
daysByMonth[key] = {
dates: [date],
// Since this is the first time we encounter the key,
// We can assume this is the earliest/first date of the month
firstDate: current.format('DD/MM/YYYY')
}
}
// At the end of the while loop, increment by a week, rinse and repeat
current.add(7, 'days');
}
// Once done, we only want the values in the dictionary
// We don't need to keep the unique month+year key
return Object.values(daysByMonth);
}
const range = generateRanges('15/11/2020', '20/01/2021');
console.log(range);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
The Moment.JS has an API for adding days to a date: the add function.
In order to build your final object, you would start from your startDate, and add 7 days for each loop iteration until reaching the end date. Like this:
let currentDate = moment(startDate);
while(currentDate < endDate) { // Make sure endDate is also a moment object
// Add the current date - you will want to adapt this
dates.push(currentDate.clone()); // Since .add() will mutate the currentDate object, clone the object when adding it to the array so that it's not affected by the add()
// Prepare for the next iteration
currentDate.add({days: 7});
}
As for month changes, remember the last month for every iteration (use month) and create a new object in your final array, then add dates to object instead of the previous one.
Side note: Months are zero-indexed in Javascript, which is not the case for the month day (date)
When dealing with date or datetime is always a good practice to use milliseconds. Also it is space efficient, a long integer = 4kb instead of a Date() object which is 32bytes.
In your case it is very straightforward to convert our dates to milliseconds, find how many weeks are between as integer and then run a loop increment by this iteration.
let from = new Date('2020/11/15').getTime();
let to = new Date('2021/01/20').getTime();
let week = 604800000;
let day = 86400000;
let allWeeks = [];
let current =0;
let weeks = (to-from)/day/7
for (i=0; i<weeks; i++){
allWeeks.push(new Date(from += week).toLocaleDateString())
}
console.log(JSON.stringify(allWeeks))
//["22/11/2020","29/11/2020","06/12/2020","13/12/2020","20/12/2020","27/12/2020","03/01/2021","10/01/2021","17/01/2021","24/01/2021"]
Finally you will have a list applicable for JSON to build any logic you prefer.
I hope to pin point a differed approach to your case!

Find closest next day from dates array, using Moment.js

I have an array:
dates = [
"2019-10-04T12:38:02.506204+00:00",
"2019-10-04T14:59:39.370487+00:00",
"2019-10-04T14:59:50.897597+00:00",
"2019-10-04T14:59:57.344401+00:00",
"2019-10-04T15:00:04.631711+00:00",
"2019-10-04T15:00:13.460667+00:00",
"2019-10-04T15:00:21.672496+00:00",
"2019-10-04T15:00:29.643194+00:00",
"2019-10-04T15:00:37.022307+00:00",
"2019-10-04T15:01:00.134239+00:00",
"2019-10-04T15:01:08.146224+00:00",
"2019-10-04T15:01:15.205999+00:00",
"2019-10-04T15:01:21.877861+00:00",
"2019-10-04T15:01:28.089368+00:00",
"2019-10-04T16:29:05.438103+00:00",
"2019-10-04T16:29:49.927139+00:00",
"2019-10-05T16:35:00.994699+00:00",
"2019-10-06T08:45:47.289637+00:00",
"2019-10-06T08:46:11.294362+00:00",
"2019-10-06T08:46:23.702585+00:00",
"2019-10-06T08:46:33.374726+00:00",
"2019-10-06T08:46:42.726666+00:00",
"2019-10-06T08:46:52.916887+00:00",
"2019-10-06T08:47:02.659273+00:00",
"2019-10-06T16:08:14.975139+00:00",
"2019-10-06T16:08:29.047735+00:00",
"2019-10-06T16:08:42.831487+00:00",
"2019-10-06T16:08:58.472631+00:00",
"2019-10-07T08:32:43.248706+00:00",
"2019-10-07T08:37:00.512249+00:00",
"2019-10-07T08:38:12.188744+00:00",
"2019-10-07T08:40:08.362515+00:00",
"2019-10-07T08:41:57.151322+00:00",
"2019-10-07T08:46:52.107963+00:00",
"2019-10-07T08:53:38.604697+00:00",
"2019-10-07T08:53:53.449463+00:00",
"2019-10-07T09:15:31.659223+00:00"
]
I need to make a switch with two buttons, the first will switch the dates forward, the second - back.
Dates are used from an array.
Help with JS please.
You can use the isBefore method on Moment.js objects. If you pass in the second argument as "day", then it would consider that:
"2019-10-04T12:38:02.506204+00:00" (4th of October) is before "2019-10-05T16:35:00.994699+00:00" (5th of October)
"2019-10-04T12:38:02.506204+00:00" (4th of October) is not before "2019-10-04T14:59:39.370487+00:00" (4th of October)
let dates = [
"2019-10-04T12:38:02.506204+00:00",
"2019-10-04T14:59:39.370487+00:00",
"2019-10-04T14:59:50.897597+00:00",
"2019-10-04T14:59:57.344401+00:00",
"2019-10-04T15:00:04.631711+00:00",
"2019-10-04T15:00:13.460667+00:00",
"2019-10-04T15:00:21.672496+00:00",
"2019-10-04T15:00:29.643194+00:00",
"2019-10-04T15:00:37.022307+00:00",
"2019-10-04T15:01:00.134239+00:00",
"2019-10-04T15:01:08.146224+00:00",
"2019-10-04T15:01:15.205999+00:00",
"2019-10-04T15:01:21.877861+00:00",
"2019-10-04T15:01:28.089368+00:00",
"2019-10-04T16:29:05.438103+00:00",
"2019-10-04T16:29:49.927139+00:00",
"2019-10-05T16:35:00.994699+00:00",
"2019-10-06T08:45:47.289637+00:00",
"2019-10-06T08:46:11.294362+00:00",
"2019-10-06T08:46:23.702585+00:00",
"2019-10-06T08:46:33.374726+00:00",
"2019-10-06T08:46:42.726666+00:00",
"2019-10-06T08:46:52.916887+00:00",
"2019-10-06T08:47:02.659273+00:00",
"2019-10-06T16:08:14.975139+00:00",
"2019-10-06T16:08:29.047735+00:00",
"2019-10-06T16:08:42.831487+00:00",
"2019-10-06T16:08:58.472631+00:00",
"2019-10-07T08:32:43.248706+00:00",
"2019-10-07T08:37:00.512249+00:00",
"2019-10-07T08:38:12.188744+00:00",
"2019-10-07T08:40:08.362515+00:00",
"2019-10-07T08:41:57.151322+00:00",
"2019-10-07T08:46:52.107963+00:00",
"2019-10-07T08:53:38.604697+00:00",
"2019-10-07T08:53:53.449463+00:00",
"2019-10-07T09:15:31.659223+00:00"
]
let currentDate = moment(dates[0]); //pick a spot for the "current time"
//sort the dates to ensure they are sequential
dates.sort();
let nextDate = dates.
filter(isoDate => currentDate.isBefore(isoDate, "day")) //filter anything before the current
[0]; //take the first (lowest) date
console.log(nextDate);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

How to get a string of max date from an array of string dates?

What would be the most elegant way to get max date from an array of strings like below?
var dates = ["2018-12-29T15:23:20.486695Z", "2018-12-29T15:23:21.613216Z", "2018-12-29T15:23:22.695710Z", "2018-12-29T15:23:24.013567Z", "2018-12-29T15:23:25.097649Z", "2018-12-29T15:23:26.692125Z", "2018-12-29T15:23:27.918561Z", "2018-12-29T15:23:29.217879Z", "2018-12-29T15:23:30.468284Z", "2018-12-29T15:23:31.548761Z"]
I have tried:
var timestamps = dates.map(date => Date.parse(date));
var max_date = Math.max.apply(Math, timestamps)
But this leaves me with a timestamp that I would need to convert back to the exact original format (and I don't know how to do that).
​
You could compare the ISO 8601 date like strings and take the greater value.
var dates = ["2018-12-29T15:23:20.486695Z", "2018-12-29T15:23:21.613216Z", "2018-12-29T15:23:22.695710Z", "2018-12-29T15:23:24.013567Z", "2018-12-29T15:23:25.097649Z", "2018-12-29T15:23:26.692125Z", "2018-12-29T15:23:27.918561Z", "2018-12-29T15:23:29.217879Z", "2018-12-29T15:23:30.468284Z", "2018-12-29T15:23:31.548761Z"],
latest = dates.reduce((a, b) => a > b ? a : b);
console.log(latest);
That's the format provided by toISOString on Date. So you take your timestamp value, feed it into new Date, and use toISOString on the result:
console.log(new Date(max_date).toISOString());
Example:
var dates = [
"2018-12-29T15:23:20.486695Z",
"2018-12-29T15:23:21.613216Z",
"2018-12-29T15:23:22.695710Z",
"2018-12-29T15:23:24.013567Z",
"2018-12-29T15:23:25.097649Z",
"2018-12-29T15:23:26.692125Z",
"2018-12-29T15:23:27.918561Z",
"2018-12-29T15:23:29.217879Z",
"2018-12-29T15:23:30.468284Z",
"2018-12-29T15:23:31.548761Z"
];
var timestamps = dates.map(date => Date.parse(date));
var max_date = Math.max.apply(Math, timestamps)
console.log(new Date(max_date).toISOString());
Note that you get "2018-12-29T15:23:31.548Z" rather than "2018-12-29T15:23:31.548761Z" because you've parsed the strings to JavaScript dates, and JavaScript dates only hold milliseconds, not microseconds.

Categories

Resources