Monday 19 November 2012

Using a strftime style

You should already know the now function, it gives you all information about time. If you were wont to use strftime function from other language, you could use the form-date function that is included in the following script, look a the following examples:

>> form-date now "%A %e%i %B, %Y at %T"
== "Monday 19th November, 2012 at 10:39:33"

>> form-date now "%d-%b-%Y/%H:%M:%S%Z"
== "19-Nov-2012/10:39:53+01:00

Here the source of the script:
REBOL [
    Title: "form-date"
    Author: "Christopher Ross-Gill"
    Date: 26-Apr-2007
    Version: 1.0.1
    File: %form-date.r
    Rights: {Copyright (c) 2007, Christopher Ross-Gill}
    Purpose: {Return formatted date string using strftime style format specifiers}
    Home: http://www.ross-gill.com/QM/
    Comment: {Extracted from the QuarterMaster web framework}
    History: [
        1.0.1 18-Jul-2007 btiffin "Obtained permission to add %c and %s precise seconds"
        1.0.0 26-Apr-2007 btiffin "Obtained permission to prepare script for rebol.org library"
        1.0.0 24-Apr-2007 chrisrg "The original"
    ]
]
form-date: use [get-class interpolate pad pad-zone get-iso-year date-codes] [
;--## SERIES HELPER
;-------------------------------------------------------------------##
    get-class: func [classes [block!] item][
        all [
            classes: find classes item
            classes: find/reverse classes type? pick head classes 1
            first classes
        ]
    ]
;--## STRING HELPERS
;-------------------------------------------------------------------##
    interpolate: func [body [string!] escapes [any-block!] /local out][
        body: out: copy body
        parse/all body [
            any [
                to #"%" body: (
                    body: change/part body reduce any [
                        select/case escapes body/2 body/2
                    ] 2
                ) :body
            ]
        ]
        out
    ]
    pad: func [text length [integer!] /with padding [char!]][
        padding: any [padding #"0"]
        text: form text
        skip tail insert/dup text padding length negate length
    ]
;--## DATE HELPERS
;-------------------------------------------------------------------##
    pad-zone: func [time /flat][
        rejoin [
            pick "-+" time/hour < 0
            pad abs time/hour 2
            either flat [""][#":"]
            pad time/minute 2
        ]
    ]
    pad-precise: func [time /local tstr tsec tpre] [
        tstr: form time
        tsec: copy/part tstr find tstr "."
        tpre: find tstr "."
        rejoin [pad tsec 2 head change/part copy ".000000" tpre length? tpre]
  ]
    get-iso-year: func [year [integer!] /local d1 d2][
        d1: to-date join "4-1-" year
        d2: to-date join "28-12-" year
        return reduce [d1 + 1 - d1/weekday d2 + 7 - d2/weekday]
    ]
    to-iso-week: func [date [date!] /local out d1 d2][
        out: 0x0
        set [d1 d2] get-iso-year out/y: date/year
        case [
            date < d1 [d1: first get-iso-year out/y: date/year - 1]
            date > d2 [d1: first get-iso-year out/y: date/year + 1]
        ]
        out/x: date + 8 - date/weekday - d1 / 7
        out
    ]
    date-codes: [
        #"a" [copy/part pick system/locale/days date/weekday 3]
        #"A" [pick system/locale/days date/weekday]
        #"b" [copy/part pick system/locale/months date/month 3]
        #"B" [pick system/locale/months date/month]
        #"c" [pad date/day 2 "-"
              copy/part pick system/locale/months date/month 3 "-"
              pad date/year 4 "/"
              pad time/hour 2 ":"
              pad time/minute 2 ":"
              pad-precise time/second
              pad-zone zone]
        #"C" [to-integer date/year / 100]
        #"d" [pad date/day 2]
        #"D" [date/year #"/" pad date/month 2 #"/" pad date/day 2]
        #"e" [date/day]
        #"g" [pad (second to-iso-week date) // 100 2]
        #"G" [second to-iso-week date]
        #"H" [pad time/hour 2]
        #"i" [any [get-class ["st" 1 21 31 "nd" 2 22 "rd" 3 23] date/day "th"]]
        #"I" [pad time/hour + 11 // 12 + 1 2]
        #"j" [pad date/julian 3]
        #"J" [date/julian]
        #"m" [pad date/month 2]
        #"M" [pad time/minute 2]
        #"p" [pick ["AM" "PM"] time/hour < 12]
        #"s" [pad-precise time/second]
        #"S" [pad round time/second 2]
        #"t" [#"^-"]
        #"T" [pad time/hour 2 #":" pad time/minute 2 #":" pad round time/second 2]
        #"u" [date/weekday]
        #"U" [pad to-integer date/julian + 6 - (date/weekday // 7) / 7 2]
        #"V" [pad first to-iso-week date 2]
        #"w" [date/weekday // 7]
        #"W" [pad to-integer date/julian + 7 - date/weekday / 7 2]
        #"y" [pad date/year // 100 2]
        #"Y" [date/year]
        #"z" [pad-zone/flat zone]
        #"Z" [pad-zone zone]
        #"%" ["%"]
    ]
    func [
        "Renders a date to a given format (largely compatible with strftime)"
        date [date!] format [any-string!]
        /gmt "Align time with GMT"
        /local time zone nyd
    ][
        bind date-codes 'date
        all [
            gmt date/time date/zone
            date/time: date/time - date/zone
            date/zone: none
        ]
        time: any [date/time 0:00]
        zone: any [date/zone 0:00]
        interpolate format date-codes
    ]
]
The function support the following special chars:

  • %a   The abbreviated weekday name according to the current locale.
  • %A  The full weekday name according to the current locale.
  • %b   The abbreviated month name according to the current locale.
  • %B  The full month name according to the current locale.
  • %c   The preferred date and time representation for the current locale.
  • %C  The century number (year/100) as a 2-digit integer. (SU)
  • %d   The day of the month as a decimal number (range 01 to 31).
  • %D  Equivalent to %m/%d/%y. (Yecch-for Americans only. Americans should note that in other countries %d/%m/%y is rather common. This means that in international context this format is ambiguous and should not be used.) (SU)
  • %G  The ISO 8601 week-based year (see NOTES) with century as a decimal number. The 4-digit year corresponding to the ISO week number (see %V). This has the same format and value as %Y, except that if the ISO week number belongs to the previous or next year, that year is used instead. (TZ)
  • %g   Like %G, but without century, that is, with a 2-digit year (00-99). (TZ)
  • %H  The hour as a decimal number using a 24-hour clock (range 00 to 23).
  • %I   The hour as a decimal number using a 12-hour clock (range 01 to 12).
  • %i   The word to append at the number (st, nd, rd, th)
  • %j   The day of the year as a decimal number (range 001 to 366). 
  • %J  The day of the year as a decimal number (range 001 to 366).
  • %m The month as a decimal number (range 01 to 12).
  • %M The minute as a decimal number (range 00 to 59).
  • %p   Either "AM" or "PM" according to the given time value, or the corresponding strings for the current locale. Noon is treated as "PM" and midnight as "AM".
  • %s   The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). (TZ)
  • %S   The second as a decimal number (range 00 to 60). (The range is up to 60 to allow for occasional leap seconds.)
  • %t   A tab character. (SU)
  • %T  The time in 24-hour notation (%H:%M:%S). (SU)
  • %u   The day of the week as a decimal, range 1 to 7, Monday being 1. See also %w. (SU)
  • %U   The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01. See also %V and %W.
  • %V   The ISO 8601 week number (see NOTES) of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the new year. See also %U and %W. (SU)
  • %w   The day of the week as a decimal, range 0 to 6, Sunday being 0. See also %u.
  • %W  The week number of the current year as a decimal number, range 00 to 53, starting with the first Monday as the first day of week 01.
  • %y  The year as a decimal number without a century (range 00 to 99).
  • %Y  The year as a decimal number including the century.
  • %z   The +hhmm or -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU)
  • %Z   The timezone or name or abbreviation.
  • %%   A literal '%' character.

No comments:

Post a Comment