OraStory

Dates, Timestamps and ISO 8601

May 15, 2007 · 6 Comments

If there’s one issue that comes back time and again in Oracle, it’s characterset conversions and timezones. If there are two things that come back time and time again in Oracle..

Someone asked me today how to format a date in Oracle into ISO8601 format.
Specifically the format:


2007-05-15T16:45:00Z

First reaction was what is ISO8601?

Turns out that this format is

Complete date plus hours, minutes, seconds and a decimal fraction of asecond
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)

From an Oracle perspective, I found a couple of resources from the community.

I wondered about the Z – stands for Z time. Essentially, the same timezone as GMT and UTC.

Anyway, supposedly, to get an ISO 8601 format timestamp we need a timestamp with timezone.

So, it seems that, fair enough, we need to go from date -> timestamp -> timestamp with timezone and then we should be able to get the right format.

Date -> Timestamp is easy using TO_TIMESTAMP.

And we can get from Timestamp -> Timestamp with timezone using FROM_TZ.

What about that format we needed?

Well, it’s then that we seem to fall short.
We can’t get the ‘Z’ but seeing as that is just the equivalent of ‘+00:00′ then the latter is perfectly acceptable as is any other offset. The format mask of TZH:TZM does for this.

But the ‘T’ is problematic. Remember:


2007-05-15T16:45:00Z

Unless, not for the first time, I’m mistaken, this isn’t possible without using some horrible string concatenation.
Which is slightly odd because a search of the 10gR2 documentation shows that the XML Developer’s Kit knows something about this format.

Of course, one simple(ton) “solution” from a date would be:


select to_char(sysdate,'YYYY-MM-DD')||'T'||to_char(sysdate,'HH24:MI:SS')||'Z'
from dual

That ‘Z’ is only valid for those Z-time timezones, but hey, I’m alright Jack, I’m in GMT.

Or rather, of course, if you need a timezone, use a timestamp with timezone.

Categories: oracle · timestamps

6 responses so far ↓

  • David Aldridge // May 15, 2007 at 4:31 pm | Reply

    You can embed literal strings in a format picture quite easily . for example …

    To_Char(sysdate,’YYYY-MM-DD”T”HH24:MI:SS”Z”‘)

  • dombrooks // May 15, 2007 at 4:36 pm | Reply

    Something new every day….
    You’d think I’d have come across that before now.
    I feel like a total wally now.
    I should really delete the post to save face :-) but hey… then others wouldn’t come across it.

    In my very thin defence….um, er …. still seems a little odd that XML documentation alludes to it as an official format but not to_char…. that’s the best I can come up with.

    Thanks David.

  • David Aldridge // May 15, 2007 at 9:21 pm | Reply

    It was a surprise to me when I found that out as well. Shhhh!

  • Adderek // December 15, 2008 at 11:06 am | Reply

    You can use the following:
    OPTION A:
    alter session set nls_timestamp_tz_format=’YYYY-MM-DD”T”HH24:MI:SSFFTZR’;
    select current_timestamp from dual;
    CURRENT_TIMESTAMP
    —————————————————————————
    2008-12-15T12:01:55833586+01:00

    OPTION B:
    select to_char(current_timestamp,’YYYY-MM-DD”T”HH24:MI:SS.FFTZR’) from dual;
    TO_CHAR(CURRENT_TIMESTAMP,’YYY
    —————————————————————————
    2008-12-15T12:04:02.652233+01:00

    I prefer the option A – to always set a custom time/date formats. This way I can locate any code where someone (hopefully not me) hardcoded the time/date format.

  • jianping // June 10, 2009 at 9:06 pm | Reply

    I have a slightly different problem: I need to convert 2007-05-15T16:45:00Z back to a date on oracle. What is the data format? I tried
    ‘yyyy-mm-dd”Thh24:mi:ss”Z’. It doesn’t work

  • dombrooks // June 11, 2009 at 9:34 am | Reply

    See comments above – ‘yyyy-mm-dd”T”hh24:mi:ss”Z”‘ – just need to get those quotes & double quotes right

    Cheers,
    Dominic

Leave a Comment