Coder Social home page Coder Social logo

Iterating over months about date HOT 7 CLOSED

howardhinnant avatar howardhinnant commented on August 19, 2024
Iterating over months

from date.

Comments (7)

HowardHinnant avatar HowardHinnant commented on August 19, 2024 1

This basically falls out of the question: What month will it be six months from now?

#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    std::cout << oct + months{6} << '\n';
}

Once one decides to support arithmetic like this, it leads down the path of the circular range.

from date.

HowardHinnant avatar HowardHinnant commented on August 19, 2024

There's a couple ways you can do this, but all of them share checking at the end of the loop instead of the beginning. In this example:

https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#not_ok_is_ok

iteration looks like this:

for (auto m = jan; true; ++m)
{
    if (m == dec)
        break;
}

You could also use a do-while:

auto m = jan;
do
{
}  while (++m != jan);

You'll hit a similar issue for iterating over days of the week (weekday). Consider both of these circular ranges as opposed to linear ranges.

from date.

galik avatar galik commented on August 19, 2024

Would it be worth defining some useful arrays in the library to make iterating easier?

constexpr date::month months[] =
{
    date::jan,
    date::feb,
    date::mar,
    date::apr,
    date::may,
    date::jun,
    date::jul,
    date::aug,
    date::sep,
    date::oct,
    date::nov,
    date::dec,
};

int main()
{
    for(date::month m: months)
        std::cout << m << '\n';
}

from date.

iliocatallo avatar iliocatallo commented on August 19, 2024

@HowardHinnant thank you for your reply.

Assume that I need a generic procedure for initializing the afore-mentioned map. It should work with any kind of time unit (months, days, weeknum etc.). As mentioned, my first attempt was to achieve this in a STL-fashion:

template <typename T>
std::map<T, ...> init(T first, T last) {

    std::map<T, ...> my_map;
    while (first != last) {
        my_map[first] = 0;
        ++first;
    }
    return my_map;
}

where T is the time unit at hand. If I get your advice correctly, I can retain the same interface if I do something like:

template <typename T>
std::map<T, ...> init(T first, T last) {
    std::map<T, ...> my_map;

    if (first == last) return my_map;
    --last;
    while (true) {
        my_map[first] = 0;
        if (first == last) break;
        ++first; 
    }
    return my_map;
}

Any particular reason for making month circular? It is much easier to construct a circular iterator on top of a linear one than the other way around.

Thanks.

from date.

HowardHinnant avatar HowardHinnant commented on August 19, 2024

The rationale stems from the fact that January follows December.

If you want you can do this:

    for (auto mi = 1u; mi < 13; ++mi)
    {
        std::cout << month{mi} << '\n';
    }

Often one wants to iterate over the months of a specific year:

    for (auto ym = 2016_y/jan; ym < 2017_y/jan; ym += months{1})
    {
        std::cout << ym << '\n';
    }

(which is a linear range with a past-the-end value)

from date.

socantre avatar socantre commented on August 19, 2024

Thinking about the month type as a circular range is interesting. I wonder if this might be generally useful, in the sense that libraries like range-v3 might provide generic support.

I believe there's already support for infinite ranges so I you should just need a way to query if a particular infinite range is infinite because it repeats, and how long that cycle is. Then you could handle things like this by getting the cycle length and using months | view::take(cycle_length(months)).

On the other hand range-v3 already has support for taking a finite range and making it repeat, so maybe a library's underlying month range could be non-cyclical and when people need the repetition they'd just add it in the context they need it.

from date.

HowardHinnant avatar HowardHinnant commented on August 19, 2024

Closing as "answered question."

from date.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.