Month name shown in English on item page, in spite of language settings

I use the NumericDataTypes module to record dates as, well, dates (timestamps).

As the module has not yet been updated with translations from Transifex, I have manually uploaded to the language subfolder the translations files for my language (Italian), and indeed now I see correctly the month names in Italian in the backend. So far, so good.

However, in the front-end (i.e. when visiting the website) I still see month names in English. I have Italian set as the default language of the installation, and I have explicitly set it as language for the specific website. I have tried changing the LC_ settings on the server, but this also does not seem to have any impact.

Ultimately, I don’t see in the translation files available on Transifex the strings that should appear in the frontend, just e.g. in the format "04 — April" used for the backend.

Any suggestions of where do I change this setting? Or hints about where I should try to fix it (in the module, in the theme, elsewhere in omeka, on the server itself?).

thanks!

There is no setting to fix this, nor is there an easy generalizable solution. Internationalizing date strings is tricky. Currently the module renders the date string according to a hard-coded format, which, as you see, favors the American format (month day, year). To fix this for Italian (or any other language, really), you’ll need to edit some classes to reformat and translate the date/time strings, these classes specifically:

  • NumericDataTypes\DataType\Timestamp::render()
  • NumericDataTypes\DataTypeAbstractDateTimeDataType::getDateTimeFromValue()

From there it’s up to your technical knowhow and your server’s capabilities. Perhaps you can use PHP’s IntlDateFormatter, or a combination of setlocale() and strftime(), or maybe you could just localize the render formats in getDateTimeFromValue() and do a find and replace for the month translations.

As you see, date string internationalization is tricky, and certainly hard to generalize, at least in a PHP environment. Sorry there’s no easy fix.

Painful, but helpful, thanks!

I’m running Omeka on its own docker image, so I should probably make sure I have all set up there first, adjust the order of month and day in the files you pointed out, and take it from there with php.

I’ll report back when I figure this out!

Alright, here is how I dealt with this.

In modules/NumericDataTypes/src/DataType/AbstractDateTimeDataType.php I changed the order of day and month, from e.g. the American “December 17, 2019” to “17 December 2019”. This was rather straightforward, and just meant inverting the order of j and F and removing commas immediatel after // Set the render format in the file. This is how it looks for me now:

// Set the render format.

        if (isset($dateTime['month']) && isset($dateTime['day']) && isset($dateTime['hour']) && isset($dateTime['minute']) && isset($dateTime['second']) && isset($dateTime['offset_value'])) {
            $format = 'j F Y H:i:s P';
        } elseif (isset($dateTime['month']) && isset($dateTime['day']) && isset($dateTime['hour']) && isset($dateTime['minute']) && isset($dateTime['offset_value'])) {
            $format = 'j F Y H:i P';
        } elseif (isset($dateTime['month']) && isset($dateTime['day']) && isset($dateTime['hour']) && isset($dateTime['offset_value'])) {
            $format = 'j F Y H P';
        } elseif (isset($dateTime['month']) && isset($dateTime['day']) && isset($dateTime['hour']) && isset($dateTime['minute']) && isset($dateTime['second'])) {
            $format = 'j F Y H:i:s';
        } elseif (isset($dateTime['month']) && isset($dateTime['day']) && isset($dateTime['hour']) && isset($dateTime['minute'])) {
            $format = 'j F Y H:i';
        } elseif (isset($dateTime['month']) && isset($dateTime['day']) && isset($dateTime['hour'])) {
            $format = 'j F Y H';
        } elseif (isset($dateTime['month']) && isset($dateTime['day'])) {
            $format = 'j F Y';
        } elseif (isset($dateTime['month'])) {
            $format = 'F Y';
        } else {
            $format = 'Y';
        }

Now the word order was right, but everything was still in English. Unfortunately, I was unable to get anything done with setlocale(), so I want with the find&replace option.

To fix this, I edited the file modules/NumericDataTypes/src/DataType/Timestamp.php , immediately after the comment // Render the datetime, allowing for reduced accuracy. My file looks as follows:

        // Render the datetime, allowing for reduced accuracy.
        $date = $this->getDateTimeFromValue($value->value());

// start of custom fix for Italian translation of months
$renderedDate = $date['date']->format($date['format_render']);
        $monthsEnglish = array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
        $monthsItalian   = array("gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre");
        $renderedDate = str_replace($monthsEnglish, $monthsItalian, $renderedDate);

        return $renderedDate;
// end of custom fix for Italian translation of months

Everything works fine, but largely due to my limited php skills this took longer than it could have. Hope it helps others who find themselves in the same situation.

All things considered, I agree that “Internationalizing date strings is tricky”, and yet, it would be so nice to be able to get this right without all this custom editing.

I understand that doing this via locale, which should be the “right” way to go about it, is likely problematic due to server issues, but ultimately, even hardcoding month names in a couple of dozen languages and inheriting language settings from the site settings should be doable without the need to create custom settings exposed to the user. Ultimately, NumericDataTypes is really a must-have module for Omeka S, and having dates appear in a foreign language on every page is actually a very significant issue for non-English speakers.