File tree Expand file tree Collapse file tree 4 files changed +75
-0
lines changed
Expand file tree Collapse file tree 4 files changed +75
-0
lines changed Original file line number Diff line number Diff line change @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55The format is based on [ Keep a Changelog] ( https://keepachangelog.com/en/1.0.0/ ) ,
66and this project adheres to [ Semantic Versioning] ( https://semver.org/spec/v2.0.0.html ) .
77
8+ ## [ Unreleased]
9+ ### Added
10+ * ` ExtractYear ` time function to extract the year from date/datetime columns
11+
812## [ 1.5.0] - 2025-02-14
913### Added
1014* Laravel 12 support
Original file line number Diff line number Diff line change @@ -360,12 +360,25 @@ Schema::table('users', function (Blueprint $table): void {
360360
361361#### Time
362362``` php
363+ use Tpetry\QueryExpressions\Function\Time\ExtractYear;
363364use Tpetry\QueryExpressions\Function\Time\Now;
364365use Tpetry\QueryExpressions\Function\Time\TimestampBin;
365366
367+ new ExtractYear(string|Expression $column);
366368new Now();
367369new TimestampBin(string|Expression $expression, DateInterval $step, ?DateTimeInterface $origin = null);
368370
371+ // Extract year for filtering or grouping
372+ User::select([
373+ new Alias(new ExtractYear('created_at'), 'registration_year'),
374+ new Count('*'),
375+ ])->groupBy(new ExtractYear('created_at'))->get();
376+
377+ // Use with CountFilter for year-based aggregations
378+ Movie::select([
379+ new Alias(new CountFilter(new Equal(new ExtractYear('released_at'), new Value(2024))), 'released_2024'),
380+ ])->get();
381+
369382BlogVisit::select([
370383 'url',
371384 new TimestampBin('created_at', DateInterval::createFromDateString('5 minutes')),
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Tpetry \QueryExpressions \Function \Time ;
6+
7+ use Illuminate \Contracts \Database \Query \Expression ;
8+ use Illuminate \Database \Grammar ;
9+ use Tpetry \QueryExpressions \Concerns \IdentifiesDriver ;
10+ use Tpetry \QueryExpressions \Concerns \StringizeExpression ;
11+
12+ class ExtractYear implements Expression
13+ {
14+ use IdentifiesDriver;
15+ use StringizeExpression;
16+
17+ public function __construct (
18+ private readonly string |Expression $ column ,
19+ ) {}
20+
21+ public function getValue (Grammar $ grammar ): string
22+ {
23+ $ column = $ this ->stringize ($ grammar , $ this ->column );
24+
25+ return match ($ this ->identify ($ grammar )) {
26+ 'mariadb ' , 'mysql ' , 'sqlsrv ' => "year( {$ column }) " ,
27+ 'pgsql ' => "extract(year from {$ column })::int " ,
28+ 'sqlite ' => "cast(strftime('%Y', {$ column }) as integer) " ,
29+ };
30+ }
31+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ use Illuminate \Database \Query \Expression ;
6+ use Illuminate \Database \Schema \Blueprint ;
7+ use Tpetry \QueryExpressions \Function \Time \ExtractYear ;
8+
9+ it ('can extract the year from a column ' )
10+ ->expect (new ExtractYear ('val ' ))
11+ ->toBeExecutable (function (Blueprint $ table ) {
12+ $ table ->date ('val ' );
13+ })
14+ ->toBeMysql ('year(`val`) ' )
15+ ->toBePgsql ('extract(year from "val")::int ' )
16+ ->toBeSqlite ('cast(strftime( \'%Y \', "val") as integer) ' )
17+ ->toBeSqlsrv ('year([val]) ' );
18+
19+ it ('can extract the year from an expression ' )
20+ ->expect (new ExtractYear (new Expression ('current_date ' )))
21+ ->toBeExecutable (function (Blueprint $ table ) {
22+ $ table ->date ('val ' );
23+ })
24+ ->toBeMysql ('year(current_date) ' )
25+ ->toBePgsql ('extract(year from current_date)::int ' )
26+ ->toBeSqlite ('cast(strftime( \'%Y \', current_date) as integer) ' )
27+ ->toBeSqlsrv ('year(current_date) ' );
You can’t perform that action at this time.
0 commit comments