Angularjs 1: sort date by week - javascript

i have list of objs:
[{
name: one,
date: 2017-09-18
}, {
name: two,
date: 2017-09-11
}, {
name: three,
date: 2017-09-13
}]
And i want to sort it by week.
Maybe like:
{
1week(or , maybe better key like start of week): [{
name: two,
date: 2017-09-11
}, {
name: three,
date: 2017-09-13
],
2week: [{
name: one,
date: 2017-09-18
}]
}
how can I determine by what week the dates belong?
how can I do better?

I played around with this, and I think this is similar to what you need:
https://jsfiddle.net/pegla/ytmayemr/
code:
let arrayOfDates = [{
name: 'one',
date: '2017-09-18'
}, {
name: 'two',
date: '2017-09-11'
}, {
name: 'three',
date: '2017-09-13'
}];
function getWeekNumber(d) {
// Copy date so don't modify original
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
// Get first day of year
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
// Calculate full weeks to nearest Thursday
var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
// Return array of year and week number
return [d.getUTCFullYear(), weekNo];
}
let newArrayOfDatesByWeek = arrayOfDates.reduce((prevVal, currVal, index)=>{
let week = `week ${getWeekNumber(new Date(currVal.date))[1]} of ${getWeekNumber(new Date(currVal.date))[0]}`;
if(!(week in prevVal)) {
prevVal[week] = [];
}
prevVal[week].push(currVal);
return prevVal;
}, []);
console.log(newArrayOfDatesByWeek);
getWeekNumber function is taken from this answer by RobG, so thanks for that:
Get week of year in JavaScript like in PHP

Related

JavaScript detect if giving region and date is a holiday

const regions = [
{
id: 1,
name: "Baden-Württemberg",
holidays: HOLIDAYS_BW,
},
{
id: 2,
name: "Bayern",
holidays: HOLIDAYS_BY,
},
]
const HOLIDAYS_BW = [
{ date: "01.01.2022", day: "Samstag" },
{ date: "06.01.2022", day: "Donnerstag" },
];
const HOLIDAYS_BY = [
{ date: "01.01.2022", day: "Samstag" },
{ date: "06.01.2022", day: "Donnerstag" },
];
How can I check wether the region and date the user picks is a holiday.
For instance I would like to check wether the region Bayern and the date 05.05.2022 is a holiday, the array shows all holidays
I tried this so far, but it does not seems to work
regions.find((region) => region.holidays.includes(date));
The date which I gave to the "query" is in this format
Tue Mar 22 2022 01:00:00 GMT+0100
That is an issue I think
You can try like so, finding if the region exists first (returns undefined if not), and then if the date is in the list.
return regions.find(r => r.name == region)?.holidays.some(h => h.date == date)
If you don't like the undefined and always want false, just add ?? false at the end.
return regions.find(r => r.name == region)?.holidays.some(h => h.date == date) ?? false
const HOLIDAYS_BW = [{
date: "01.01.2022",
day: "Samstag"
},
{
date: "06.01.2022",
day: "Donnerstag"
},
];
const HOLIDAYS_BY = [{
date: "01.01.2022",
day: "Samstag"
},
{
date: "06.01.2022",
day: "Donnerstag"
},
];
const regions = [{
id: 1,
name: "Baden-Württemberg",
holidays: HOLIDAYS_BW,
},
{
id: 2,
name: "Bayern",
holidays: HOLIDAYS_BY,
},
]
function formatDate(date) {
return `${('0' + (date.getDate())).slice(-2)}.${('0' + (date.getMonth())).slice(-2)}.${date.getFullYear()}`
}
function isHoliday(region, date) {
var formattedDate = formatDate(date);
return regions.find(r => r.name == region)?.holidays.some(h => h.date == formattedDate);
}
console.log(isHoliday('Bayern', new Date(2022, 01, 06))); // true
console.log(isHoliday('Baden-Württemberg', new Date(2022, 01, 01))); // true
console.log(isHoliday('Bayern', new Date())); // false
console.log(isHoliday('Hamburg', new Date(2022, 01, 06))); // undefined as Hamburg is not on the list
UPDATE
Turns out the input is a date, you can format it first with something like:
var formattedDate = `${('0' + (date.getDate())).slice(-2)}.${('0' + (date.getMonth())).slice(-2)}.${date.getFullYear()}`
and then use the string for the comparison.

Filter date time in json based on date

I'm writing a code that has date time in a json, And I want to filter the json and show the data where date from datetime is greater than today's date.
Here is my code.
var data = [{
datetime: "2021-08-09T06:00:00.000Z",
id: "1"
}, {
datetime: "2021-06-07T02:00:00.000Z",
id: "2"
}, {
datetime: "2021-08-04T11:00:00.000Z",
id: "3"
}, {
datetime: "2021-08-04T10:00:00.000Z",
id: "4"
}, {
datetime: "2021-08-05T12:55:00.000Z",
id: "5"
}, {
datetime: "2020-08-10T13:30:00.000Z",
id: "6"
}]
data = data.filter(item=> { return new Date(item.datetime).getDate() > new Date().getDate()});
console.log(data);
it should print every thing apart from id 3, 4 and 6. Also when I do a getDate(), I think it only considers DD from MMDDYYYY, that's why 6 is getting printed. what would be the best way to achieve this?
There seems to be a typo:
data = data.filter(item=> { return new Date(item.datatime).getDate() > new Date().getDate()});
// ^
// datetime
data = data.filter(item => {
const date = new Date(item.datetime);
const today = new Date();
return date.getUTCFullYear() * 10000 + date.getUTCMonth() * 100 + date.getUTCDate() > today.getUTCFullYear() * 10000 + today.getUTCMonth() * 100 + today.getUTCDate();
});

How to create a json grouped by date in js?

I have an array of objects sorted by date:
const alerts = [{
id: 1, date: '2018-10-31T23:18:31.000Z', name: 'Joke', title: 'this is the first 1'
}, {
id: 2, date: '2018-10-30T23:18:31.000Z', name: 'Mark', title: 'this is the second one'
}]
I am trying to 'group' the alerts by date so trying to create 'datesections' which have a dateheader, the result should be something like:
const sections = [{
date: '2018-10-31T23:18:31.000Z',
heading: 'today',
alerts: [{ id: 1, date: '2018-10-31T23:18:31.000Z', name: 'Joke',
title: 'this is the first one' }]
}, {
date: '2018-10-30T23:18:31.000Z',
heading: 'Yesterday',
alerts: [{ id: 2, date: '2018-05-30T23:18:31.000Z', name: 'Mark',
title: 'this is the second one' }]
}]
I tried something this but can't figure out how to get the alerts with the same date in the alerts prop:
const sections2=alerts.map(a =>
({
date: a.date,
heading:'today new',
alerts:alerts
})
)
const alerts = [
{ id: 1, date: '2018-10-31T23:18:31.000Z', name: 'Joke', title: 'this is the first 1' },
{ id: 2, date: '2018-05-30T23:18:31.000Z', name: 'Mark', title: 'this is the second one' }
]
const grouping = _.groupBy(alerts, element => element.date.substring(0, 10))
const sections = _.map(grouping, (items, date) => ({
date: date,
alerts: items
}));
console.log(sections);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Can't help you with headings - what if it's neither "today" or "yesterday"?
I feel like you are asking a couple of things here. The key one is how to group by day with a date.
To do that you will first need to know how to group. This answer may help with that.
As far as how to group by day there are a number of ways to do that. Simplest I can think of is to cut off everything after the "T" in the date string and sort that.
From my point of view it's not really a map what you need here, map will return a new array but not what you want. You can do this with 2 for statements
let total = [];
for (let j = 0; j < alerts.length; j++) {
let item = alerts[j];
let foundDate = false;
for (let i = 0; i < total.length; i++) {
if (total[i].date === item.date) {
foundDate = true;
total.alerts.push(item);
}
}
if (!foundDate) {
console.log("!found");
total.push({
date: item.date,
heading: "Yesterday",
alerts: [item]
});
}
}
If you console.log yout total array, will contain what you want.
If you need any other explanation pls let me know.
You can use a regular expression to match the part of the date you want and then group your data. You can add there the header you want. Hope this helps.
const alerts = [
{ id: 1, date: '2018-10-31T23:18:31.000Z', name: 'Joke', title: 'this is the first 1' },
{ id: 2, date: '2018-10-30T23:18:31.000Z', name: 'Mark', title: 'this is the second one' },
{ id: 3, date: '2018-10-30T23:14:32.000Z', name: 'Mark', title: 'this is the third one' }
];
const groupByDate = (data) => {
return data.reduce((acc, val) => {
const date = val.date.match(/\d{4}-\d{2}-\d{2}/g).toString();
const item = acc.find((item) => item.date.match(new RegExp(date, 'g')));
if (!item) acc.push({ date: val.date, alerts: [val], heading: 'some heading' });
else item.alerts.push(val);
return acc;
}, []);
};
console.log(groupByDate(alerts));
Maybe you need something like this? Didn't have much time for this and last array parsing might be done in more elegant way ;)
var alerts = [
{ id: 1, date: '2018-10-31T23:18:31.000Z', name: 'Joke', title: 'this is the first 1' },
{ id: 3, date: '2018-10-31T23:44:31.000Z', name: 'Joke1', title: 'this is the 2nd' },
{ id: 2, date: '2018-10-30T23:18:31.000Z', name: 'Mark', title: 'this is the second one' },
{ id: 4, date: '2018-10-30T23:45:31.000Z', name: 'Mark1', title: 'this is the 3rd' },
{ id: 5, date: '2018-10-27T23:18:31.000Z', name: 'Mark2', title: 'this is the 4th' },
];
var processedAlerts = [], finalAlerts;
(function(initAlerts){
//iterate through array to make keys to group by day
for(var i = 0; i < initAlerts.length; i++){
processedAlerts[i] = initAlerts[i];
//substring here can be more sophisticated - this was faster
initAlerts[i].keyDate = initAlerts[i].date.substr(0, 10);
}
//supporting function to convert string to date
//to acheve more detailed sorting that includes time
//just use date object and use hours, minutes and/or seconds to create Date object
function dateFromString(strDate){
var date, tmpDate;
//convert string to array - I assume that date format is always the same
//yyyy-mm-dd and will become Array 0: year, 1: month, 2: day of the month
tmpDate = strDate.split("-");
//moths in js are zero pased so Jan is 0, Feb is 1 and so on
//so we want to substract 1 from human readable month value to get correct date
date = new Date(tmpDate[0], tmpDate[1]-1, tmpDate[2]);
return date;
}
//function used to compare dates and passed to sort function
function comparedates(obj1, obj2){
var date1, date2;
date1 = dateFromString(obj1.keyDate);
date2 = dateFromString(obj2.keyDate);
let comparison = 0;
if(date1>date2){
comparison = 1;
} else if(date1<date2){
comparison = -1;
}
//to achieve reverse just multiply comparison result by -1
return comparison*(-1);
}
function getHeader(date){
//here place logic to generate header
//this involves comparing dates probably from keyDate
return "temp header: " + date.toString()
}
//sort the array by keyDate from newest to oldest
processedAlerts.sort(comparedates);
//final array rebuild
//pass here sorted array
finalAlerts = (function(arrayAlerts){
var aAlerts = [], k = 0;
for(var j = 0; j < arrayAlerts.length; j++){
//check if entry for date exists
//if no than create it
if(!aAlerts[k]){
aAlerts[k] = {
//removed title because I asummed that each alert has unique title and put them in alerts instead
date: arrayAlerts[j].keyDate, //agroupped date
heading: getHeader(arrayAlerts[j].keyDate), //update this function to return personalized heading
//here you can shape the alert object how you need
//I just passed it as it was
alerts: [arrayAlerts[j]] //array with first object inside
};
} else {
//add another alert to day
aAlerts[k].alerts.push(arrayAlerts[j]) //array with first object inside
}
//increasing final array key
//if there is previous entry and keys are the same for current and previous
if(arrayAlerts[j-1] && (arrayAlerts[j].keyDate == arrayAlerts[j-1].keyDate)){
k++;
}
}
return aAlerts;
})(processedAlerts);
})(alerts);
console.log(finalAlerts);

Javascript loop through and combine dates in object

I need help with something that might be a common problem and something that others would benefit from as well, which is to modify dates in an object and combine them into a chronological list. The overall goal is to create a list which reflects all of the upcoming special dates in a year:
1 Jan - Sharpe's Anniversary
2 May - Edward's Birthday
12 Dec - Zero's Anniversary
etc...
I began by creating an object to represent this. Then slice out the year so that a comparison won't just arrange them by their order of initial occurrence, but will give an annual basis. Then perform a comparison to arrange the dates in chronological order. Then log out the result with the matching person's identity.
Up to this point I got it to work. However, I do not know how to repeat this and make it DRY. Certainly it would be sloppy to run this for anniversaries, then for birthdays without making some sort of custom function. All my attempts have not ended successfully.
Does anyone have a more elegant solution?
Much thanks to the community here :)
// Sample data
var items = [{
name: 'Edward',
anniversary: "2015-01-23",
birthday: "1988-05-02"
},
{
name: 'Sharpe',
anniversary: "2017-01-01",
birthday: "1988-05-10"
},
{
name: 'And',
anniversary: "2018-05-10",
birthday: "1988-06-12"
},
{
name: 'The',
anniversary: "1988-08-11",
birthday: "1979-03-12"
},
{
name: 'Magnetic',
anniversary: "2017-01-05",
birthday: "1956-06-21"
},
{
name: 'Zeros',
anniversary: "1990-12-12",
birthday: "1935-07-23"
}
];
// Slice out the year so that dates are annualized
for (var i = 0; i < items.length; i++) {
items[i].anniversary = items[i].anniversary.slice(5, 10);
};
// Sort dates in chronological order
items.sort(function(a, b) {
return new Date(a.anniversary) - new Date(b.anniversary);
});
// Console.log the dates with their associated name
for (var i = 0; i < items.length; i++) {
console.log(items[i].anniversary + " " + items[i].name);
}
When you remove the year from a date like "1988-08-11" you get "08-11". If you then parse this with the built-in Date parser, you'll either get an invalid date, or a date for 1 November 0008, when the original date was for 11 August. The parser will see a year and a month, and use 1 for the missing day.
But don't dispair! The ISO 8601 date format can be sorted as a string, so do as you are and sort as strings, not dates, e.g.
// Sample data
var items = [{
name: 'Edward',
anniversary: "2015-01-23",
birthday: "1988-05-02"
},
{
name: 'Sharpe',
anniversary: "2017-01-01",
birthday: "1988-05-10"
},
{
name: 'And',
anniversary: "2018-05-10",
birthday: "1988-06-12"
},
{
name: 'The',
anniversary: "1988-08-11",
birthday: "1979-03-12"
},
{
name: 'Magnetic',
anniversary: "2017-01-05",
birthday: "1956-06-21"
},
{
name: 'Zeros',
anniversary: "1990-12-12",
birthday: "1935-07-23"
}
];
// Get the events
var specialDates = items.reduce(function(acc, item) {
acc.push([item.name, item.anniversary.substr(5), 'Anniversary'], [item.name, item.birthday.substr(5), 'Birthday']);
return acc;
}, []).sort(function (a, b) { // sort on month
return a[1].localeCompare(b[1]);
}).map(function(event) { // Replace month number with short name
var months = [,'Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'];
return [event[0], months[+event[1].split('-')[0]] + ' ' + event[1].substr(3), event[2]];
});
// Write result
specialDates.forEach(function(event) {
console.log(event[1] + ': ' + event[0] + ' ' + event[2]);
});
This could be a bit smarter and get the event name from the original object so that you can add as many event types as you want and not have them hard coded, so an object like:
var items = [{
name: 'Edward',
events: {
anniversary: "2015-01-23",
birthday: "1988-05-02"
}
},
...
Also note that new Date("2015-01-23") will treat the string as UTC (timezone offset +00:00), so for hosts west of Greenwich the date might appear to be the day before.
let goal = items
.map( ({ name, anniversary }) => ({ name, 'anniversary': anniversary.slice( 5, 10 ) }) )
.sort( ({ 'anniversary': a }, { 'anniversary': b }) => {
if( a > b ) return 1;
if( a < b ) return -1;
return 0;
}
.map( ({ name, anniversary }) => anniversary + ' ' + name );
goal.forEach( item => { console.log( item ); });

Return individual days opening hours from foursquare venue endpoint

The foursquare api returns the following, located at data.response.venue.hours, for the venue opening hours at:
hours: {
status: "Closed until Noon",
isOpen: false
timeframes: [
{
days: "Mon–Wed",
open: [
{
renderedTime: "Noon–11:00 PM"
}
],
segments: [ ]
},
{
days: "Thu",
includesToday: true,
open: [
{
renderedTime: "Noon–Midnight"
}
]
segments: [ ]
},
{
days: "Fri–Sat",
open: [
{
renderedTime: "11:00 AM–1:00 AM"
}
]
segments: [ ]
},
{
days: "Sun",
open: [
{
renderedTime: "Noon–10:30 PM"
}
]
segments: [ ]
},
]
}
The group of days varies from venue to venue, i.e. some might have Mon-Tue, Wed-Sat, Sun or another variation instead of the above.
I'm looking to sort this information so that I can return the opening hours for individual days, i.e. call Monday on it's own. My javascript knowledge isn't that great so where to start would be good.
Thanks for any help.
For getting venue hours, you can use the venues/VENUE_ID/hours endpoint, which has a more machine-friendly result
hours: {
timeframes: [
{
days: [
1
2
3
4
5
6
7
],
includesToday: true,
open: [
{
start: "0600",
end: "2000"
}
],
segments: [ ]
}
]
}
This is a simplified case where all 7 days have the same open segment, but in other cases you should be able to iterate through timeframes and get each day's open array.
var Mon;
if (timeframes[j].days.indexOf(i) != -1) {
Mon = timeframes[j].open;
}
I would start with a mapping object describing what days match with the particular opening times:
var diff = {
mon: 'Mon–Wed',
tue: 'Mon–Wed',
wed: 'Mon–Wed',
thu: 'Thu',
fri: 'Fri-Sat',
sat: 'Fri-Sat'
};
Then, instead of sorting the data I would use filter to pull out the relevant result from the data using the mapping object:
function getOpeningTimes(day) {
var arr = hours.timeframes.filter(function (el) {
// return the match where the value of the property
// in the mapping object that matches the search equals the
// days property in the current object in the data.
return diff[day] === el.days;
});
return arr[0].open[0].renderedTime;
}
console.log(getOpeningTimes('mon')); // Noon–11:00 PM
Fiddle

Categories

Resources