35

I built Alpine Linux in a Docker container with the following Dockerfile:

FROM alpine:3.2
RUN apk add --update jq curl && rm -rf /var/cache/apk/*

the build run successfully:

$ docker build -t collector .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM alpine:3.2
3.2: Pulling from alpine
8697b6cc1f48: Already exists 
alpine:3.2: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:eb84cc74347e4d7c484d566dec8a5eef82bab1b78308b92cda559bcff29c27cc
Status: Downloaded newer image for alpine:3.2
 ---> 8697b6cc1f48
Step 1 : RUN apk add --update jq curl && rm -rf /var/cache/apk/*
 ---> Running in 888571296e79
fetch http://dl-4.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz
(1/11) Installing run-parts (4.4-r0)
(2/11) Installing openssl (1.0.2a-r1)
(3/11) Installing lua5.2-libs (5.2.4-r0)
(4/11) Installing lua5.2 (5.2.4-r0)
(5/11) Installing ncurses-terminfo-base (5.9-r3)
(6/11) Installing ncurses-widec-libs (5.9-r3)
(7/11) Installing lua5.2-posix (33.3.1-r2)
(8/11) Installing ca-certificates (20141019-r2)
(9/11) Installing libssh2 (1.5.0-r0)
(10/11) Installing curl (7.42.1-r0)
(11/11) Installing jq (1.4-r0)
Executing busybox-1.23.2-r0.trigger
Executing ca-certificates-20141019-r2.trigger
OK: 9 MiB in 26 packages
 ---> 7625779b773d
Removing intermediate container 888571296e79
Successfully built 7625779b773d

anyway when I run date -d it fails:

$ docker run -i -t collector sh
/ # date -d yesterday
date: invalid date 'yesterday'
/ # date -d now
date: invalid date 'now'
/ # date -d next-month
date: invalid date 'next-month'

while the rest of the options seem running ok:

/ # date 
Sat May 30 18:57:24 UTC 2015
/ # date +"%A"
Saturday
/ # date +"%Y-%m-%dT%H:%M:%SZ"
2015-05-30T19:00:38Z
1
  • Don't count on the date command supporting reference dates with "now", "yesterday", etc., or other non-standard extensions.
    – Janis
    Commented May 30, 2015 at 21:09

5 Answers 5

64

BusyBox/Alpine version of date doesn't support -d options, even if the help is exatly the same in the Ubuntu version as well as in others more fat distros.

Also the "containerization" doesn't miss anything here.

To work with -d options you just need to add coreutils package:

$ cat Dockerfile.alpine-coreutils
FROM alpine:3.2
RUN apk add --update coreutils && rm -rf /var/cache/apk/*


$ docker build -t alpine-coreutils - <  Dockerfile.alpine-coreutils
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM alpine:3.2
3.2: Pulling from alpine
8697b6cc1f48: Already exists 
alpine:3.2: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:eb84cc74347e4d7c484d566dec8a5eef82bab1b78308b92cda559bcff29c27cc
Status: Downloaded newer image for alpine:3.2
 ---> 8697b6cc1f48
Step 1 : RUN apk add --update coreutils && rm -rf /var/cache/apk/*
 ---> Running in 694fa5cb271c
fetch http://dl-4.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz
(1/3) Installing libattr (2.4.47-r3)
(2/3) Installing libacl (2.2.52-r2)
(3/3) Installing coreutils (8.23-r0)
Executing busybox-1.23.2-r0.trigger
OK: 12 MiB in 18 packages
 ---> a7d9116a00ee
Removing intermediate container 694fa5cb271c
Successfully built a7d9116a00ee


$ docker run -i -t alpine-coreutils sh
/ # date -d last-week
Sun May 24 09:19:34 UTC 2015
/ # date -d yesterday 
Sat May 30 09:19:46 UTC 2015
/ # date 
Sun May 31 09:19:50 UTC 2015

The image size will double but is till 11.47 MB, more than an order of siZe less, compared to Debian standard :

$ docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
alpine-coreutils           latest              a7d9116a00ee        2 minutes ago       11.47 MB
alpine                     3.2                 8697b6cc1f48        2 days ago          5.242 MB
debian                     latest              df2a0347c9d0        11 days ago         125.2 MB

Thanks to Andy Shinn: https://github.com/gliderlabs/docker-alpine/issues/40#issuecomment-107122371

And to Christopher Horrell: https://github.com/docker-library/official-images/issues/771#issuecomment-107101595

1
  • This is only an option if you are creating the Docker image yourself. If you are using a built container to use with a date range this is not a solution. The answer explaining that the format is like zsh strftime and not GNU is better.
    – tbeauvais
    Commented Apr 19, 2021 at 9:02
6

busybox date supports a -D option which (like zsh's strftime but contrary to GNU date) gives you an interface to strptime() where you can parse dates (though not relative dates) in any format (ast-open date and ksh93's printf also have ways to customize the input format).

Where busybox is built against a C library implementation whose strptime() and strftime() support the non-standard %s flag, you could do:

date -D %s -d "$(($(date +%s) - 86400))"

In the musl C library which alpine Linux uses however, strftime() does support %s but strptime() doesn't. It's OK though as busybox date, like GNU date supports the @epochtime date specification, so you can do:

date -d "@$(($(date +%s) - 86400))"

Which will give you the date 86400 seconds ago, without the ambiguity of GNU date's yesterday (is it 86400 ago, or is it yesterday at the same time of the day? What if there was no such time of the day yesterday because the clock changed for DST?).

That syntax should also work with GNU date.

With ast-open's date (or ksh93's printf '%(%c)T'), you'd use:

date -d "#$(($(date +%s) - 86400))"

instead.

Note that if you want to report UTC (Zulu) time, you should use TZ=UTC0 date or date -u as otherwise, you'd get the time in the system's/user's timezone.

1
  • Very well, and it is even compatible with GNU date! Wonderful! Commented Jul 27, 2021 at 16:31
4

EDIT: I tested this command on Alpine:3.2

To substract 24 hours from current day, you can run:

# date
Fri Jul 10 13:08:56 UTC 2020

# date -d "-24:00:00"
Thu Jul  9 00:00:00 UTC 2020

You can also add to current date by using:

# date -d "+24:00:00"
Sat Jul 11 00:00:00 UTC 2020

Hope this helps

2
  • 1
    Welcome to the site, and thank you for your contribution. Please note that the problem seems to be related to the BusyBox implementation of date since the OP is running the command inside a Docker container with Alpine linux. Can you confirm that the approach works also under these conditions?
    – AdminBee
    Commented Jul 10, 2020 at 13:40
  • Please note this works for dates, but not for time. You'd expect that date -d "+01:00:00" returns time 1h ahead, but it actually gives today 1am. Commented Jul 27, 2021 at 16:30
1

I suppose the date you can run in that container is not GNU coreutils date which is commonly available on Linux hosts, but one of the Busybox applets. Try to get help messages from both of them.

# date --help
BusyBox v1.22.1 (Ubuntu 1:1.22.0-9ubuntu1) 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 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

BusyBox offers many applets for Posix standard commands with single crunched binary, but most of them has very restricted functions in exchange for its saved size (compare outputs of find --help or tar --help in both environments for example). It frequently happens that a script which runs successfully in the development/host environment doesn't work at all in the container/target environment with BusyBox.

0

If you need timezone conversion, coreutils is not enough.
You'll need tzdata as well.

Commands like TZ='America/Los_Angeles' date wouldn't work, TZ var is simply ignored.
After apk add tzdata timezone conversion starts working properly.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .