0

I understand that command date -d "20170712" validates and return the date in string form as Wed Jul 12 00:00:00 PDT 2017.

The questions I have are:

  1. How does date know that format in which I gave the string (in this case Year as 2107, Month as Jul and Day as 12)?

  2. Also what if I want to pass "20171307" and want to tell the function that day is 13th and month is Jul?

  3. Is there a way to specify the format of the string I pass to date command?

  • Check out info coreutils 'date invocation' for detailed information about date program. There is section: "Date input formats" – mrc02_kr Jul 13 '17 at 12:32
2

GNU date does its darndest to parse your input, but some formats are inherently ambiguous.

BSD date allows (or practically requires) you to specify an input format with -f and then simply parses your input according to that, throwing an error if the input doesn't match the format.

Expecting or requiring standard tools to support an illogical and haphazard date format like yours seems misdirected, anyway. Standard tools should support standard formats, and I think you'll find in the long run that it makes sense for your scripts and programs to use a computer-friendly fomat internally. For interfacing with humans with odd behaviors, it's easy enough to write a simple shell wrapper function like

Wackydate () {
    local day  # local is a Bashism
    local mon
    local year
    year=${1%????}
    mon=${1#$year??}
    day=${1#$year}
    day=${day%$mon}
    shift
    date -d "$year$mon$day" "$@"
}

The shell's parameter substitutions ${variable#prefix} and ${variable%suffix} return the value of variable with any wildcard match on the expression after # or % removed at the beginning or end, respectively.

  • It would be easier still if you restrict the script to Bash only, as there is a substring operator ${1:0:4} but I wanted this to be portable to POSIX sh if you just drop the local declarations. – tripleee Jul 13 '17 at 12:42
  • For those in linux: Please note that the open and quite small busybox has a date component that also allows the format of -d to be defined with -D. – Arrow Jul 13 '17 at 21:25
  • I don't see how that affects people on Linux particularly, but thanks for the note. – tripleee Jul 14 '17 at 3:24
  • Because of your line: BSD date allows you to specify an input format . If not in BSD, that is, in Linux: busybox date provide an equivalent solution. – Arrow Jul 14 '17 at 3:34
  • Oh, I see. There are many other environments like various legacy big-iron systems which have their own userland utilities so I don't think we can or want to build an exhaustive database of their date behaviors here; and installing Busybox just to get a custom date parser seems a bit excessive if you know the input date format anyway -- it should be just a few lines of shell or Awk or Perl script to massage it into something understood by GNU date. – tripleee Jul 14 '17 at 3:42
1

Please, oh Please, do not do this.

In general, the output of date is controlled by LC_TIME variable

$ LC_TIME=ja_JP.utf8 date; date'
2017年  7月 13日 木曜日 18:00:22 EDT
Thu Jul 13 18:00:22 EDT 2017

And it may be very (and I mean: really very) difficult to parse a date string even if it seems natural and obvious to the reader.

Like the Japan format above.

It could not be used back as input to the date command.

You can edit the locale file to fit your needs and even make it the default.

First, a quote:

 Our units of temporal measurement, from seconds on up to months,
 are so complicated, asymmetrical and disjunctive so as to make
 coherent mental reckoning in time all but impossible.  Indeed, had
 some tyrannical god contrived to enslave our minds to time, to make
 it all but impossible for us to escape subjection to sodden
 routines and unpleasant surprises, he could hardly have done better
 than handing down our present system.  It is like a set of
 trapezoidal building blocks, with no vertical or horizontal
 surfaces, like a language in which the simplest thought demands
 ornate constructions, useless particles and lengthy
 circumlocutions.  Unlike the more successful patterns of language
 and science, which enable us to face experience boldly or at least
 level-headedly, our system of temporal calculation silently and
 persistently encourages our terror of time.

 ... It is as though architects had to measure length in feet, width
 in meters and height in ells; as though basic instruction manuals
 demanded a knowledge of five different languages.  It is no wonder
 then that we often look into our own immediate past or future, last
 Tuesday or a week from Sunday, with feelings of helpless confusion.
 ...

—Robert Grudin, ‘Time and the Art of Living’.

Answers:

  1. Because it mostly conforms to the ISO-8601 date format.
    Which could be printed as this:

    $ date -Id -d 20170713 
    
  2. Yes, you can use such an awkward format (with busybox date or BSD date):

    $ busybox date -D '%Y%d%m' -d "20171307"
    Thu Jul 13 00:00:00 EDT 2017
    

    And even print it in the same format:

    $ busybox date -D '%Y%d%m' -d "20171307" +'%Y%d%m'
    20171307
    
  3. Yes, you can provide a format, and above in 2 is an example.

  • Nice quote. Almost reads the same with "... It is as though architects had to measure length, width, and height in inches, feet, and yards." – tripleee Jul 14 '17 at 3:47
  • date -D command doesn't work. Any suggestion? – AlluSingh Jul 25 '17 at 21:41
  • @AlluSingh Have you installed busybox ? The normal linux date does not have a -D option. – Arrow Jul 25 '17 at 22:39
0

Actually, it all depends on the version of date you are using.

GNU date expects the input date to be yy[y]*mmdd as in 20170713 (13th of July 2017) or 1000901123 (23rd November 100090, yes, the year is faaaar in the future ;-)). It prints dates reliably up until 10 dixits, not sure what it does for years beyond that ... year as 2140000000 works, year 2150000000 does not work on my system.

You can also use human expressions such as date -d 'yesterday', again, not portable.

Use sed to reorganize your date to yyyymmdd.

  • 1
    Shouldn't that be yy[yy]mmdd? – roaima Jul 13 '17 at 12:10
  • 1
    Yeah, sort of, because it accepts two digit years, but it accepts years up to a certain amount of digits ... – thecarpy Jul 13 '17 at 12:24
  • Seeing your updated question I think I withdraw my comment. That far into the future is plainly ridiculous ("we can do this even though it doesn't make sense..") !! – roaima Jul 13 '17 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.