mirror of
https://github.com/HowardHinnant/date.git
synced 2025-08-05 05:34:27 +02:00
Updated Examples and Recipes (markdown)
@@ -11,6 +11,7 @@ This page contains examples and recipes contributed by community members. Feel f
|
||||
- [Obtaining `y/m/d h:m:s` components from a `time_point`](#components_to_time_point)
|
||||
- [Normalizing `y/m/d` when it is `!ok()`](#normalize)
|
||||
- [When is it ok to be `!ok()`?](#not_ok_is_ok)
|
||||
- [How to find the next Monday (or Thursday)](#next_weekday)
|
||||
- [Converting from {year, microseconds} to CCSDS](#ccsds)
|
||||
- [Difference in months between two dates](#deltamonths)
|
||||
- [Parsing ISO strings](http://stackoverflow.com/a/33438989/576911)
|
||||
@@ -500,6 +501,52 @@ Next year it will output:
|
||||
|
||||
_Many_ invalid dates were computed during the execution of this program. And _none_ of them represented errors.
|
||||
|
||||
<a name="next_weekday"></a>
|
||||
### How to find the next Monday (or Thursday)
|
||||
(by [Howard Hinnant](https://github.com/HowardHinnant))
|
||||
|
||||
Given a `year_month_day`, and a day of the week, how to I efficiently increment the `year_month_day` until it is the desired day of the week?
|
||||
|
||||
This is very easy. But first you have to decide: If the `year_month_day` is already the desired `weekday`, do you want to return the original `year_month_day` or add a week? There is no one right answer. We'll do it both ways here. First I'll show how to keep the original. It is then an easy modification to show how to jump to the next week.
|
||||
|
||||
date::year_month_day
|
||||
next_weekday(date::year_month_day ymd, date::weekday target)
|
||||
{
|
||||
using namespace date;
|
||||
sys_days sd = ymd;
|
||||
return sd + (target - weekday{sd});
|
||||
}
|
||||
|
||||
The first thing to do is to convert the `year_month_day` to a `sys_days`. This is done because it is very efficient to find the day of the week of a `sys_days` (count of days), and to do day-oriented arithmetic on that data structure.
|
||||
|
||||
Next find out how many days we need to add to `sd` to get to the desired `weekday`. This is just the target weekday minus the current weekday. `weekday` subtraction is unsigned modulo 7. That is, it always returns a value between 0 and 6. `mon - sun` is `days{1}` since `mon` is always 1 day after `sun`. `sun - mon` is `days{6}` since `sun` is always 6 days after `mon`.
|
||||
|
||||
Above if `target == weekday{sd}`, then we don't add any days at all because `ymd` already has the desired `weekday`. Else we add up to 6 days. Then the return implicitly converts back to a `year_month_day`.
|
||||
|
||||
If we want to add a week when the input is already at the target weekday, then you just add a day to `sd` prior to the algorithm:
|
||||
|
||||
date::year_month_day
|
||||
next_weekday(date::year_month_day ymd, date::weekday target)
|
||||
{
|
||||
using namespace date;
|
||||
sys_days sd = ymd;
|
||||
sd += days{1};
|
||||
return sd + (target - weekday{sd});
|
||||
}
|
||||
|
||||
The reverse is similar:
|
||||
|
||||
date::year_month_day
|
||||
prev_weekday(date::year_month_day ymd, date::weekday target)
|
||||
{
|
||||
using namespace date;
|
||||
sys_days sd = ymd;
|
||||
sd -= days{1};
|
||||
return sd - (weekday{sd} - target);
|
||||
}
|
||||
|
||||
Except now we're subtracting weekdays to find out how many days to subtract from `sd`. Remove the pre-decrement by a day if you want this function to return the input when the input is already at the target weekday.
|
||||
|
||||
<a name="ccsds"></a>
|
||||
### Converting from {year, microseconds} to CCSDS
|
||||
(by [Howard Hinnant](https://github.com/HowardHinnant))
|
||||
|
Reference in New Issue
Block a user