date command in busybox not accepting formatted input date

16,451

Solution 1

busybox date only accepts very specific time formats, not arbitrary ones.

$ busybox date --help
[...]
    [-s,--set] TIME Set time to TIME
[...]
Recognized TIME formats:
    hh:mm[:ss]
    [YYYY.]MM.DD-hh:mm[:ss]
    YYYY-MM-DD hh:mm[:ss]
    [[[[[YY]YY]MM]DD]hh]mm[.ss]
    'date TIME' form accepts MMDDhhmm[[YY]YY][.ss] instead

So you'll just have to write it like, date -s 2010.02.17-19:14:32 (or whichever format you prefer).

Solution 2

You can get busybox date to do the conversion of formats for you, using -D to specify the input format, and the usual +... for the output format, with -d providing the reference date and time. For example,

r='Tue, 15 Jan 2019 09:16:53 GMT'
d=$(busybox date -d "$r" -D "%a, %d %b %Y %T %Z" +'%Y-%m-%d %H:%M:%S')
# d becomes 2019-01-15 09:01:53
busybox date -s "$d"

Solution 3

Some versions of busybox date accept custom format as input using -D option. However, after spending a good hour on this, this option does not support timezone format %Z.

List of all supported format for C strftime: C library function - strftime()

Note: one needs to remove the + from the start of the output format to use as input format with -D. E.g. "+%FT%T%z" becomes -D "%FT%T%z".

Generally working conversion

## Date context for other commands
# date -Iminutes
2021-04-01T13:30+0000

# date -u -D '%b %e %Y' -d "Apr 1 2021"
Thu Apr  1 00:00:00 UTC 2021

# date -u -d "2021 04xx25" -D '%Y %mxx%d'
Sun Apr 25 00:00:00 UTC 2021

# date -u -d "5 12:35:58" -D "%e %H:%M:%S"
Mon Apr  5 12:35:58 UTC 2021

With the timezone

## Format returned by `openssl x509 -enddate`
# date -u +"%b %e %H:%M:%S %Y %Z"
Apr  1 13:33:58 2021 UTC

# # date -u -D "%b %e %H:%M:%S %Y %Z" -d "Apr  1 13:33:58 2021 UTC"
date: invalid date 'Apr  1 13:33:58 2021 UTC'


## removing the %Z timezone from the input:
# date -u -D "%b %e %H:%M:%S %Y" -d "Apr  1 13:33:58 2021 UTC"
Thu Apr  1 13:33:58 UTC 2021

## yet providing %Z in output format works well
# date -u -D "%b %e %H:%M:%S %Y" -d "Apr  1 13:33:58 2021 UTC" +"%F %T %Z"
2021-04-01 13:33:58 UTC

Busybox version and date help

Container running alpine linux busybox v1.32.1

# uname -a
Linux f4d750b1edf8 4.19.121-linuxkit #1 SMP Thu Jan 21 15:36:34 UTC 2021 x86_64 Linux
# busybox date --help
BusyBox v1.32.1 () multi-call binary.

Usage: date [OPTIONS] [+FMT] [TIME]

Display time (using +FMT), or set time

        [-s,--set] TIME Set time to TIME
        -u,--utc        Work in UTC (don't convert to local time)
        -R,--rfc-2822   Output RFC-2822 compliant date string
        -I[SPEC]        Output ISO-8601 compliant date string
                        SPEC='date' (default) for date only,
                        'hours', 'minutes', or 'seconds' for date and
                        time to the indicated precision
        -r,--reference FILE     Display last modification time of FILE
        -d,--date TIME  Display TIME, not 'now'
        -D FMT          Use FMT (strptime format) for -d TIME conversion

Recognized TIME formats:
        hh:mm[:ss]
        [YYYY.]MM.DD-hh:mm[:ss]
        YYYY-MM-DD hh:mm[:ss]
        [[[[[YY]YY]MM]DD]hh]mm[.ss]
        'date TIME' form accepts MMDDhhmm[[YY]YY][.ss] instead
Share:
16,451
tzippy
Author by

tzippy

Updated on September 18, 2022

Comments

  • tzippy
    tzippy almost 2 years

    I want to set the date using busybox's date command (BusyBox v1.21.0). My custom date to which I want to set the computer is of this form:

    Tue, 15 Jan 2019 10:46:13 GMT
    

    What my date command is capable of is to print out the date in the same format using this string:

    date +"%a, %d %b %Y %T %Z"

    It returns the date in the exact same format as above. But It would not accept this when I use the -s option to set the date.

    This fails for example:

    date -u +"%a, %d %b %Y %T %Z" -s "Wed, 17 Feb 2010 19:14:32 UTC"
    date: invalid date 'Wed, 17 Feb 2010 19:14:32 UTC'
    

    I know busybox commands are reduced in function, but I imagined that when it can handle the format string to print the current date in the desired form, then it should also be able to use it to interpret an input string.

  • tzippy
    tzippy over 5 years
    thanks! So there's no way of getting my date's month (for example `'Jan') into the date command?
  • frostschutz
    frostschutz over 5 years
    not unless you provide your own script that translates your arbitrary date format into one understood by busybox date. date can output most formats fine, just doesn't accept them as input when setting date.
  • tzippy
    tzippy over 5 years
    Got it. That's what I'm doing now with a script that returns the month's number when given the 3 digit string.
  • frostschutz
    frostschutz over 5 years
    Amazing! (and now I have to find out why this doesn't work with ArchLinux busybox)
  • frostschutz
    frostschutz over 5 years
    OK, for whatever reason, ArchLinux busybox does not accept %Z in date -D. Works fine otherwise.
  • Pedro Witzel
    Pedro Witzel over 4 years
    Isn't something wrong with 2019-16-15 ? :) Even though the output d was correct for me, busybox still complains about the date format, saying it's invalid
  • meuh
    meuh over 4 years
    @PedroWitzel you are right, thanks. Sorry about the typing error. Check the output of busybox date -h to see if it has YYYY-MM-DD hh:mm[:ss] in one of the recognised time formats. If not, try one of the other listed formats by changing the +... part of the d=... command to match the desired input, for example, +'%Y%m%d%H%M.%S'
  • roaima
    roaima over 2 years
    That looks like it would have simply printed your date string. That's what it does here, 2021-12-20 12:37:00
  • ShaileshKumarMPatel
    ShaileshKumarMPatel over 2 years
    No. In fact, It did changed date.