date-fns - countdown from date including weeks - javascript

I am building a countdown clock, and I am using date-fns. I need to be able to countdown from a date including the number of weeks. The documentation here looks like formatDuration returns the number of weeks but doesn't seem to and wonder if I need to use something else?
I'm aware of the differenceInWeeks function they provide, but not sure how suitable that would be in my case.
Thanks in advance.
import { intervalToDuration, formatDuration } from 'date-fns';
const units = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'];
let duration = intervalToDuration({
start: new Date(2022, 6, 2, 0, 0, 15),
end: new Date(),
});
formatDuration(duration, {
format: units,
delimiter: ', ',
});
// Returns years, months, days, hours, minutes and seconds but not weeks

When creating a duration, date-fns doesn't add weeks by default and if they aren't in the duration, the formatter won't show them.
You can manually add weeks using a function based on the value for days, e.g.
function addWeeks(duration) {
if (!duration.weeks) {
duration.weeks = duration.days / 7 | 0;
duration.days = duration.days - duration.weeks*7;
}
}
You may want to test if duration.days exists before using it. Then do something like:
let duration = intervalToDuration({
start: new Date(2022, 6, 2, 0, 0, 15),
end: new Date()
});
// Add weeks if missing
addWeeks(duration);
let formattedDuration = formatDuration(duration, {
format: units,
delimiter: ', '
});
// "1 year, 9 months, 1 week, 1 day, 10 hours, 39 minutes, 27 seconds"
console.log(formattedDuration);

Related

how to check that date is over 18 and under 100?

how to check that date is over 18 and under 100 or what methods need to use from date-fns? i tried to use this solution:
dateIsAfter18AndBefore100: (value) => {
const date = value.replace(/(\d+).(\d+).(\d+)/, '$3/$2/$1')
if (!(isAfter(subYears(new Date(), 18), new Date(date)) && isBefore(subYears(new Date(), 100), new Date(date)))) {
return createTranslatable('validationDateIsBeforeCurrentDate');
}
},
``` but it not react on days and months, only years

Check if a date from a collection is 3, 6, or 9 months (and so on) ago

Must check if a collection of projects contains a startDate that has passed 3, 6, and so on, months, using moment.js but having problems coming up with a way to calculate the difference in time between today and startDate, was thinking of seeing if (today / startDate) % 3 === 0 but I don't think that's the best way and the results are not as expected. Even using moment.js diff, like this doesn't yield desired results and logs projects that clearly haven't elapsed elapsed 3, 6 etc... months.
Obviously I'm missing something would appreciate some help thank you.
const today = moment()
const projects = await ProjectModel.find()
projects.forEach(project => {
if (today.diff(moment(project.startDate), "month") % 3 == 0) {
console.log(project)
}
})
% is the wrong way to go about it. You want to find the 3 month ago bracket that the date falls in, so get the difference in months and divide by 3 and floor the result. If diff < 3, you'll get 0. If 3 <= diff <6 months, you'll get 1, etc.
E.g.
let projects = [
{startDate: new Date(2017,10,1)}, // 1 Nov 2017
{startDate: new Date(2018,10,1)}, // 1 Nov 2018
{startDate: new Date(2019, 0,1)}, // 1 Jan 2019
{startDate: new Date(2019, 3,1)}, // 1 Apr 2019
{startDate: new Date(2019, 4,1)}, // 1 May 2019
{startDate: new Date(2019, 6,1)}, // 1 Jul 2019
{startDate: new Date(2019, 7,1)} // 1 Aug 2019
];
let today = moment();
projects.forEach(project => {
let diff = today.diff(moment(project.startDate), "month") / 3 | 0;
console.log(
moment(project.startDate).format('DD-MMM-YYYY') +
' was ' + (diff * 3) + ' to ' +
(++diff * 3) + ' months ago'
);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
The modulo makes sense to me. If you roll your own dates, it works like this (plus or minus a leap-year-day, which is what libraries like moment.js are good at abstracting away):
const projects = [
{ id: 1, startDate: 1551441600000 },
{ id: 2, startDate: 1554120000000 },
{ id: 3, startDate: 1556712000000 },
{ id: 4, startDate: 1559390400000 },
{ id: 5, startDate: 1564660800000 }
];
// Gets current year, month, and date
const now = new Date(),
thisYear = now.getFullYear(),
thisMonth = now.getUTCMonth(),
thisDate = now.getUTCDate();
// Loops through projects
projects.forEach(project => {
// Gets year, month, and date for each project
const then = new Date(project.startDate),
startYear = then.getFullYear(),
startMonth = then.getUTCMonth(),
startDate = then.getUTCDate();
//console.log(then.toUTCString());
// Reports on the project if it started on an earlier day of the month 3, 6, etc months ago
const justStarted = thisYear == startYear && thisMonth == startMonth,
isQuarterInterval = thisMonth % 3 == startMonth % 3 && thisDate >= startDate
if(isQuarterInterval && !justStarted){
console.log("Project #" + project.id + " started " + then);
}
});

How to get start date and end date of a week from given year and week?

function getWeekDate(year, week) {
var obj = {
2017:["12/26~01/01","01/02~01/08","01/09~01/15","01/16~01/22","01/23~01/29","01/30~02/05","02/06~02/12","02/13~02/19","02/20~02/26","02/27~03/05","03/06~03/12","03/13~03/19","03/20~03/26","03/27~04/02","04/03~04/09","04/10~04/16","04/17~04/23","04/24~04/30","05/01~05/07","05/08~05/14","05/15~05/21","05/22~05/28","05/29~06/04","06/05~06/11","06/12~06/18","06/19~06/25","06/26~07/02","07/03~07/09","07/10~07/16","07/17~07/23","07/24~07/30","07/31~08/06","08/07~08/13","08/14~08/20","08/21~08/27","08/28~09/03","09/04~09/10","09/11~09/17","09/18~09/24","09/25~10/01","10/02~10/08","10/09~10/15","10/16~10/22","10/23~10/29","10/30~11/05","11/06~11/12","11/13~11/19","11/20~11/26","11/27~12/03","12/04~12/10","12/11~12/17","12/18~12/24","12/25~12/31"],
2018:["01/01~01/07","01/08~01/14","01/15~01/21","01/22~01/28","01/29~02/04","02/05~02/11","02/12~02/18","02/19~02/25","02/26~03/04","03/05~03/11","03/12~03/18","03/19~03/25","03/26~04/01","04/02~04/08","04/09~04/15","04/16~04/22","04/23~04/29","04/30~05/06","05/07~05/13","05/14~05/20","05/21~05/27","05/28~06/03","06/04~06/10","06/11~06/17","06/18~06/24","06/25~07/01","07/02~07/08","07/09~07/15","07/16~07/22","07/23~07/29","07/30~08/05","08/06~08/12","08/13~08/19","08/20~08/26","08/27~09/02","09/03~09/09","09/10~09/16","09/17~09/23","09/24~09/30","10/01~10/07","10/08~10/14","10/15~10/21","10/22~10/28","10/29~11/04","11/05~11/11","11/12~11/18","11/19~11/25","11/26~12/02","12/03~12/09","12/10~12/16","12/17~12/23","12/24~12/30"],
2019:["12/31~01/06"]
}
return obj[year][week - 1]
}
For example here I can get all the weeks in 2017, 2018, and the first week of 2019. Of course I could list all the weeks in a year and then get the date off that array but it seems very inefficient. What other methods I could use to get the start date and the end date of a week from given year and week?
Based on this week definition, you could calculate the week range by:
function getDateOfWeek(year, week) {
var start = (1 + (week - 1) * 7); // 1st of January + 7 days for each week
var end = 6 + start; // add 6 more days to get the end of the week
return {start: new Date(year, 0, start), end: new Date(year, 0, end)};
}
However, following your week definition, you could probably done something like this
function weekDateToDate (year, week) {
var firstDayOfYear = new Date(year, 0, 1)
var start = 2 + (week - 1) * 7 - firstDayOfYear.getDay();
var end = start + 6;
return {start: new Date(year, 0, start), end: new Date(year, 0, end)};
}

Finding whether the given date and time is in Empty segment of DST

My client and server are in UTC(+1245) Chatham Islands Time Zone
In this time zone, the clock will go one hour ahead from 30th Sep 2018 02:45 to 30th Sep 2018 03:45.
I want that if someone sets the time in-between these hours, it should notify the user. I have used the following code for finding it but it is not showing.
https://jsfiddle.net/tt8dmm4y/5/
Date.prototype.stdTimezoneOffset = function() {
var jan = new Date(2018, 0, 1);
var jul = new Date(2018, 6, 1);
return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}
Date.prototype.isDstObserved = function() {
return this.getTimezoneOffset() < this.stdTimezoneOffset();
}
var checkdate = new Date(2018, 09, 30, 02, 55, 00);
if (checkdate.isDstObserved()) {
alert("Daylight saving time!");
}
Any help?
The Date object in JavaScript will always work in the time zone that is local to the user. If you are comfortable with that, then simply compare the hours and minutes of the Date object with what you put in:
function isInvalidLocalTime(year, month, day, hour, minute) {
var d = new Date(year, month-1, day, hour, minute);
return d.getHours() !== hour || d.getMinutes() !== minute;
}
isInvalidLocalTime(2018, 9, 30, 3, 0) // false, but only when local time is Chatham
When a time in a transitional gap is provided, the Date object will shift it to some other time (which way it shifts is implementation dependent in older browsers). Note that minutes are required, because some time zone offset transitions are only 30 minutes, and not all transitions are related to DST.
If you need it to be specific to a particular time zone instead of a user-local time zone, then you will need to use a library that supports such things and take a similar approach as above while specifying the time zone. For example, we can use Luxon like this:
function isInvalidLocalTime(tz, year, month, day, hour, minute) {
var dt = luxon.DateTime.fromObject({zone: tz, year: year, month: month, day: day, hour: hour, minute: minute});
return dt.hour !== hour || dt.minute !== minute;
}
isInvalidLocalTime('Pacific/Chatham', 2018, 9, 30, 3, 0) // false
Also note that the Date object and Luxon's DateTime differ in whether months are zero-based or one-based. I accounted for that above (both functions are 1-based), but in your code in the question - you were testing October, not September.

Count days, hours and minutes to a specific date with javascript

I have this script that counts the days, hours and minutes from the time at the moment until May 8 at 23:59:59 - 1 second before May 9, and displays it as a counter with FlipClock, but for some reason it is missing 2 days and 1 hour. From today March 23 at 10:37 (24 hr clock) there are 48 days, 13 hours, 23 minutes hours, but my clock shows 46 days, 12 hours, 23 minutes.
Should be very simple, but I cannot figure out where the 2 days and 1 hour are gone missing.
I have this javascript:
// Grab the current date
var currentDate = new Date();
// Set the date to May 8
var futureDate = new Date(2016, 04, 08, 23, 59, 59);
// Calculate the difference in seconds between the future and current date
var diff = futureDate.getTime() / 1000 - currentDate.getTime() / 1000;
var clock = new FlipClock($('.clock'), diff, {
clockFace: 'DailyCounter',
countdown: true,
showSeconds: false,
language: 'da'
});
If I have to do anything with times, I usually use momentjs, it does not mean you have to, but I know it works and it works correctly enough for my criterias.
Duration format is not part of moment js, it is a feature. You could roll one yourself, but John Madhavan-Reese has already done this.
var futureDate = moment(new Date(2016, 04, 08, 23, 59, 59));
setInterval(function() {
var ms = moment().diff(moment(futureDate));
var duration = moment.duration(ms).format("yy-MM-dd hh:mm:ss");
$("#time").text(duration);
}, 200);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
<span id="time"><span>

Categories

Resources