Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

From week number to start and end timestamp #2018

Closed
nicolasr75 opened this issue Jan 26, 2022 · 7 comments
Closed

From week number to start and end timestamp #2018

nicolasr75 opened this issue Jan 26, 2022 · 7 comments
Labels
no-spec-text PR can be ignored by implementors question

Comments

@nicolasr75
Copy link

A common scenario in my business domain is that users select a calendar week by selecting the week number and the year. The software is supposed to convert this into the start and end timestamps for the given week. An example would be a query for all measured temperature values of a specific week.

Temporal knows weekOfYear and dayOfWeek but how do I go the other direction?
Given an ISO calendar week number and a year, how do we get to the start and end date of that week?

moment.js allows me to set the week, see f.e. here:
https://www.tutorialspoint.com/momentjs/momentjs_week_of_year.htm

@justingrant
Copy link
Collaborator

justingrant commented Jan 26, 2022

Hi @nicolasr75 - Below is one way to get the date range you're looking for. The trick is that the fourth of January is always on the first ISO week of the year. So to calculate a week range, just find the start of the week that contains Jan 4, and add the correct number of weeks.

function getWeekRange({weekNumber, year}) {
  const dayInFirstWeek = Temporal.PlainDate.from({ year, month: 1, day: 4 });
  const start = dayInFirstWeek.add({ days: 1 - dayInFirstWeek.dayOfWeek }).add({ weeks: weekNumber - 1 });
  const end = start.add({ days: 6 });
  return { start, end };
}

function formatDate(date) {
  const formatted = date.toLocaleString(undefined, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
  return `${formatted} (week ${date.weekOfYear})`
}
const { start, end } = getWeekRange({year: 2022, weekNumber: 2});
console.log(`${formatDate(start)} - ${formatDate(end)}`);
// => Monday, January 10, 2022 (week 2) - Sunday, January 16, 2022 (week 2)

EDIT 2022-01-28: fixed a bug in code above as discussed in later comments

@justingrant justingrant added question no-spec-text PR can be ignored by implementors labels Jan 26, 2022
@nicolasr75
Copy link
Author

Thanks, I see. Would be great to see that example in the cookbook or somewhere else. Not everyone will think of this immediately ;-)

@ptomato
Copy link
Collaborator

ptomato commented Jan 26, 2022

Would you be able to mention a bit more about your use case in js-temporal/proposal-temporal-v2#11 ?

@nicolasr75
Copy link
Author

@ptomato Done!

@nicolasr75
Copy link
Author

@justingrant Your example does not work for week number 1 in 2022 because

const start = dayInFirstWeek.add({days: 1 - dayInFirstWeek.dayOfWeek, weeks: weekNumber - 1});

throws an error "mixed-sign values not allowed as duration fields". That is because days is -1 in this case and weeks is 0.
It works when I split it up into:

const start dayInFirstWeek.add({weeks: weekNumber - 1}).add({ days: 1 - dayInFirstWeek.dayOfWeek });

@justingrant
Copy link
Collaborator

justingrant commented Jan 28, 2022

@nicolasr75 - Thanks for catching that! Temporal.Duration instances cannot have opposite signs (see #782). Because add and subtract operate on durations, the same limitation also applies to property bags used in place of a Temporal.Duration instance.

Note that week number 1 is OK because zeroes are always allowed. It's only mixing positive and negative that fails. So week number 2+ will fail, e.g. getWeekRange({year: 2022, weekNumber: 2});.

I updated the code in my original comment so that folks finding this in Google won't copy/paste the bug.

@ptomato
Copy link
Collaborator

ptomato commented May 10, 2022

I think the question has been answered, so I'll close this.

@ptomato ptomato closed this as completed May 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-spec-text PR can be ignored by implementors question
Projects
None yet
Development

No branches or pull requests

3 participants