phibble

Dates and strings

Verification

Scope

Date parsing, date parts, date rounding, periods, and time zones; string patterns, padding, truncation, and case. mutate() on all five backends.

References

Reference
lubridate 1.9.5 and stringr 1.6.0, on R 4.6.1
Versions
R 4.6.1, stringr 1.6.0, lubridate 1.9.5, jsonlite 2.0.0, PHP 8.5.10, SQLite 3.45.2, PostgreSQL 17.0 (Laravel Herd), MySQL 8.0.46, php_polars 0.1.0

Data

date and string cases
5 rows of dates, datetimes, and text with NA; per-case vectors Source

Method

tests/r/lubridate_stringr.R evaluates each case with lubridate and stringr and writes the results. The PHP tests evaluate the same expressions in each backend. Fixtures regenerated with the listed R versions on 2026-11-01; output byte-identical to the committed files.

Check
Comparison with a reference implementation
Recorded
2026-11-02, PHP 8.5.10, macOS 27.0.1 (arm64), commit 1abdeb1

Tolerances

exact equality

Applies to: Column values

Dates as YYYY-MM-DD, datetimes as YYYY-MM-DD HH:MM:SS +hhmm in their time zone, numbers rounded to 9 decimal places, NA in identical positions

exact equality

Applies to: Polars column values

As above, with no fallback to a DataFrame except str_to_title(), which requires ICU word breaks

x: package value; r: reference value.

Results

325 comparisons in 65 cases: 325 pass, 0 fail, 0 skipped.

By case

Results by case
Case Comparisons Status
ymd 5 pass
ymd_hms 5 pass
dmy 5 pass
mdy 5 pass
parse_dt 5 pass
year 5 pass
month 5 pass
day 5 pass
wday 5 pass
wday_mon 5 pass
yday 5 pass
quarter 5 pass
hour 5 pass
minute 5 pass
second 5 pass
year_t 5 pass
floor_hour 5 pass
floor_15min 5 pass
floor_week 5 pass
floor_month_d 5 pass
floor_quarter_d 5 pass
floor_year_d 5 pass
ceiling_month_d 5 pass
ceiling_hour 5 pass
round_day 5 pass
round_month_d 5 pass
plus_days 5 pass
plus_months 5 pass
plus_years 5 pass
minus_weeks 5 pass
plus_hours 5 pass
plus_minutes 5 pass
diff_days 5 pass
difftime_hours 5 pass
difftime_weeks 5 pass
with_tz 5 pass
force_tz 5 pass
str_detect 5 pass
str_detect_fixed 5 pass
str_detect_ic 5 pass
str_detect_negate 5 pass
str_starts 5 pass
str_ends 5 pass
str_count 5 pass
str_count_fixed 5 pass
str_count_class 5 pass
str_extract 5 pass
str_extract_all 5 pass
str_split 5 pass
str_split_i 5 pass
str_split_i_neg 5 pass
str_replace 5 pass
str_replace_all 5 pass
str_replace_all_fixed 5 pass
str_replace_na 5 pass
str_pad 5 pass
str_pad_right 5 pass
str_pad_both 5 pass
str_trunc 5 pass
str_trunc_left 5 pass
str_trunc_center 5 pass
str_to_title 5 pass
str_to_upper 5 pass
str_squish 5 pass
str_length 5 pass
All 325 comparisons
Every comparison
Case Implementation Quantity Criterion Values Status
ymd DataFrame mutate exact equality 5 pass
ymd_hms DataFrame mutate exact equality 5 pass
dmy DataFrame mutate exact equality 5 pass
mdy DataFrame mutate exact equality 5 pass
parse_dt DataFrame mutate exact equality 5 pass
year DataFrame mutate exact equality 5 pass
month DataFrame mutate exact equality 5 pass
day DataFrame mutate exact equality 5 pass
wday DataFrame mutate exact equality 5 pass
wday_mon DataFrame mutate exact equality 5 pass
yday DataFrame mutate exact equality 5 pass
quarter DataFrame mutate exact equality 5 pass
hour DataFrame mutate exact equality 5 pass
minute DataFrame mutate exact equality 5 pass
second DataFrame mutate exact equality 5 pass
year_t DataFrame mutate exact equality 5 pass
floor_hour DataFrame mutate exact equality 5 pass
floor_15min DataFrame mutate exact equality 5 pass
floor_week DataFrame mutate exact equality 5 pass
floor_month_d DataFrame mutate exact equality 5 pass
floor_quarter_d DataFrame mutate exact equality 5 pass
floor_year_d DataFrame mutate exact equality 5 pass
ceiling_month_d DataFrame mutate exact equality 5 pass
ceiling_hour DataFrame mutate exact equality 5 pass
round_day DataFrame mutate exact equality 5 pass
round_month_d DataFrame mutate exact equality 5 pass
plus_days DataFrame mutate exact equality 5 pass
plus_months DataFrame mutate exact equality 5 pass
plus_years DataFrame mutate exact equality 5 pass
minus_weeks DataFrame mutate exact equality 5 pass
plus_hours DataFrame mutate exact equality 5 pass
plus_minutes DataFrame mutate exact equality 5 pass
diff_days DataFrame mutate exact equality 5 pass
difftime_hours DataFrame mutate exact equality 5 pass
difftime_weeks DataFrame mutate exact equality 5 pass
with_tz DataFrame mutate exact equality 5 pass
force_tz DataFrame mutate exact equality 5 pass
str_detect DataFrame mutate exact equality 5 pass
str_detect_fixed DataFrame mutate exact equality 5 pass
str_detect_ic DataFrame mutate exact equality 5 pass
str_detect_negate DataFrame mutate exact equality 5 pass
str_starts DataFrame mutate exact equality 5 pass
str_ends DataFrame mutate exact equality 5 pass
str_count DataFrame mutate exact equality 5 pass
str_count_fixed DataFrame mutate exact equality 5 pass
str_count_class DataFrame mutate exact equality 5 pass
str_extract DataFrame mutate exact equality 5 pass
str_extract_all DataFrame mutate exact equality 5 pass
str_split DataFrame mutate exact equality 5 pass
str_split_i DataFrame mutate exact equality 5 pass
str_split_i_neg DataFrame mutate exact equality 5 pass
str_replace DataFrame mutate exact equality 5 pass
str_replace_all DataFrame mutate exact equality 5 pass
str_replace_all_fixed DataFrame mutate exact equality 5 pass
str_replace_na DataFrame mutate exact equality 5 pass
str_pad DataFrame mutate exact equality 5 pass
str_pad_right DataFrame mutate exact equality 5 pass
str_pad_both DataFrame mutate exact equality 5 pass
str_trunc DataFrame mutate exact equality 5 pass
str_trunc_left DataFrame mutate exact equality 5 pass
str_trunc_center DataFrame mutate exact equality 5 pass
str_to_title DataFrame mutate exact equality 5 pass
str_to_upper DataFrame mutate exact equality 5 pass
str_squish DataFrame mutate exact equality 5 pass
str_length DataFrame mutate exact equality 5 pass
ymd Polars mutate exact equality 5 pass
ymd_hms Polars mutate exact equality 5 pass
dmy Polars mutate exact equality 5 pass
mdy Polars mutate exact equality 5 pass
parse_dt Polars mutate exact equality 5 pass
year Polars mutate exact equality 5 pass
month Polars mutate exact equality 5 pass
day Polars mutate exact equality 5 pass
wday Polars mutate exact equality 5 pass
wday_mon Polars mutate exact equality 5 pass
yday Polars mutate exact equality 5 pass
quarter Polars mutate exact equality 5 pass
hour Polars mutate exact equality 5 pass
minute Polars mutate exact equality 5 pass
second Polars mutate exact equality 5 pass
year_t Polars mutate exact equality 5 pass
floor_hour Polars mutate exact equality 5 pass
floor_15min Polars mutate exact equality 5 pass
floor_week Polars mutate exact equality 5 pass
floor_month_d Polars mutate exact equality 5 pass
floor_quarter_d Polars mutate exact equality 5 pass
floor_year_d Polars mutate exact equality 5 pass
ceiling_month_d Polars mutate exact equality 5 pass
ceiling_hour Polars mutate exact equality 5 pass
round_day Polars mutate exact equality 5 pass
round_month_d Polars mutate exact equality 5 pass
plus_days Polars mutate exact equality 5 pass
plus_months Polars mutate exact equality 5 pass
plus_years Polars mutate exact equality 5 pass
minus_weeks Polars mutate exact equality 5 pass
plus_hours Polars mutate exact equality 5 pass
plus_minutes Polars mutate exact equality 5 pass
diff_days Polars mutate exact equality 5 pass
difftime_hours Polars mutate exact equality 5 pass
difftime_weeks Polars mutate exact equality 5 pass
with_tz Polars mutate exact equality 5 pass
force_tz Polars mutate exact equality 5 pass
str_detect Polars mutate exact equality 5 pass
str_detect_fixed Polars mutate exact equality 5 pass
str_detect_ic Polars mutate exact equality 5 pass
str_detect_negate Polars mutate exact equality 5 pass
str_starts Polars mutate exact equality 5 pass
str_ends Polars mutate exact equality 5 pass
str_count Polars mutate exact equality 5 pass
str_count_fixed Polars mutate exact equality 5 pass
str_count_class Polars mutate exact equality 5 pass
str_extract Polars mutate exact equality 5 pass
str_extract_all Polars mutate exact equality 5 pass
str_split Polars mutate exact equality 5 pass
str_split_i Polars mutate exact equality 5 pass
str_split_i_neg Polars mutate exact equality 5 pass
str_replace Polars mutate exact equality 5 pass
str_replace_all Polars mutate exact equality 5 pass
str_replace_all_fixed Polars mutate exact equality 5 pass
str_replace_na Polars mutate exact equality 5 pass
str_pad Polars mutate exact equality 5 pass
str_pad_right Polars mutate exact equality 5 pass
str_pad_both Polars mutate exact equality 5 pass
str_trunc Polars mutate exact equality 5 pass
str_trunc_left Polars mutate exact equality 5 pass
str_trunc_center Polars mutate exact equality 5 pass
str_to_title Polars mutate exact equality 5 pass
str_to_upper Polars mutate exact equality 5 pass
str_squish Polars mutate exact equality 5 pass
str_length Polars mutate exact equality 5 pass
ymd SQLite mutate exact equality 5 pass
ymd_hms SQLite mutate exact equality 5 pass
dmy SQLite mutate exact equality 5 pass
mdy SQLite mutate exact equality 5 pass
parse_dt SQLite mutate exact equality 5 pass
year SQLite mutate exact equality 5 pass
month SQLite mutate exact equality 5 pass
day SQLite mutate exact equality 5 pass
wday SQLite mutate exact equality 5 pass
wday_mon SQLite mutate exact equality 5 pass
yday SQLite mutate exact equality 5 pass
quarter SQLite mutate exact equality 5 pass
hour SQLite mutate exact equality 5 pass
minute SQLite mutate exact equality 5 pass
second SQLite mutate exact equality 5 pass
year_t SQLite mutate exact equality 5 pass
floor_hour SQLite mutate exact equality 5 pass
floor_15min SQLite mutate exact equality 5 pass
floor_week SQLite mutate exact equality 5 pass
floor_month_d SQLite mutate exact equality 5 pass
floor_quarter_d SQLite mutate exact equality 5 pass
floor_year_d SQLite mutate exact equality 5 pass
ceiling_month_d SQLite mutate exact equality 5 pass
ceiling_hour SQLite mutate exact equality 5 pass
round_day SQLite mutate exact equality 5 pass
round_month_d SQLite mutate exact equality 5 pass
plus_days SQLite mutate exact equality 5 pass
plus_months SQLite mutate exact equality 5 pass
plus_years SQLite mutate exact equality 5 pass
minus_weeks SQLite mutate exact equality 5 pass
plus_hours SQLite mutate exact equality 5 pass
plus_minutes SQLite mutate exact equality 5 pass
diff_days SQLite mutate exact equality 5 pass
difftime_hours SQLite mutate exact equality 5 pass
difftime_weeks SQLite mutate exact equality 5 pass
with_tz SQLite mutate exact equality 5 pass
force_tz SQLite mutate exact equality 5 pass
str_detect SQLite mutate exact equality 5 pass
str_detect_fixed SQLite mutate exact equality 5 pass
str_detect_ic SQLite mutate exact equality 5 pass
str_detect_negate SQLite mutate exact equality 5 pass
str_starts SQLite mutate exact equality 5 pass
str_ends SQLite mutate exact equality 5 pass
str_count SQLite mutate exact equality 5 pass
str_count_fixed SQLite mutate exact equality 5 pass
str_count_class SQLite mutate exact equality 5 pass
str_extract SQLite mutate exact equality 5 pass
str_extract_all SQLite mutate exact equality 5 pass
str_split SQLite mutate exact equality 5 pass
str_split_i SQLite mutate exact equality 5 pass
str_split_i_neg SQLite mutate exact equality 5 pass
str_replace SQLite mutate exact equality 5 pass
str_replace_all SQLite mutate exact equality 5 pass
str_replace_all_fixed SQLite mutate exact equality 5 pass
str_replace_na SQLite mutate exact equality 5 pass
str_pad SQLite mutate exact equality 5 pass
str_pad_right SQLite mutate exact equality 5 pass
str_pad_both SQLite mutate exact equality 5 pass
str_trunc SQLite mutate exact equality 5 pass
str_trunc_left SQLite mutate exact equality 5 pass
str_trunc_center SQLite mutate exact equality 5 pass
str_to_title SQLite mutate exact equality 5 pass
str_to_upper SQLite mutate exact equality 5 pass
str_squish SQLite mutate exact equality 5 pass
str_length SQLite mutate exact equality 5 pass
ymd PostgreSQL mutate exact equality 5 pass
ymd_hms PostgreSQL mutate exact equality 5 pass
dmy PostgreSQL mutate exact equality 5 pass
mdy PostgreSQL mutate exact equality 5 pass
parse_dt PostgreSQL mutate exact equality 5 pass
year PostgreSQL mutate exact equality 5 pass
month PostgreSQL mutate exact equality 5 pass
day PostgreSQL mutate exact equality 5 pass
wday PostgreSQL mutate exact equality 5 pass
wday_mon PostgreSQL mutate exact equality 5 pass
yday PostgreSQL mutate exact equality 5 pass
quarter PostgreSQL mutate exact equality 5 pass
hour PostgreSQL mutate exact equality 5 pass
minute PostgreSQL mutate exact equality 5 pass
second PostgreSQL mutate exact equality 5 pass
year_t PostgreSQL mutate exact equality 5 pass
floor_hour PostgreSQL mutate exact equality 5 pass
floor_15min PostgreSQL mutate exact equality 5 pass
floor_week PostgreSQL mutate exact equality 5 pass
floor_month_d PostgreSQL mutate exact equality 5 pass
floor_quarter_d PostgreSQL mutate exact equality 5 pass
floor_year_d PostgreSQL mutate exact equality 5 pass
ceiling_month_d PostgreSQL mutate exact equality 5 pass
ceiling_hour PostgreSQL mutate exact equality 5 pass
round_day PostgreSQL mutate exact equality 5 pass
round_month_d PostgreSQL mutate exact equality 5 pass
plus_days PostgreSQL mutate exact equality 5 pass
plus_months PostgreSQL mutate exact equality 5 pass
plus_years PostgreSQL mutate exact equality 5 pass
minus_weeks PostgreSQL mutate exact equality 5 pass
plus_hours PostgreSQL mutate exact equality 5 pass
plus_minutes PostgreSQL mutate exact equality 5 pass
diff_days PostgreSQL mutate exact equality 5 pass
difftime_hours PostgreSQL mutate exact equality 5 pass
difftime_weeks PostgreSQL mutate exact equality 5 pass
with_tz PostgreSQL mutate exact equality 5 pass
force_tz PostgreSQL mutate exact equality 5 pass
str_detect PostgreSQL mutate exact equality 5 pass
str_detect_fixed PostgreSQL mutate exact equality 5 pass
str_detect_ic PostgreSQL mutate exact equality 5 pass
str_detect_negate PostgreSQL mutate exact equality 5 pass
str_starts PostgreSQL mutate exact equality 5 pass
str_ends PostgreSQL mutate exact equality 5 pass
str_count PostgreSQL mutate exact equality 5 pass
str_count_fixed PostgreSQL mutate exact equality 5 pass
str_count_class PostgreSQL mutate exact equality 5 pass
str_extract PostgreSQL mutate exact equality 5 pass
str_extract_all PostgreSQL mutate exact equality 5 pass
str_split PostgreSQL mutate exact equality 5 pass
str_split_i PostgreSQL mutate exact equality 5 pass
str_split_i_neg PostgreSQL mutate exact equality 5 pass
str_replace PostgreSQL mutate exact equality 5 pass
str_replace_all PostgreSQL mutate exact equality 5 pass
str_replace_all_fixed PostgreSQL mutate exact equality 5 pass
str_replace_na PostgreSQL mutate exact equality 5 pass
str_pad PostgreSQL mutate exact equality 5 pass
str_pad_right PostgreSQL mutate exact equality 5 pass
str_pad_both PostgreSQL mutate exact equality 5 pass
str_trunc PostgreSQL mutate exact equality 5 pass
str_trunc_left PostgreSQL mutate exact equality 5 pass
str_trunc_center PostgreSQL mutate exact equality 5 pass
str_to_title PostgreSQL mutate exact equality 5 pass
str_to_upper PostgreSQL mutate exact equality 5 pass
str_squish PostgreSQL mutate exact equality 5 pass
str_length PostgreSQL mutate exact equality 5 pass
ymd MySQL mutate exact equality 5 pass
ymd_hms MySQL mutate exact equality 5 pass
dmy MySQL mutate exact equality 5 pass
mdy MySQL mutate exact equality 5 pass
parse_dt MySQL mutate exact equality 5 pass
year MySQL mutate exact equality 5 pass
month MySQL mutate exact equality 5 pass
day MySQL mutate exact equality 5 pass
wday MySQL mutate exact equality 5 pass
wday_mon MySQL mutate exact equality 5 pass
yday MySQL mutate exact equality 5 pass
quarter MySQL mutate exact equality 5 pass
hour MySQL mutate exact equality 5 pass
minute MySQL mutate exact equality 5 pass
second MySQL mutate exact equality 5 pass
year_t MySQL mutate exact equality 5 pass
floor_hour MySQL mutate exact equality 5 pass
floor_15min MySQL mutate exact equality 5 pass
floor_week MySQL mutate exact equality 5 pass
floor_month_d MySQL mutate exact equality 5 pass
floor_quarter_d MySQL mutate exact equality 5 pass
floor_year_d MySQL mutate exact equality 5 pass
ceiling_month_d MySQL mutate exact equality 5 pass
ceiling_hour MySQL mutate exact equality 5 pass
round_day MySQL mutate exact equality 5 pass
round_month_d MySQL mutate exact equality 5 pass
plus_days MySQL mutate exact equality 5 pass
plus_months MySQL mutate exact equality 5 pass
plus_years MySQL mutate exact equality 5 pass
minus_weeks MySQL mutate exact equality 5 pass
plus_hours MySQL mutate exact equality 5 pass
plus_minutes MySQL mutate exact equality 5 pass
diff_days MySQL mutate exact equality 5 pass
difftime_hours MySQL mutate exact equality 5 pass
difftime_weeks MySQL mutate exact equality 5 pass
with_tz MySQL mutate exact equality 5 pass
force_tz MySQL mutate exact equality 5 pass
str_detect MySQL mutate exact equality 5 pass
str_detect_fixed MySQL mutate exact equality 5 pass
str_detect_ic MySQL mutate exact equality 5 pass
str_detect_negate MySQL mutate exact equality 5 pass
str_starts MySQL mutate exact equality 5 pass
str_ends MySQL mutate exact equality 5 pass
str_count MySQL mutate exact equality 5 pass
str_count_fixed MySQL mutate exact equality 5 pass
str_count_class MySQL mutate exact equality 5 pass
str_extract MySQL mutate exact equality 5 pass
str_extract_all MySQL mutate exact equality 5 pass
str_split MySQL mutate exact equality 5 pass
str_split_i MySQL mutate exact equality 5 pass
str_split_i_neg MySQL mutate exact equality 5 pass
str_replace MySQL mutate exact equality 5 pass
str_replace_all MySQL mutate exact equality 5 pass
str_replace_all_fixed MySQL mutate exact equality 5 pass
str_replace_na MySQL mutate exact equality 5 pass
str_pad MySQL mutate exact equality 5 pass
str_pad_right MySQL mutate exact equality 5 pass
str_pad_both MySQL mutate exact equality 5 pass
str_trunc MySQL mutate exact equality 5 pass
str_trunc_left MySQL mutate exact equality 5 pass
str_trunc_center MySQL mutate exact equality 5 pass
str_to_title MySQL mutate exact equality 5 pass
str_to_upper MySQL mutate exact equality 5 pass
str_squish MySQL mutate exact equality 5 pass
str_length MySQL mutate exact equality 5 pass

Limitations

Known differences

  • SQL databases: functions without a faithful SQL translation run in memory after the query. These cases are compared identically.

Reproduction

From the repository root
Rscript tests/r/lubridate_stringr.R
PHIBBLE_TEST_PGSQL="pgsql:host=127.0.0.1;port=5432;dbname=postgres" PHIBBLE_TEST_PGSQL_USER=postgres PHIBBLE_TEST_MYSQL="mysql:host=127.0.0.1;port=3306" PHIBBLE_TEST_MYSQL_USER=root php vendor/bin/pest tests/LubridateStringrTest.php tests/SqlTest.php
php -d extension=php_polars.so php vendor/bin/pest tests/Polars/PolarsLubridateStringrTest.php
Raw record
site/verifications/lubridate-stringr.json
Input data
tests/fixtures/expr/lubridate_stringr.json