lestrrat-go / strftime

Fast strftime for Go
MIT License
117 stars 22 forks source link

Hyphenated formats for non-zero padded numbers #13

Open Evidlo opened 4 years ago

Evidlo commented 4 years ago

Some strftime implementations support non-zero padded numbers.

For example, in Python

>>> from datetime import datetime
>>> datetime.strftime(datetime.now(), '%-d')
'1'

This is documented in glibc's strftime.

Windows has its own set of codes which use # instead of -: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strftime-wcsftime-strftime-l-wcsftime-l?redirectedfrom=MSDN&view=vs-2019

Another reference: https://strftime.org/#platforms

lestrrat commented 4 years ago

Implementing this is probably trivial, but if you could provide us with test cases in Go test format, that would be a great start.

lestrrat commented 4 years ago

as a personal reminder: from the glibc doc

Glibc provides some extensions for conversion specifications. (These extensions are not specified in POSIX.1-2001, but a few other systems provide similar features.) Between the '%' character and the conversion specifier character, an optional flag and field width may be specified. (These precede the E or O modifiers, if present.)

This is an extension, so the implementation would fall into the extensions mechanism like %L

harrylepotter commented 3 years ago

@lestrrat use case here... Getting the front page of the new york times: https://cdn.newseum.org/dfp/pdf%-d/NY_NYT.pdf

we want numbers below 10 to simply return without padding: eg: https://cdn.newseum.org/dfp/pdf1/NY_NYT.pdf

certainly seems to be supported by other implementations

Evidlo commented 3 years ago

@lestrrat I generated some test cases with this snippet

#include <stdio.h>
#include <time.h>

int main() {
    struct tm {
        1,     /* seconds,  range 0 to 59          */
        1,     /* minutes, range 0 to 59           */
        1,     /* hours, range 0 to 23             */
        1,     /* day of the month, range 1 to 31  */
        1,     /* month, range 0 to 11             */
        -1000, /* The number of years since 1900   */
        1,     /* day of the week, range 0 to 6    */
        1,     /* day in the year, range 0 to 365  */
        0,     /* daylight saving time             */
    };

    char buffer[200];

    strftime(buffer, 200, "%d|%e|%H|%I|%j|%k|%l|%M|%m|%S|%U|%V|%W|%y|%z", &t);
    printf(buffer);
    printf("\n");
    strftime(buffer, 200, "%-d|%-e|%-H|%-I|%-j|%-k|%-l|%-M|%-m|%-S|%-U|%-V|%-W|%-y|%-z", &t);
    printf(buffer);
    printf("\n");
}

Which gives the output

01| 1|01|01|002| 1| 1|01|02|01|01|01|01|00|+0000
1|1|1|1|2|1|1|1|2|1|1|1|1|0|+0

The format codes excluded from the snippet don't change when including a hyphen.