diff --git a/db_utils/db_utils.go b/db_utils/db_utils.go
index 5e9202cac83d863003045b74c95b0b72d6498908..4abd2d655b0392ae29c1dceb635836c8ec1c49a0 100644
--- a/db_utils/db_utils.go
+++ b/db_utils/db_utils.go
@@ -3,7 +3,9 @@ package db_utils
 import (
 	"fmt"
 	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/date_utils"
+	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors"
 	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/number_utils"
+	"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/struct_utils"
 	"regexp"
 	"strings"
 	"time"
@@ -79,3 +81,38 @@ func AbsoluteDateStringQuery(absolute string) string {
 	// Not matched, so try to match it literally (It'll probably break and return nothing, but that's good)
 	return fmt.Sprintf(" = '%v'", absolute)
 }
+
+type PageParams struct {
+	Limit  int64 `json:"limit,omitempty"`  // Limit number of items returned in list (default: 0 (no limit))
+	Offset int64 `json:"offset,omitempty"` // Offset in list (default: 0 (no offset))
+}
+
+func (params *PageParams) Validate() error {
+	if params.Limit < 0 {
+		return errors.Errorf("limit=%d must be positive", params.Limit)
+	}
+	if params.Offset < 0 {
+		return errors.Errorf("offset=%d must be >=0", params.Offset)
+	}
+	return nil
+}
+
+func (params *PageParams) EnforceLimit() {
+	if params.Limit <= 0 {
+		params.Limit = 20
+	}
+}
+
+func ValidateDateFilters(params any, dateFiltersToValidate ...string) error {
+	queryParams := struct_utils.MapParams(params)
+	for _, filter := range dateFiltersToValidate {
+		date, present := queryParams[filter]
+		if present {
+			_, err := date_utils.ParseTimeString(date)
+			if err != nil {
+				return errors.Errorf("invalid %s: %s", filter, date)
+			}
+		}
+	}
+	return nil
+}
diff --git a/db_utils/db_utils_test.go b/db_utils/db_utils_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..33c50fddef89a08e00b952f18136e998d4bc3f4f
--- /dev/null
+++ b/db_utils/db_utils_test.go
@@ -0,0 +1,89 @@
+package db_utils
+
+import (
+	"testing"
+)
+
+func TestPageParams_Validate(t *testing.T) {
+	tests := []struct {
+		name    string
+		params  PageParams
+		wantErr bool
+	}{
+		{"ValidParams", PageParams{Limit: 10, Offset: 5}, false},
+		{"NegativeLimit", PageParams{Limit: -1, Offset: 5}, true},
+		{"NegativeOffset", PageParams{Limit: 10, Offset: -1}, true},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			err := tt.params.Validate()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestPageParams_EnforceLimit(t *testing.T) {
+	tests := []struct {
+		name   string
+		params PageParams
+		want   int64
+	}{
+		{"NoLimit", PageParams{Limit: 0}, 20},
+		{"NegativeLimit", PageParams{Limit: -5}, 20},
+		{"PositiveLimit", PageParams{Limit: 10}, 10},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.params.EnforceLimit()
+			if tt.params.Limit != tt.want {
+				t.Errorf("EnforceLimit() = %v, want %v", tt.params.Limit, tt.want)
+			}
+		})
+	}
+}
+
+func TestValidateDateFilters(t *testing.T) {
+	type args struct {
+		params                any
+		dateFiltersToValidate []string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			"ValidDateFilter",
+			args{params: struct {
+				Date string `json:"date"`
+			}{Date: "2023-10-01T00:00:00Z"}, dateFiltersToValidate: []string{"date"}},
+			false,
+		},
+		{
+			"InvalidDateFilter",
+			args{params: struct {
+				Date string `json:"date"`
+			}{Date: "invalid-date"}, dateFiltersToValidate: []string{"date"}},
+			true,
+		},
+		{
+			"MissingDateFilter",
+			args{params: struct {
+				Date string `json:"date"`
+			}{Date: "2023-10-01T00:00:00Z"}, dateFiltersToValidate: []string{"non_existent_date"}},
+			false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := ValidateDateFilters(tt.args.params, tt.args.dateFiltersToValidate...); (err != nil) != tt.wantErr {
+				t.Errorf("ValidateDateFilters() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}