date
Version, currently main branch1 version
- main branchlatestApr 18, 2026
github.com/jgaskins/date
Crystal Date type without a time. Useful for tracking things with calendar days rather than multiples of seconds.
Installation
# Add this to your shard.yml
dependencies:
date:
github: jgaskins/date
branch: mainmain is a branch, not a release, so this tracks it rather than pinning a version.
Then run:
shards installshard.yml
- Crystal
>= 1.18.2- License
- MIT
- Author
- Jamie Gaskins
Dependencies
Runtime Dependencies
- duration*github: jgaskins/duration
Development Dependencies
- pg*github: will/crystal-pgdev
README
date
This shard provides a Date type without a timestamp. This is useful when you need to measure things in calendar days where a time component complicates things. For example, if a subscription expires on a certain date, you don't necessarily need to mark a time on that day that the subscription expires and, in fact, using a timestamp means you have to decide whether to use the time of day or truncate to the day boundary. Then you have to apply that logic consistently throughout your app. If instead, you use a date representation that has no time of day, this just works for you.
Installation
-
Add the dependency to your
shard.yml:dependencies: date: github: jgaskins/date -
Run
shards install
Usage
require "date"
Date.new(2026, 1, 23) # => Date(@year=2026, @month=1, @day=23)
Date.parse("2026-01-23") # => Date(@year=2026, @month=1, @day=23)
Using with Postgres date columns
By default, the pg shard parses date values coming back from Postgres as Crystal Time instances, but you can also read them as Date values.
require "date/pg"
db = DB.open("postgres:///")
db.exec <<-SQL
CREATE TABLE subscriptions(
id uuid PRIMARY KEY DEFAULT uuidv7(), -- requires Postgres 18
expires_on date NOT NULL
)
SQL
at_exit { db.exec "DROP TABLE IF EXISTS subscriptions" }
# Insert one expired and one active subscription
db.exec <<-SQL
INSERT INTO subscriptions (expires_on)
VALUES
('2020-01-23'),
('2090-02-26')
SQL
# Only returns the expired subscription
pp expired = db.query_all <<-SQL, as: {UUID, Date}
SELECT id, expires_on
FROM subscriptions
WHERE expires_on < now()
SQL
# [{UUID(019c9d38-8462-7660-8506-65f490826fe9),
# Date(@day=23, @month=1, @year=2020)}]
You can also use it with DB::Serializable.
struct Subscription
include DB::Serializable
getter id : UUID
getter expires_on : Date
end
pp expired = db.query_all <<-SQL, as: Subscription
SELECT id, expires_on
FROM subscriptions
WHERE expires_on < now()
SQL
# [Subscription(
# @expires_on=Date(@day=23, @month=1, @year=2020),
# @id=UUID(019c9d3a-39cb-7640-8593-266f9f4747cd))]
Contributing
- Fork it (https://github.com/jgaskins/date/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Jamie Gaskins - creator and maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This branch
- Branch
main- Seen
- Apr 18, 2026
- Crystal
>= 1.18.2- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/jgaskins/date
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 14, 2026
- Synced
- Aug 14, 2026
- Versions
- 1