5

My web-scraping scripts have long enjoyed using date -d to read in human-formatted time and date stamps like "March 11, 1999" and convert to any other format I need via the -s parameter.

How might I get it to understand dates printed in other locales like 27 Kwi, 13:54 in Polish? I can artifically prepend/append the year (2012) if needed.

I checked my env and tried the following, but no luck:

LOCALE=PL date -d "30 Kwi, 17:02"
LANGUAGE=pl_PL:pl date -d "30 Kwi, 17:02"
LC_CTYPE=pl_PL:pl date -d "30 Kwi, 17:02"
LANG=pl_PL:pl date -d "30 Kwi, 17:02"
LC_COLLATE=pl_PL:pl date -d "30 Kwi, 17:02"
LC_MESSAGES=pl_PL:pl date -d "30 Kwi, 17:02"
date: invalid date `30 Kwi, 17:02'

In my system as installed,

LANGUAGE=en_US:en
LC_CTYPE=en_US.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_COLLATE=en_US.UTF-8
1
  • Reminder: I don't get to control the input format. But I may prepend or append eg. the current year before sending off the whole string to a universal, magic parser.
    – Marcos
    May 9, 2012 at 11:42

1 Answer 1

6

Unfortunately you can't.

GNU coreutils - General date syntax

In the current implementation, only English is supported for words and abbreviations like ‘AM’, ‘DST’, ‘EST’, ‘first’, ‘January’, ‘Sunday’, ‘tomorrow’, and ‘year’.


Since I can't find a way to do it using date or any other tool like it, here's how you could do it in Python.

import time
import locale

locale.setlocale(locale.LC_TIME, 'pl_PL')

logtime = time.strptime('30 Kwi 2012, 17:02', '%d %b %Y, %H:%M')

You could use strptime in any language that provides it, e.g. Python, Perl, C, Ruby, etc.


If you really have to use only bash, try this:

# create an associative array, e.g. month[kwi] = 4
# requires bash >= 4
declare -A month
for m in {1..12}; do
  # any year should do since we only print the month
  mmm=$(LC_TIME=pl_PL.UTF-8 date -d "2000-$m-1" "+%b")
  month[$mmm]=$m
done

# test that the associative array works, should print 4
echo ${month[kwi]}

# given arguments <day> <month> <year>, <hour>:<minute>
# where month is a three-letter abbreviated Polish month name
# print it using the system's default date format
pl_date() {
  local d=$1
  local mmm=$2
  local yyyy=$3
  local hhmm=$4

  local m=${month[$mmm]}
  date -d "$yyyy-$m-$d $hhmm"
}

# use without quotes
pl_date 30 kwi 2012 17:02

Notes:

Even in English, the year is required and the comma is not allowed:

$ date -d "30 Apr, 17:02"
date: invalid date `30 Apr, 17:02'

$ date -d "30 Apr 2012 17:02"
Mon Apr 30 17:02:00 PDT 2012

Only LANGUAGE supports a list like pl_PL:pl, the other variables require a single name, e.g. pl_PL or pl_PL.UTF-8.

3
  • Very good demonstration of bash techniques. Besides that I mostly use Ruby for programs if not awk for one-liners, both have strptime or similar--where you still have to specify the field format manually.
    – Marcos
    May 1, 2012 at 15:19
  • 1
    GNU awk has strftime but no strptime as far as I can tell.
    – Mikel
    May 1, 2012 at 15:32
  • And yes, Ruby is another good choice, but if you need to use Ruby, Python, or Perl, it might be better to write the whole script in that language.
    – Mikel
    May 1, 2012 at 15:34

You must log in to answer this question.

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