I'm searching a way to get date range from week number with Luxon to replace my 'moment' code.
Today I'm using this code:
m = moment(yearNumber + "-W" + weekNumber);
dateFromStr = moment(m.startOf('week')).add(1, 'day'); // To get Monday 00:00:00
dateToStr = moment(m.endOf('week')).add(1, 'day'); // To get Sunday 23:59:59
I found a way to do that from a month number with 'DateTime.fromObject()' but that's doesn't work with 'week'. So I don't find the best way to do that from a week number :(
Thank's in advance.
You can use DateTime.fromObject that:
Create a DateTime from a JavaScript object with keys like 'year' and 'hour' with reasonable defaults.
passing weekYear (an ISO week year) and weekNumber (an ISO week number, between 1 and 52 or 53, depending on the year) in the input object.
Here an live example:
const DateTime = luxon.DateTime;
const yearNumber = 2020;
const weekNumber = 3;
const dt = DateTime.fromObject({
weekYear: yearNumber,
weekNumber: weekNumber
});
const dateFromStr = dt.startOf('week');
console.log(dateFromStr.toISO()); // last Monday at 00:00:00
const dateToStr = dt.endOf('week');
console.log(dateToStr.toISO()); // next Sunday at 23:59:59
<script src="https://cdn.jsdelivr.net/npm/luxon#1.26.0/build/global/luxon.js"></script>
You can also use DateTime.fromISO passing ISO compliant format such as YYYY-Www (see more on here). Please note that week number should be two digits.
Related
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>
Can someone help me:
I need to create the following.
Sunday 4 October 08.30 - 10.30 CET
Underneath this tough, I need to be able to display the local timezone??
Can someone please advise me on the best approach and can I do this with moment.js?
Thanks,
You will first need to include moment-timezone to figure out what "CET" means. Standard moment does not know how to convert named timezones to offsets.
Now, you need to use a regular expression to parse the meaningful pieces of information from your date range.
Once you have pulled out the information, reconstruct the pieces into a start and end date string.
Parse the date strings relative to the time zone.
I displayed the moment date objects in ISO 8601 format, so they will be in GMT (2 hours behind CET).
const grammar = /^(\w+) (\d+) (\w+) (\d+\.\d+) - (\d+\.\d+) (\w+)$/;
const inputFormat = 'dddd D MMMM HH.mm'
const input = 'Sunday 4 October 08.30 - 10.30 CET'
const m = input.match(grammar);
const startDateInput = `${m[1]} ${m[2]} ${m[3]} ${m[4]}`;
const endDateInput = `${m[1]} ${m[2]} ${m[3]} ${m[5]}`;
const timezone = m[6];
console.log(`Input (Start Date) : ${startDateInput}`);
console.log(`Input (End Date) : ${endDateInput}`);
const startDate = moment.tz(startDateInput, inputFormat, timezone);
const endDate = moment.tz(endDateInput, inputFormat, timezone);
console.log(`Output (Start Date) : ${startDate.toISOString()}`);
console.log(`Output (End Date) : ${endDate.toISOString()}`);
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.31/moment-timezone-with-data.min.js"></script>
I am not sure your exact question. You can use JavaScript Date Class.
//This will return time, "Mon Aug 10 2020 19:46:31 GMT+0530 (India Standard Time)"
const timeZone = /\((.*)\)/.exec(new Date().toString())[1];
// Here you can calculate offset hours
const offsetHours = new Date().getTimezoneOffset() / 60;
//This is the best way, beacuse sometimes offsethours might be wrong due to daylight saving rules
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
And there are different ways to format a string and for other calculation.
Hope this will solve your problem.
I am looking to do something quite complex and I've been using moment.js or countdown.js to try and solve this, but I think my requirements are too complex? I may be wrong. Here is the criteria...
I need to be able to have the following achievable without having to change the dates manually each year, only add it once and have many countdowns on one page.
Find current date
Find current year
Find current month
Find day within week of month that applies
¬ 3rd Sunday or 2nd Saturday
Convert to JS and output as html and run countdown
When past date - reset for following year
Pretty mental. So for example if an event is always on the 3rd Sunday of March. The date would not be the same each year.
2016 - Sunday March 19th
2017 - Sunday March 20th
2018 - Sunday March 18th etc.
I hope this is explained well, I realise it may be a total mess though. I managed to get it resetting each year with the date added manually but then someone threw in the spanner of the date being different each year.
var event = new Date();
event = new Date(event.getFullYear() + 1, 3 - 1, 19);
jQuery('#dateEvent').countdown({ until: event });
<div id="dateEvent"></div>
I have edited this answer as I have now put together a solution that works for me. As I believe this isn't simple coding due to the fact it wasn't actually answered 'Please, this is basic coding. pick up a javascript book and learn to code', yeah thanks...
// get the specific day of the week in the month in the year
function getDay(month) {
// Convert date to moment (month 0-11)
var myMonth = moment("April", "MMMM");
// Get first Sunday of the first week of the month
var getDay = myMonth.weekday(0); // sunday is 0
var nWeeks = 3; // 0 is 1st week
// Check if first Sunday is in the given month
if (getDay.month() != month) {
nWeeks++;
}
// Return 3rd Sunday of the month formatted (custom format)
return getDay.add(nWeeks, 'weeks').format("Y-MM-D h:mm:ss");
}
// print out the date as HTML and wrap in span
document.getElementById("day").innerHTML = '<span>' + getDay() + '</span>';
Using
<script src="moment.js"></script>
Hope it helps someone - I'll update when I figure how to + 1 year after it's checked current date and event has passed. I'll look in that JS book.
Please take a look at the below code, I explained in the comment what what does.
You use it by supplying a javascript Date object of any wished start date, and then add as a second value the corresponding year you wish to know the date in.
var date = new Date("2016-03-20");
function getDayInYear(startDate, year) {
// get a moment instance of the start date
var start = moment(startDate);
// collect the moment.js values for the day and month
var day = start.day();
var month = start.month();
// calculate which week in the month the date is.
var nthWeekOfMoth = Math.ceil(start.date() / 7);
// Build up the new moment with a date object, passing the requested year, month and week in it
var newMoment = moment(new Date(year,month,(nthWeekOfMoth * 7)));
// Return the next instance of the requested day from the current newMoment date value.
return newMoment.day(day);
}
var oldMoment = moment(date);
var newMoment2017 = getDayInYear(date,2017);
var newMoment2018 = getDayInYear(date,2018);
console.log(oldMoment.format('YYYY MMMM dddd DD'));
console.log(newMoment2017.format('YYYY MMMM dddd DD'));
console.log(newMoment2018.format('YYYY MMMM dddd DD'));
/** working from today up to 10 years into the future **/
var date = new Date();
var year = date.getFullYear();
for(var i = 0; i < 11; i++) {
console.log(getDayInYear(date, year+i).format('YYYY MMMM dddd DD'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
My goal is to compare two data sets representing financial quarters. The quirks of the API require two dates per get request: startDate (inclusive) and endDate (exclusive). Therefore, e.g., to get data for the month of July 2016 you need:
startDate = 20160701 and endDate = 20160801.
Given a single unixStartDate (which is a Unix timestamp), I want to find (1) the startDate and endDate for the current quarter, and (2) the startDate and endDate for the previous quarter.
So far I can use moment.js to determine the current quarter without issue:
const currentQuarter = moment.unix(unixStartDate).utc().quarter();
I could probably make a hacky switch-case based on that information, but I'm hoping for a more elegant solution.
Moment.js also contains moment().startOf('quarter'), but I've been unable to figure out its proper usage. Console.log yields an object:
Moment {_isAMomentObject: true,
_isUTC: false,
_pf: Object,
_locale: Locale,
_d: Fri Jul 01 2016 00:00:00 GMT-1000 (HST)…}
Here's a verbose version:
const moment = require('moment');
let unixStartDate = ...;
let current = moment(unixStartDate);
let currentStartOf = moment(current).startOf('quarter');
let currentEndOf = moment(current). endOf('quarter').add(1, 'day');
let previous = moment(current).subtract(1, 'quarter');
let previousStartOf = moment(previous).startOf('quarter');
let previousEndOf = moment(previous). endOf('quarter').add(1, 'day');
console.log(
'current ',
currentStartOf.format('YYYYMMDD'),
currentEndOf .format('YYYYMMDD')
)
console.log(
'previous',
previousStartOf.format('YYYYMMDD'),
previousEndOf .format('YYYYMMDD')
)
How can I convert a string representation of a date to a real javascript date object?
the date has the following format
E MMM dd HH:mm:ss Z yyyy
e.g.
Sat Jun 30 00:00:00 CEST 2012
Thanks in advance
EDIT:
My working solution is based on the accepted answer. To get it work in IE8, you have to replace the month part (e.g. Jun) with the months number (e.g. 5 for June, because January is 0)
Your date string can mostly be parsed as is but CEST isn't a valid time zone in ISO 8601, so you'll have to manually replace it with +0200.
A simple solution thus might be :
var str = "Sat Jun 30 00:00:00 CEST 2012";
str = str.replace(/CEST/, '+0200');
var date = new Date(str);
If you want to support other time zones defined by their names, you'll have to find their possible values and the relevant offset. You can register them in a map :
var replacements = {
"ACDT": "+1030",
"CEST": "+0200",
...
};
for (var key in replacements) str = str.replace(key, replacements[key]);
var date = new Date(str);
This might be a good list of time zone abbreviation.
You can use following code to convert string into datetime:
var sDate = "01/09/2013 01:10:59";
var dateArray = sDate.split('/');
var day = dateArray[1];
// Attention! JavaScript consider months in the range 0 - 11
var month = dateArray[0] - 1;
var year = dateArray[2].split(' ')[0];
var hour = (dateArray[2].split(' ')[1]).split(':')[0];
var minute = (dateArray[2].split(' ')[1]).split(':')[1];
var objDt = new Date(year, month, day, hour, minute);
alert(objDt);