Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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
share|improve this question
    
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 '12 at 11:42
add comment

1 Answer

up vote 5 down vote accepted

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.

share|improve this answer
    
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 '12 at 15:19
1  
GNU awk has strftime but no strptime as far as I can tell. –  Mikel May 1 '12 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 '12 at 15:34
1  
Added a link to the Ruby strptime function for completeness. –  Mikel May 1 '12 at 15:37
    
Actually, the eval stuff was not necessary. Changed it to be simpler. –  Mikel May 1 '12 at 20:57
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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