First week of the year belongs in December? - javascript

I have a small method in js that looks like this:
const getSelectWeekText = (weekNumber, year) => {
let date = moment().year(year).week(weekNumber);
let month = date.format('MMMM');
return `Week ${weekNumber} (${month})`;
};
Running example here:
https://jsfiddle.net/472uoLg8/
I dont understand why the first item in the result has Month of December? I expected it to be January.

Because different locales define week of year numbering differently, Moment.js added moment#week to get/set the localized week of the year.
Use moment().isoWeek(weekNumber);
const getSelectWeekText = (weekNumber, year) => {
let date = moment().year(year).isoWeek(weekNumber);
let month = date.format('MMMM');
return `Week ${weekNumber} (${month})`;
};
Refer to https://momentjs.com/docs/#/get-set/week/.

Related

How to get date string from day number and month number using moment?

dayNumber: 28,
monthNumber: 2,
expected output using moment "2022-02-28"
What I've tried const date = moment() .month(monthNumber) .days(dayNumber) .format("YYYY-MM-DD");
but that gives me something like "2022-03-17"
what am I doing wrong?
You have two errors in your code:
The first one is that you need to replace the days function call with date
The second one is that the argument of the month function starts from 0. So 0 is January, 1 is February etc.
So, what you need to do in order to get 2022-02-28 is the following:
const date = moment() .month(1) .date(28) .format("YYYY-MM-DD");
.month expects values from 0-11. See: https://momentjs.com/docs/#/get-set/month/
.days is day of week, .date is day of month. See: https://momentjs.com/docs/#/get-set/day/ and https://momentjs.com/docs/#/get-set/date/
const date = moment().month(monthNumber-1).date(dayNumber).format("YYYY-MM-DD");
You can also create a moment instance with an array of numbers that mirror the parameters passed to new Date(), e.g. [year, month, day].
See moment/parsing/array
NB: Month is zero-indexed.
const year = 2022;
const monthNumber = 2;
const dayNumber = 28;
console.log(moment([year, monthNumber - 1, dayNumber]).format('YYYY-MM-DD'))
<script src="https://momentjs.com/downloads/moment.js"></script>

I want to store the value of a datePicker in WixCOde

Based on this Supplied Code,
$w.onReady(function () {
//TODO: write your page related code here...
const startFromDays = 4;
const endAtMonths = 9;
const today = new Date();
let startDate = new Date(today);
let endDate = new Date(today);
startDate.setDate(startDate.getDate() + startFromDays);
endDate.setMonth(endDate.getMonth() + endAtMonths);
$w.onReady(function () {
$w("#datePicker1").minDate = startDate;
$w("#datePicker2").maxDate = endDate;
});
});
I need help to find the difference between the endDate and the startDate and output it as Text. Knowing the fact that some start dates can be of the Eg: 26th of Feb and end Date can fall on 3rd March.
This Code is been run on Wixcode, where the dates are used as a Date-picker user input. Thank you.
Start by getting the difference between the two dates using something like what is described in this post.
Then, use that number to populate a text field that you've added to your page.
So, assuming you have a datediff() function declared:
const diff = datediff(startDate, endDate);
$w("#text1").text = diff.toString();

Check if time is the same with Moment.js

How to check if time is the same for Moment objects with different dates?
For example I have object like
const endDate = moment().add(30, 'days').endOf('day');
and I want to check if some moment object is endOf day.
private isEndOfDay(dateTime: string) {
const m = moment().endOf('day');
return m.isSame(dateTime, 'minute');
}
const receivedDateFormat: string = 'YYYY-MM-DD hh:mm:ss';
this.isEndOfDay(this.endDate.format(this.receivedDateFormat))
But for this case, when I pass "minute" parameter, it will check minute, hour, day, month and year... which isn't what I want to check.
The part of the documentation that explains that behaviour is
When including a second parameter, it will match all units equal or larger. Passing in month will check month and year. Passing in day will check day, month, and year.
So, if you just want to compare the minutes, you'll need to do something like
endDate.minute() === startDate.minute()
To compare the time only, format() the dates
endDate.format('HH:mm:ss') === startDate.format('HH:mm:ss')
To compare only time part you can set a given date (year, month and day) to your input.
Please note that passing 'minute' to isSame will ignore seconds.
Here a live sample:
function isEndOfDay(dateTime) {
let m = moment().endOf('day');
let m2 = moment(dateTime);
m2.set({
y: m.year(),
M: m.month(),
D: m.date()
});
return m.isSame(m2, 'minute');
}
var endDate = moment().add(30, 'days').endOf('day');
const receivedDateFormat = 'YYYY-MM-DD hh:mm:ss';
var ret = isEndOfDay(endDate.format(this.receivedDateFormat))
console.log(ret);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Another way to to is checking only units that matter for you:
function isEndOfDay(dateTime) {
let m = moment().endOf('day');
let m2 = moment(dateTime);
if( m.hours() === m2.hours() &&
m.minutes() === m2.minutes() &&
m.seconds() === m2.seconds() ){
return true;
}
return false;
}
var endDate = moment().add(30, 'days').endOf('day');
const receivedDateFormat = 'YYYY-MM-DD hh:mm:ss';
var ret = isEndOfDay(endDate.format(this.receivedDateFormat))
console.log(ret);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
See Get + Set section of the docs to see how to get and set units of moment objects.

Showing next available dates with 24h margin with Angular and MomentJS

I'm trying to display an array of possible delivery dates using AngularJS and MomentJS.
The issue is that it needs to meet certain conditions: Delivery dates are only Monday, Wednesday and Fridays.
Also, when the page loads, it recognizes the current date and it will only display the next available date that is minimum 24h away (e.g., if I load the page on a Sunday at 1pm, the first available date will be Wednesday, as Monday doesn't meet the 24h margin).
So far I could only think if dealing with the issue doing conditionals for every day of the week, but I'm pretty sure there has to be a neater way of dealing with it.
Here's what I did so far:
$scope.today = moment();
$scope.$watch('today', function () {
if ($scope.today = moment().day('Sunday')){
$scope.nextdateone = moment().add(3, 'd');
$scope.nextdatetwo = moment().add(5, 'd');
$scope.nextdatethree = moment().add(8, 'd');
$scope.nextdatefour = moment().add(10, 'd');
}
else if ($scope.today = moment().day('Monday')){
$scope.nextdateone = moment().add(2, 'd');
$scope.nextdatetwo = moment().add(4, 'd');
$scope.nextdatethree = moment().add(7, 'd');
$scope.nextdatefour = moment().add(9, 'd');
}
else if ...
});
This was the logic I came up with, but it doesn't really work as of now...
Any tips?
The delivery dates "Monday, Wednesday and Fridays", which (according to http://momentjs.com/docs/#/get-set/day/) you can represent as 1, 3 and 5.
So I would create a array with those dates, and then given the current day I would iterate that array of delivery dates to find the most suitable one... something like this:
const deliveryDates = [1, 3, 5];
const getDeliveryDate = (today) => {
let deliveryIndex = -1;
deliveryDates.some((date, index) => {
// If today is a delivery date, then schedule for the next delivery
if (today === date) {
deliveryIndex = index + 1;
return true;
}
// If today is before the current delivery date, store it
if (today < date) {
deliveryIndex = index;
return true;
}
});
// If delivery date is out of bounds, return the first delivery date
return deliveryIndex === deliveryDates.length || deliveryIndex === -1 ? 0 : deliveryIndex;
};
const getNextDelivery = (today) => {
return deliveryDates[getDeliveryDate(today)];
};
console.log(moment().day(getNextDelivery(moment().day())));
You can check a working example here:
https://jsbin.com/jawexafiji/edit?js,console

Find next instance of a given weekday (ie. Monday) with moment.js

I want to get the date of the next Monday or Thursday (or today if it is Mon or Thurs). As Moment.js works within the bounds of a Sunday - Saturday, I'm having to work out the current day and calculate the next Monday or Thursday based on that:
if (moment().format("dddd")=="Sunday") { var nextDay = moment().day(1); }
if (moment().format("dddd")=="Monday") { var nextDay = moment().day(1); }
if (moment().format("dddd")=="Tuesday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Wednesday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Thursday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Friday") { var nextDay = moment(.day(8); }
if (moment().format("dddd")=="Saturday") { var nextDay = moment().day(8); }
This works, but surely there's a better way!
The trick here isn't in using Moment to go to a particular day from today. It's generalizing it, so you can use it with any day, regardless of where you are in the week.
First you need to know where you are in the week: moment().day(), or the slightly more predictable (in spite of locale) moment().isoWeekday(). Critically, these methods return an integer, which makes it easy to use comparison operators to determine where you are in the week, relative to your targets.
Use that to know if today's day is smaller or bigger than the day you want. If it's smaller/equal, you can simply use this week's instance of Monday or Thursday...
const dayINeed = 4; // for Thursday
const today = moment().isoWeekday();
if (today <= dayINeed) {
return moment().isoWeekday(dayINeed);
}
But, if today is bigger than the day we want, you want to use the same day of next week: "the monday of next week", regardless of where you are in the current week. In a nutshell, you want to first go into next week, using moment().add(1, 'weeks'). Once you're in next week, you can select the day you want, using moment().day(1).
Together:
const dayINeed = 4; // for Thursday
const today = moment().isoWeekday();
// if we haven't yet passed the day of the week that I need:
if (today <= dayINeed) {
// then just give me this week's instance of that day
return moment().isoWeekday(dayINeed);
} else {
// otherwise, give me *next week's* instance of that same day
return moment().add(1, 'weeks').isoWeekday(dayINeed);
}
See also https://stackoverflow.com/a/27305748/800457
EDIT: other commenters have pointed out that the OP wanted something more specific than this: the next of an array of values ("the next Monday or Thursday"), not merely the next instance of some arbitrary day. OK, cool.
The general solution is the beginning of the total solution. Instead of comparing for a single day, we're comparing to an array of days: [1,4]:
const daysINeed = [1,4]; // Monday, Thursday
// we will assume the days are in order for this demo, but inputs should be sanitized and sorted
function isThisInFuture(targetDayNum) {
// param: positive integer for weekday
// returns: matching moment or false
const todayNum = moment().isoWeekday();
if (todayNum <= targetDayNum) {
return moment().isoWeekday(targetDayNum);
}
return false;
}
function findNextInstanceInDaysArray(daysArray) {
// iterate the array of days and find all possible matches
const tests = daysINeed.map(isThisInFuture);
// select the first matching day of this week, ignoring subsequent ones, by finding the first moment object
const thisWeek = tests.find((sample) => {return sample instanceof moment});
// but if there are none, we'll return the first valid day of next week (again, assuming the days are sorted)
return thisWeek || moment().add(1, 'weeks').isoWeekday(daysINeed[0]);;
}
findNextInstanceInDaysArray(daysINeed);
I'll note that some later posters provided a very lean solution that hard-codes an array of valid numeric values. If you always expect to search the same days, and don't need to generalize for other searches, that'll be the more computationally efficient solution, although not the easiest to read, and impossible to extend.
get the next monday using moment
moment().startOf('isoWeek').add(1, 'week');
moment().day() will give you a number referring to the day_of_week.
What's even better: moment().day(1 + 7) and moment().day(4 + 7) will give you next Monday, next Thursday respectively.
See more: http://momentjs.com/docs/#/get-set/day/
The following can be used to get any next weekday date from now (or any date)
var weekDayToFind = moment().day('Monday').weekday(); //change to searched day name
var searchDate = moment(); //now or change to any date
while (searchDate.weekday() !== weekDayToFind){
searchDate.add(1, 'day');
}
Most of these answers do not address the OP's question. Andrejs Kuzmins' is the best, but I would improve on it a little more so the algorithm accounts for locale.
var nextMoOrTh = moment().isoWeekday([1,4,4,4,8,8,8][moment().isoWeekday()-1]);
Here's a solution to find the next Monday, or today if it is Monday:
const dayOfWeek = moment().day('monday').hour(0).minute(0).second(0);
const endOfToday = moment().hour(23).minute(59).second(59);
if(dayOfWeek.isBefore(endOfToday)) {
dayOfWeek.add(1, 'weeks');
}
Next Monday or any other day
moment().startOf('isoWeek').add(1, 'week').day("monday");
IMHO more elegant way:
var setDays = [ 1, 1, 4, 4, 4, 8, 8 ],
nextDay = moment().day( setDays[moment().day()] );
Here's e.g. next Monday:
var chosenWeekday = 1 // Monday
var nextChosenWeekday = chosenWeekday < moment().weekday() ? moment().weekday(chosenWeekday + 7) : moment().weekday(chosenWeekday)
The idea is similar to the one of XML, but avoids the if / else statement by simply adding the missing days to the current day.
const desiredWeekday = 4; // Thursday
const currentWeekday = moment().isoWeekday();
const missingDays = ((desiredWeekday - currentWeekday) + 7) % 7;
const nextThursday = moment().add(missingDays, "days");
We only go "to the future" by ensuring that the days added are between 0 and 6.

Categories