Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
MohannadNaj committed Nov 25, 2023
1 parent 0457216 commit 8dcb626
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 24 deletions.
52 changes: 33 additions & 19 deletions src/Function/Date/DateFormat.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,18 @@ class DateFormat implements Expression
],
'sqlite' => [
'Y' => '%Y',
// No format for 3 letter month name.
'M' => '%m',
'm' => '%m',
// No format for full month name.
'F' => '%m',
// No format for 3 letter day name.
'D' => '%d',
'd' => '%d',
// No format for full day name.
'l' => '%d',
'W' => '%W',
'H' => '%H',
// No format for 12 hour with leading zeros.
'h' => '%H',
'i' => '%M',
's' => '%S',
// No format for AM/PM.
// 'A' => ''.
],
'pgsql' => [
'Y' => 'YYYY',
'y' => 'YY',
'M' => 'Mon',
'n' => 'FMMM',
'm' => 'MM',
'F' => 'Month',
'D' => 'Dy',
'd' => 'DD',
'l' => 'Day',
Expand All @@ -81,15 +67,13 @@ class DateFormat implements Expression
'sqlsrv' => [
'A' => 'tt',
'd' => 'dd',
'F' => 'MMM',
'h' => 'hh',
'H' => 'HH',
'i' => 'mm',
'm' => 'MM',
// No format for 3 letter month name.
'M' => 'MMM',
's' => 'ss',
'Y' => 'yyyy',
'D' => 'ddd',
],
];

Expand All @@ -99,20 +83,46 @@ class DateFormat implements Expression
protected array $emulatableCharacters = [
'mysql' => [
'U' => 'unix_timestamp(%s)',
'a' => '(CASE WHEN hour(%s) < 12 THEN \'am\' ELSE \'pm\' END)',
'G' => 'hour(%s)',
'g' => 'hour(%s) %% 12',
'w' => '(dayofweek(%s) + 5) %% 7 + 1',
],
'sqlite' => [
'y' => 'substr(strftime(\'%Y\', %s), 3, 2)',
'A' => '(CASE WHEN strftime(\'%%H\', %s) < \'12\' THEN \'AM\' ELSE \'PM\' END)',
'a' => '(CASE WHEN strftime(\'%%H\', %s) < \'12\' THEN \'am\' ELSE \'pm\' END)',
'y' => 'substr(strftime(\'%%Y\', %s), 3, 2)',
'U' => 'strftime(\'%%s\', %s)',
'n' => 'ltrim(strftime(\'%%m\', %s), \'0\')',
'j' => 'ltrim(strftime(\'%%d\', %s), \'0\')',
'h' => '(CASE WHEN strftime(\'%%H\', %s) > \'12\' THEN strftime(\'%%H\', %s) - 12 ELSE strftime(\'%%H\', %s) END)',
'G' => 'ltrim(strftime(\'%%H\', %s), \'0\')',
'F' => '(CASE WHEN strftime(\'%%m\', %s) = \'01\' THEN \'January\' WHEN strftime(\'%%m\', %s) = \'02\' THEN \'February\' WHEN strftime(\'%%m\', %s) = \'03\' THEN \'March\' WHEN strftime(\'%%m\', %s) = \'04\' THEN \'April\' WHEN strftime(\'%%m\', %s) = \'05\' THEN \'May\' WHEN strftime(\'%%m\', %s) = \'06\' THEN \'June\' WHEN strftime(\'%%m\', %s) = \'07\' THEN \'July\' WHEN strftime(\'%%m\', %s) = \'08\' THEN \'August\' WHEN strftime(\'%%m\', %s) = \'09\' THEN \'September\' WHEN strftime(\'%%m\', %s) = \'10\' THEN \'October\' WHEN strftime(\'%%m\', %s) = \'11\' THEN \'November\' WHEN strftime(\'%%m\', %s) = \'12\' THEN \'December\' END)',
'g' => '(CASE WHEN strftime(\'%%H\', %s) > \'12\' THEN ltrim(strftime(\'%%H\', %s) - 12, \'0\') ELSE ltrim(strftime(\'%%H\', %s), \'0\') END)',
'M' => '(CASE WHEN strftime(\'%%m\', %s) = \'01\' THEN \'Jan\' WHEN strftime(\'%%m\', %s) = \'02\' THEN \'Feb\' WHEN strftime(\'%%m\', %s) = \'03\' THEN \'Mar\' WHEN strftime(\'%%m\', %s) = \'04\' THEN \'Apr\' WHEN strftime(\'%%m\', %s) = \'05\' THEN \'May\' WHEN strftime(\'%%m\', %s) = \'06\' THEN \'Jun\' WHEN strftime(\'%%m\', %s) = \'07\' THEN \'Jul\' WHEN strftime(\'%%m\', %s) = \'08\' THEN \'Aug\' WHEN strftime(\'%%m\', %s) = \'09\' THEN \'Sep\' WHEN strftime(\'%%m\', %s) = \'10\' THEN \'Oct\' WHEN strftime(\'%%m\', %s) = \'11\' THEN \'Nov\' WHEN strftime(\'%%m\', %s) = \'12\' THEN \'Dec\' END)',
'W' => '(strftime(\'%%j\', %s, \'weekday 0\', \'-3 days\') - 1) / 7 + 1',
'w' => '(strftime(\'%%w\', %s) + 6) %% 7 + 1',
],
'pgsql' => [
'U' => 'extract(epoch from %s)::integer',
'G' => 'CAST(extract(hour from %s)::integer AS VARCHAR(2))',
'F' => 'TRIM(to_char(%s, \'Month\'))',
'g' => '(extract(hour from %s)::integer %% 12)',
'a' => '(CASE WHEN extract(hour from %s)::integer < 12 THEN \'am\' ELSE \'pm\' END)',
'w' => 'extract(dow from %s)::integer',
],
'sqlsrv' => [
'a' => '(CASE WHEN format(%s, \'tt\') = \'am\' THEN \'am\' ELSE \'pm\' END)',
'n' => 'cast(month(%s) as varchar(2))',
'U' => 'datediff(second, \'1970-01-01\', %s)',
'j' => 'cast(day(%s) as varchar(2))',
'G' => 'cast(datepart(hour, %s) as varchar(2))',
'g' => '(cast(datepart(hour, %s) as varchar(2)) %% 12)',
'F' => '(CASE WHEN month(%s) = 1 THEN \'January\' WHEN month(%s) = 2 THEN \'February\' WHEN month(%s) = 3 THEN \'March\' WHEN month(%s) = 4 THEN \'April\' WHEN month(%s) = 5 THEN \'May\' WHEN month(%s) = 6 THEN \'June\' WHEN month(%s) = 7 THEN \'July\' WHEN month(%s) = 8 THEN \'August\' WHEN month(%s) = 9 THEN \'September\' WHEN month(%s) = 10 THEN \'October\' WHEN month(%s) = 11 THEN \'November\' WHEN month(%s) = 12 THEN \'December\' END)',
'M' => '(CASE WHEN month(%s) = 1 THEN \'Jan\' WHEN month(%s) = 2 THEN \'Feb\' WHEN month(%s) = 3 THEN \'Mar\' WHEN month(%s) = 4 THEN \'Apr\' WHEN month(%s) = 5 THEN \'May\' WHEN month(%s) = 6 THEN \'Jun\' WHEN month(%s) = 7 THEN \'Jul\' WHEN month(%s) = 8 THEN \'Aug\' WHEN month(%s) = 9 THEN \'Sep\' WHEN month(%s) = 10 THEN \'Oct\' WHEN month(%s) = 11 THEN \'Nov\' WHEN month(%s) = 12 THEN \'Dec\' END)',
'y' => 'right(cast(year(%s) as varchar(4)), 2)',
'W' => 'cast(datepart(ISO_WEEK, %s) as varchar(2))',
'w' => '(cast(datepart(weekday, %s) as varchar(2)) + 5) %% 7 + 1',
],
];

Expand Down Expand Up @@ -162,7 +172,11 @@ public function getValue(Grammar $grammar): string
if ($emulatableCharacter) {
$expressions[] = new QueryExpression(sprintf(
$emulatableCharacter,
$this->stringize($grammar, $this->expression)
// Emulated query can have multiple '%s' occurrences
...array_fill(
start_index: 0,
count: substr_count($emulatableCharacter, '%s'),
value: $this->stringize($grammar, $this->expression)),
));
}
}
Expand Down
37 changes: 32 additions & 5 deletions tests/Function/Date/DateFormatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,41 @@
});

DB::table($table)->insert([
'created_at' => '2021-01-01 12:00:00',
'created_at' => '2021-01-01 09:00:00',
]);

if (
DB::connection()->getDriverName() === 'mysql'
) {
DB::statement('SET time_zone = \'+00:00\'');
}

foreach ([
'Y-m-d H:i:s' => '2021-01-01 12:00:00',
'Y-n-j' => '2021-1-1',
'Y-m-d' => '2021-01-01',
'U' => ['1609502400', 'except' => 'mysql'],
'U' => '1609491600',
'F' => 'January',
'M' => 'Jan',
'm' => '01',
'n' => '1',
'd' => '01',
// 'D' => 'Fri',
// 'l' => 'Friday',
'j' => '1',
'Y' => '2021',
'y' => '21',
'H' => '09',
'h' => '09',
'G' => '9',
'g' => '9',
'i' => '00',
's' => '00',
'a' => 'am',
'A' => 'AM',
'W' => '53',
'w' => '5',
// 't' => '31',
// 'I' => '0',
// 'o' => '2020',

] as $format => $expected) {
$expression = new DateFormat('created_at', $format);

Expand Down

0 comments on commit 8dcb626

Please sign in to comment.