moment.js, list days based on locale dow - javascript

I have a script that is setting the day to start the week in the locale, however when I list out the days they arent in order that I expect:
moment.updateLocale(this.language, {
week: {
dow: 4,
},
});
const weekDays = moment.weekdaysMin();
In this scenario I would expect to get the list:
Thu Fri Sat Sun Mon Tue Wed
But I always get:
Sun Mon Tue Wed Thu Fri Sat
I would really appreciate some assistance as I can't figure out what is wrong here.

You can pass boolean argument to weekdaysMin to get weekdays sorted by locale.
See Listing the months and weekdays of the current Moment.js locale section of the docs:
Similarly, moment.monthsShort returns abbreviated month names, and moment.weekdays, moment.weekdaysShort, moment.weekdaysMin return lists of weekdays.
...
As of 2.13.0 you can pass a bool as the first parameter of the weekday functions. If true, the weekdays will be returned in locale specific order.
Here a live sample:
moment.updateLocale('en', {
week: {
dow: 4,
},
});
const weekDays = moment.weekdaysMin();
console.log(weekDays);
const weekDaysSort = moment.weekdaysMin(true);
console.log(weekDaysSort);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>

Related

Javascript show next possible delivery date

I have a website, where the client can see the delivery date.
Here is the code
function getProductRecordHTML(Product, index, quantity, ProductType, blok)
{
var manufacturer = "", article_show = "", name = "";
var time_to_exe = Product.time_to_exe;
var displayDate;
if(time_to_exe == 6)
{
const date = new Date();
date.setDate(date.getDate() + parseInt(time_to_exe));
displayDate = date.toLocaleDateString();
}
if (displayDate) {
time_to_exe = displayDate;
} else {
time_to_exe = time_to_exe + "d";
}
For now, time_to_exe gives the delivery time in days
This code calculates the next delivery date just by adding these 6 days to the current date.
My main goal is to get the period from Monday to Wednesday at 12 pm, if it's true then time_to_exe shows the date of next Monday (for example 23/08/2021), but if it's false (for example it's period from Wednesday after 12 pm till Sunday 11:59 pm) then time_to_exe show Monday date 1-week after (for example 30/08/2021).
I hope explained clearly.
Already many thanks to the user #Christopher for helping before.
One way to work with dates much easier is to use a library like moment.js (which I have been using for years), or maybe even better a newer library like Luxon, since moment.js is going into maintenance mode.
Let's see how you would achieve your date calculation using moment.js:
var orderDateTime = moment('08/18/2021 8:15 am');
// Get Sunday (first day) of this week and add 3 days (to get to Wednesday) and set the time to 11:59am
var cutOffDate = moment().startOf('week').add(3,'days').set({'hour': 11, 'minute': 59, 'second': 59});
// Initialize delivery date from order date
var deliveryDate = orderDateTime.clone();
if (orderDateTime.isSameOrBefore(cutOffDate)) {
deliveryDate = deliveryDate.add(1,'week').startOf('week').add(1,'day'); // Monday next week
} else {
deliveryDate = deliveryDate.add(2,'week').startOf('week').add(1,'day'); // Monday the week after next
}
alert("Delivery Date is "+deliveryDate.format("MM/DD/YYYY"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
That's all you need for your calculation.
You can also find a fiddle of the code above at https://jsfiddle.net/yLpf3vxj/
The Javascript Date object includes a getDay() method that returns a numerical value for the day of the week. From this it's possible to work out the previous Monday's date, and then add 7 or 14 depending on the original date.
This function takes a JavaScript Date object and returns the relevant Monday as another Date.
Note that setDate() will update month and year as appropriate if the date being set is outside the current month.
function getMonday(orderDate) {
orderDate = orderDate || new Date();
if (!(orderDate instanceof Date)) {
throw "Invalid date";
}
// Get the date last Monday
let lastMonday = new Date(orderDate);
lastMonday.setDate(lastMonday.getDate()-lastMonday.getDay()+1);
// If order date is before Wednesday noon, deliver next Monday. Add 7 to last Monday date
if (orderDate.getDay()<3 || ((orderDate.getDay() === 3) && orderDate.getHours()<12)) {
lastMonday.setDate(lastMonday.getDate()+7);
} else {
// Otherwise. add 14 to last Monday date.
lastMonday.setDate(lastMonday.getDate()+14);
}
return lastMonday;
}
input:
let testDates = [
new Date(),
new Date(2021,7,18,11),
new Date(2021,7,18,13),
new Date(2021,9,1,11),
'bad date'
];
Output:
Wed Aug 18 2021 10:14:41 GMT+1200 (New Zealand Standard Time), Mon Aug 23 2021 10:14:41 GMT+1200 (New Zealand Standard Time)
Wed Aug 18 2021 11:00:00 GMT+1200 (New Zealand Standard Time), Mon Aug 23 2021 11:00:00 GMT+1200 (New Zealand Standard Time)
Wed Aug 18 2021 13:00:00 GMT+1200 (New Zealand Standard Time), Mon Aug 30 2021 13:00:00 GMT+1200 (New Zealand Standard Time)
Fri Oct 01 2021 11:00:00 GMT+1300 (New Zealand Daylight Time), Mon Oct 11 2021 11:00:00 GMT+1300 (New Zealand Daylight Time)
Invalid Date
Demo:https://jsfiddle.net/dzsf34ga/

How can i format the date with Momentjs to look like this?

I used the following date format with a moment to save a date for a document in MongoDB. The problem is that it somehow got converted, I guess by MongoDB. Now if I want to fetch that data by specifying the date, I can't use the same variables I used to create the date in the first place. Can anyone tell me how I can do this?
const date = new Date();
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
const startDate = moment(firstDay);
const day = startDate;
the day variable is saved in MongoDB as
'Wed Jun 24 2020 00:00:00 GMT+0300'
But if I try to find the document by date, the day variable is actually returning
2020-06-24T22:17:09+03:00
I guess what I am trying to do is return today's date in this format 'Wed Jun 24 2020 00:00:00 GMT+0300' with time set to 0 as I only need the date to search for the document I need.
EDIT: I was able to do it using Date instead of Momentjs.
const date = new Date();
date.setHours(0, 0, 0, 0);
console.log(date.toString().split("(Eastern European Summer Time)")[0]);
//Wed Jun 24 2020 00:00:00 GMT+0300
You can use $dateFromString in aggregation pipeline to achieve it.
Your query might looks similar to this:
db.collection.aggregate( [ {
$project: {
date: {
$dateFromString: {
dateString: '$date'
format:<formatStringExpression>
} ] )
From official MongoDB docs:
New in version 3.6.
Converts a date/time string to a date object.
The $dateFromString expression has the following syntax:
{ $dateFromString: {
dateString: <dateStringExpression>,
format: <formatStringExpression>,
timezone: <tzExpression>,
onError: <onErrorExpression>,
onNull: <onNullExpression>
} }
You might also want to look at $dateToString in aggregation pipeline, which gives the formatted date string
The syntax is similar to above:
db.collection.aggregate( [ {
$project: {
date: {
$dateToString: {
dateString: '$date'
format:<formatString>
} ] )

Problem while modifying a date (modification is wrong)

I'm trying to make a calendar in Angular. For this I have implement a drag & drop functionnality to be able to move one appointment from a day to another one.
But I have something strange, when I try to move an appointment it seems working, but when I try to move it from the 1st april to the 31 march then the date is modified to the 1st march.
When I drop my appointment I emit a change with my appointment data and the new day:
drop(evt) {
let schedule: Schedule;
schedule = evt.data.schedule;
// Emit change
this.scheduleChange.emit({schedule, day: this.day});
}
Then I edit my appointment:
scheduleChanged(evt) {
const schedule = this.createScheduleFromObject(evt.schedule);
const day = evt.day;
console.log(day);
if (this.isSameDate(schedule.start, schedule.end)) {
schedule.start.setDate(day.getDate());
schedule.start.setMonth(day.getMonth())
schedule.start.setFullYear(day.getFullYear());
schedule.end.setDate(day.getDate());
schedule.end.setMonth(day.getMonth());
schedule.end.setFullYear(day.getFullYear());
console.log(schedule);
}
}
I think the problem is when I transform my object to a Schedule class:
createScheduleFromObject(obj: any) {
const schedule: Schedule = Object.assign(new Schedule(null, '', '', '', new Date(), new Date()), obj);
console.log(obj.start);
schedule.start = new Date(obj.start);
schedule.end = new Date(obj.end);
console.log(schedule.start);
return schedule;
}
This function return the good date here is the output of the console log:
2020-04-01T21:31:49.640Z
Wed Apr 01 2020 23:31:49 GMT+0200
But when I modify it in the scheduleChanged function even if the day is the 31st march as I have in the console log:
Tue Mar 31 2020 00:00:00 GMT+0200
The start date of my schedule is set to :
Sun Mar 01 2020 23:33:19 GMT+0100
Why ?
I suspect this is a duplicate of Javascript setMonth shows improper date. What is likely happening in your case is that moving a date for April to 31 March, you are setting the day in April to a non–existent date, so it rolls over to the next month.
When setting the values of a date one at a time, you may have issues where the date of the starting Date doesn't exist in the month being set. So when setting the values of a date to new values, do it all in one go, so instead of:
schedule.start.setDate(day.getDate());
schedule.start.setMonth(day.getMonth())
schedule.start.setFullYear(day.getFullYear());
do:
schedule.start.setFullYear(day.getFullYear(), day.getMonth(), day.getDate());
So in your case, moving a date from 1 April to 31 March:
The April date is set to 31, which doesn't exist so rolls over to 1 May
The month is set to March
Year is set to whatever
So you end up with a Date for 1 March. Setting the values in one go fixes that so:
(2020-04-01).setFullYear(2020, 2, 31) -> 2020-03-31
When setting the year, you can also set the month and day, when setting month you can set the month and day. Similarly for time, setting hours can set hours, minutes, seconds and milliseconds. Setting minutes can set minutes, seconds and milliseconds, etc.

Moment JS not recognising ISO 8601 date

So I've got two dates I'd like to get the difference of:
console.log(new Date(Date.now()).toISOString()); //2017-07-07T16:55:30.471Z
console.log(asset.past[i].date); //2017-07-06T20:29:00.670Z
var a = moment([new Date(Date.now()).toISOString()]);
console.log(a); //Moment Date:Sun Jan 01 2017 00:00:00 GMT+0000
var b = moment([asset.past[i].date]);
console.log(b); //Moment Date:Sun Jan 01 2017 00:00:00 GMT+0000
console.log(a.diff(b, 'seconds', true)); //0
console.log(a.diff(b, 'days', true)); //0
console.log(a.diff(b, 'months', true)); //0
I've put the out put of the console logs as comments afterwards. I assume it doesn't recognize the date format as ISO 8601 and defaults to Sun Jan 01 2017 00:00:00 GMT+0000. Either way, any idea how to fix it?
Cheers, Ed.
Why are you passing in an array to the moment constructor? What do you want a to actually be, just the current date? If so just do moment(). If you want to pass in a string do it like you correctly did on line 1.
Here are just the 2 fixes where I removed the square brackets. Again, you can just do moment() to get a moment that points to now.
// var a = moment(new Date(Date.now()).toISOString());
var a = moment();
var b = moment(asset.past[i].date);

SQL statement querying result which is within a time range

I want to do a sql statement which queries by timestamp using javascript.
Here is how i set my timestamp:
var startTime = new Date(year, month, day, 0, 0);
var endTime = new Date(year, month, day, 23, 59);
My sql statement is:
'SELECT * FROM proximate.user WHERE join_timestamp >= $1 ' +
'AND join_timestamp<=$2 ORDER BY user_id ASC';
$1 is startTime and $2 is endTime. Given if the startTime is Sat Dec 01 2012 00:00:00 GMT+0800 (SGT) and endTime is Sat Dec 01 2012 23:59:00 GMT+0800 (SGT), the executed statement returns results which include timestamp that is a day before the startTime.
Anyone has any idea why?
Thanks in advance.
My guess is that you receive proper results but forget to convert timestamp column of returned resultset to GMT+8 : "Sat Dec 01 2012 00:00:00 GMT+0800" = Fri Nov 30 2012 16:00:00 UTC". Another option - pass dates in UTC. Actually that depends on what you want to get: if you need all users who joined on December 1st GMT+8 you need to convert result set, if you need users who joined on December 1st UTC, pass UTC dates :"Sat Dec 01 2012 00:00:00 UTC"

Categories

Resources