Strftime for Odin

strftime for Odin

Supports a combination of C and Python format specifiers. Plus a few extra added.

Feedback welcome. Feature requests and bug reports strongly encouraged.

strftime overloads 4 procedures, allowing for different input types:

  • strftime_region - preferred - gets local time of region
  • strftime_datetime - preferred - formats whatever time and region is in the DateTime parameter. Useful for past, present, or future time.
  • strftime_local - Allocates and deallocates region on each call. Prefer strftime_region so that you can only allocate your region once and continue getting time.
  • strftime_time - formats time.Time - region information not applicable

Currently only supports Gregorian Calendar. I’m open to adding region specific alternative formatting (i.e. 平成23年 which is year Heisei 23 for Japan) but would need help from others more versed in those regions.

cd $(odin root)shared
git clone https://github.com/OnlyXuul/strftime.git

Import with

import sft "shared:strftime"

Examples

cd $(odin root)shared/strftime/examples
odin run .

Format Specifiers

** Special **
- %%  Escapes %
- %c  Date and time representation     Sun Mar 08 14:30:00 2026
- %D  Date representation              equivalent to "%m/%d/%y"
- %F  Date representation              equivalent to "%Y-%m-%d"
- %R  Time representation              equivalent to "%H:%M"
- %s  RFC3339 Timestamp microseconds   equivalent to %FT%T.%f%-z - offset replaced with Z if not applicable
- %-s RFC3339 Timestamp milliseconds   equivalent to %FT%T.%-f%-z - offset replaced with Z if not applicable
- %T  Time representation              equivalent to "%H:%M:%S"

** Year **
- %C  2 digit century                   00-99
- %y  Year no century zero padded       00-99
- %-y Year no century not zero padded   0-99
- %Y  Year with century                 2026

** Month **
- %b  Abbreviated month                 Jan
- %B  Full month name                   January
- %m  Month zero padded                 01-12
- %-m Month not zero padded             1-12

** Week **
- %U  week of the year zero padded      00-53 Sunday is 1st day of week
- %-U week of the year not zero padded  0-53 Sunday is 1st day of week
- %W  week of the year zero padded      00-53 Monday is 1st day of week
- %-W week of the year not zero padded  0-53 Monday is 1st day of week

** Day **
- %a  Abbreviated weekday               Sun
- %A  Full weekday name                 Sunday
- %d  Day of month zero padded          01-31
- %-d Day of month not zero padded      1-31
- %j  day of the year zero padded       000-366
- %-j day of the year not zero padded   0-366
- %u  Weekday as a decimal number       1-7 - Monday = 1
- %w  Weekday as a decimal number       0-6 - Sunday = 0

** Time **
- %H  Hour (24-hour) zero padded        00-23
- %-H Hour (24-hour) not zero padded    0-23
- %I  Hour (12-hour) zero padded        01-12
- %-I Hour (12-hour) not zero padded    1-12
- %M  Minute zero padded                00-59
- %-M Minute not zero padded            0-59
- %p  AM or PM marker                   am, pm
- %-p AM or PM marker                   a.m., p.m.
- %P  AM or PM marker                   AM, PM
- %-P  AM or PM marker                  A.M., P.M.
- %S  Seconds zero padded               00-59
- %-S Seconds not zero padded           0-59
- %f  Microseconds zero padded          000000 - 999999
- %-f Milliseconds zero padded          000 - 999

** Zone **
- %z  UTC offset                        +HHMM or -HHMM
- %-z UTC offset                        +HH:MM or -HH:MM
- %Z  Time zone                         CST
- %r  Region                            America/Chicago

Referenced from:
- https://en.cppreference.com/w/c/chrono/strftime
- https://strftime.org/

Example Usage:

tz, tz_ok := timezone.region_load("local", context.allocator)
defer timezone.region_destroy(tz, context.allocator)

buf: [64]byte
tm, tm_ok := sft.strftime(buf[:], "%A %B %Y-%m-%d %I:%M:%S %P", tz)
fmt.println(tm)
2 Likes