My program does not expect any order. That's what "hashes" are made for.
Well, to continue down this avenue of argumentation: If you're using hashes, then isn't it also likely that you know all the names of the keys in advance? Then you could do $db->select( my_table => ['price',...] )->hashes. Then you wouldn't be getting more columns than necessary when your table definition changes, you'd get hard failures instead of unexplained undefs when your column names change, and so on. I know that listing all columns feels tedious, but I tend to agree that SELECT * is brittle, and IMHO one solution is having the column names in Perl variables and then building the queries instead of hard-coding the SQL.
Plus, query building with SQL::Abstract means you can do fun things on the Perl side like using map to easily apply the TO_CHAR function to multiple columns, something like $db->select( my_table => [ map { \["TO_CHAR(?,'YYYY-MM-DDTHH24:MI:SS') AS ?",$_,$_] } @datetime_columns ] ) (untested).
Yet another idea might be to look at extending Mojo::Pg::Results's expand method, which already processes JSON columns, you could use this to convert date/time columns to DateTime objects automatically. The "advantage" of this solution would be that you could continue using SELECT *...