sqlpostgresqlpostgresql-14postgresql-15

In Postgres, what does the ".USSTZ" at the end mean in 'YYYY-MM-DD"T"HH24:MI:SS.USSTZ'?


In Postgres, I am trying to parse the following text to a timestamp with timezone:

2023-08-09T23:39:18.832Z

The following:

select TO_TIMESTAMP('2023-08-09T23:39:18.832Z', 'YYYY-MM-DD"T"HH24:MI:SS.USSTZ');

does seem to work. However, I am not sure what the ".USSTZ" at the end means.

I am looking at the docs:

https://www.postgresql.org/docs/current/functions-formatting.html#FUNCTIONS-FORMATTING-DATETIME-TABLE

And it says US stands for microsecond. I still don't understand what the remaining "STZ" means?


Solution

  • The number of S chars in the formatting have to do with the possible number of placeholders that the timestamp format can accept. These are all valid values:

    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.832244', 'YYYY-MM-DD"T"HH24:MI:SS.USTZ');
             to_timestamp          
    -------------------------------
     2023-08-09 23:39:18.832244+00
    (1 row)
    
    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.832244', 'YYYY-MM-DD"T"HH24:MI:SS.USSSTZ');
             to_timestamp          
    -------------------------------
     2023-08-09 23:39:18.832244+00
    (1 row)
    
    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.832244', 'YYYY-MM-DD"T"HH24:MI:SS.USSSSTZ');
             to_timestamp          
    -------------------------------
     2023-08-09 23:39:18.832244+00
    (1 row)
    
    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.832244', 'YYYY-MM-DD"T"HH24:MI:SS.USSSSSTZ');
             to_timestamp          
    -------------------------------
     2023-08-09 23:39:18.832244+00
    

    If you do not have enough numbers after the decimal, it will complain:

    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.83', 'YYYY-MM-DD"T"HH24:MI:SS.USSSTZ');
    ERROR:  source string too short for "US" formatting field
    DETAIL:  Field requires 6 characters, but only 2 remain.
    HINT:  If your source string is not fixed-width, try using the "FM" modifier.
    postgres=# 
    

    The TZ indicates that the output should append the configured timezone UTC offset

    To use the FM prefix, just place it before the US section:

    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.83', 'YYYY-MM-DD"T"HH24:MI:SS.FMUSSSTZ');
           to_timestamp        
    ---------------------------
     2023-08-09 23:39:18.83+00
    (1 row)
    
    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.83', 'YYYY-MM-DD"T"HH24:MI:SS.FMUSSSSSTZ');
           to_timestamp        
    ---------------------------
     2023-08-09 23:39:18.83+00
    (1 row)
    
    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.83', 'YYYY-MM-DD"T"HH24:MI:SS.FMUSSSSSSTZ');
           to_timestamp        
    ---------------------------
     2023-08-09 23:39:18.83+00
    (1 row)
    
    postgres=# select TO_TIMESTAMP('2023-08-09T23:39:18.834567', 'YYYY-MM-DD"T"HH24:MI:SS.FMUSSTZ');
             to_timestamp          
    -------------------------------
     2023-08-09 23:39:18.834567+00
    (1 row)