How to generate a series with the start and end dates of months with Postgres

```sql WITH m AS ( SELECT generate_series(DATE('2010-01-01'), DATE('2010-12-01'), interval '1 month') AS start ) SELECT m.start, m.start + (interval '1' month) - (interval '1' second) AS end FROM m; ``` ```sql ┌────────────────────────┬────────────────────────┐ │ start │ end │ ├────────────────────────┼────────────────────────┤ │ 2010-01-01 00:00:00+02 │ 2010-01-31 23:59:59+02 │ │ 2010-02-01 00:00:00+02 │ 2010-02-28 23:59:59+02 │ │ 2010-03-01 00:00:00+02 │ 2010-03-31 23:59:59+03 │ │ 2010-04-01 00:00:00+03 │ 2010-04-30 23:59:59+03 │ │ 2010-05-01 00:00:00+03 │ 2010-05-31 23:59:59+03 │ │ 2010-06-01 00:00:00+03 │ 2010-06-30 23:59:59+03 │ │ 2010-07-01 00:00:00+03 │ 2010-07-31 23:59:59+03 │ │ 2010-08-01 00:00:00+03 │ 2010-08-31 23:59:59+03 │ │ 2010-09-01 00:00:00+03 │ 2010-09-30 23:59:59+03 │ │ 2010-10-01 00:00:00+03 │ 2010-10-31 23:59:59+02 │ │ 2010-11-01 00:00:00+02 │ 2010-11-30 23:59:59+02 │ │ 2010-12-01 00:00:00+02 │ 2010-12-31 23:59:59+02 │ └────────────────────────┴────────────────────────┘ ``` Same query without the CTE: ```sql SELECT start, start + (interval '1' month) - (interval '1' second) AS end FROM ( SELECT generate_series(DATE('2010-01-01'), DATE('2010-12-01'), interval '1 month') AS start ) months; ```