Groupdate

repository·master·Indexed 26 days ago

https://github.com/ankane/groupdate

A Ruby gem for grouping ActiveRecord queries and Ruby collections by time periods such as day, week, hour, and month. It provides robust time zone support, the ability to return complete time series including missing data points via Groupdate::SeriesBuilder, and support for custom durations and dynamic period selection.

Tokens
2.6K
Snippets
10
Records
25
Agent score
87%

What's inside groupdate

  1. Configure MySQL and MariaDB for Time Zone Support

    master

    For MySQL and MariaDB, time zone support must be installed on the server. You can install it by running the following command in your terminal:

    mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

    To verify the installation, run this SQL query:

    SELECT CONVERT_TZ(NOW(), '+00:00', 'Pacific/Honolulu');

    It should return a time value instead of NULL.

    mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
  2. Troubleshoot Postgres 'GROUP BY' errors

    master

    If you are using PostgreSQL and have a default scope that includes an order clause, you may encounter the error: column must appear in the GROUP BY clause.

    To resolve this, remove the order scope before grouping:

    User.unscope(:order).group_by_day(:created_at).count
    User.unscope(:order).group_by_day(:count).count
  3. Group Arrays and Hashes

    master

    Groupdate also works with Ruby arrays and hashes by passing a block to the grouping method.

    users.group_by_day { |u| u.created_at }
    # or
    users.group_by_day(&:created_at)

    All standard options (like time_zone, series, etc.) are supported. To get a hash of counts from an array:

    users.group_by_day { |u| u.created_at }.to_h { |k, v| [k, v.count] }
    users.group_by_day { |u| u.created_at }
  4. Use Groupdate for basic grouping

    master

    Groupdate allows you to group ActiveRecord queries by various time periods. It works with standard ActiveRecord methods like count, sum, minimum, maximum, and average. Results are returned in ascending order by default.

    Available grouping periods:

    • second, minute, hour, day, week, month, quarter, year
    • minute_of_hour, hour_of_day, day_of_week (Sunday = 0, Monday = 1, etc), day_of_month, day_of_year, month_of_year
    User.group_by_day(:created_at).count
  5. Filter by Time Range and Recent Periods

    master

    Groupdate provides options to limit the data to specific ranges or recent periods.

    Specific Range:

    User.group_by_day(:created_at, range: 2.weeks.ago.midnight..Time.now).count

    Expand Range (to include the full start/end of the period):

    User.group_by_day(:created_at, range: 2.weeks.ago..Time.now, expand_range: true).count

    Recent Periods:

    • Get the last N periods: User.group_by_week(:created_at, last: 8).count
    • Exclude the current period: User.group_by_week(:created_at, last: 8, current: false).count
    User.group_by_week(:created_at, last: 8).count
  6. Configure Series and Missing Data

    master

    By default, Groupdate returns the entire series (including periods with no data).

    • To exclude periods without data: series: false
    • To change the value used for missing data: default_value: "missing"

    Example:

    User.group_by_day(:created_at, series: false).count
  7. Configure Time Zones

    master

    The default time zone is Time.zone. You can set a global default or specify a time zone per query.

    To set a global default:

    Groupdate.time_zone = "Pacific Time (US & Canada)"

    To specify a time zone for a specific query:

    User.group_by_week(:created_at, time_zone: "Pacific Time (US & Canada)").count

    If you are grouping on date columns that do not require time zone conversion, use time_zone: false.

    User.group_by_week(:created_at, time_zone: "Pacific Time (US & Canada)").count
  8. Configure Week Start and Day Start

    master

    You can customize when a week or a day begins.

    Week Start (defaults to Sunday):

    • Global: Groupdate.week_start = :monday
    • Per query: User.group_by_week(:created_at, week_start: :monday).count

    Day Start (defaults to midnight):

    • Global: Groupdate.day_start = 2 (sets start to 2 am)
    • Per query: User.group_by_day(:created_at, day_start: 2).count
  9. Use Dynamic Grouping and Period Permitting

    master

    You can use group_by_period to pass the period as a variable. To prevent arbitrary input from causing errors, use the permit option to whitelist allowed periods.

    User.group_by_period(params[:period], :created_at, permit: ["day", "week"]).count

    If a period is not in the permit list, an ArgumentError is raised.

    User.group_by_period(params[:period], :created_at, permit: ["day", "week"]).count
  10. Format Grouping Keys

    master

    By default, keys are returned as date or time objects. You can format them using the format option. The format argument accepts:

    • A String (passed to strftime)
    • A Symbol (looked up via I18n.localize in time.formats scope)
    • A Proc

    You can also pass a locale option.

    Example using strftime:

    User.group_by_month(:created_at, format: "%b %Y").count
    User.group_by_month(:created_at, format: "%b %Y").count