Can't programmatically format with language.

Created on 21 September 2024, 3 months ago

Problem/Motivation

I need to format both en and fr dates to put in a bilingual email; but doesnt seem to be possible.

I started with a generic $node->$field-view() method to render the field as it shows in a specific view mode ('full'). Even though i load the translation of the node, the render array from view() always comes out as EN.

Next i tried using the formatter service like this:

$formatted_date = $this->dateRangeCompactFormatter->formatDateRange($start, $end, 'date_and_time_range_with_tz', NULL, $langcode);

after injecting the service into my class but the output of this is quite odd:

From 2:00 PM on Jeudi, septembre 19 to 2:00 PM on Vendredi, octobre 4, 2024 (ET)

it is translating the month and day of the week (incorrectly) but it is not using the translated compact format.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Active

Version

2.1

Component

Code

Created by

πŸ‡¨πŸ‡¦Canada liquidcms

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @liquidcms
  • πŸ‡¨πŸ‡¦Canada liquidcms

    And as is always the case, after spending 3 hours trying to get this to work, 2 min after posting this i figure it out:

        if ($langcode == 'fr') {
          $language_manager = \Drupal::service('language_manager');
          $language_manager->setConfigOverrideLanguage($language_manager->getLanguage('fr'));
        }
    
        $formatted_date = $this->dateRangeCompactFormatter->formatDateRange($start, $end, 'date_and_time_range_with_tz', NULL, $langcode);
    
  • πŸ‡ΈπŸ‡ͺSweden erik.erskine

    Thanks for reporting this.

    $formatted_date = $this->dateRangeCompactFormatter->formatDateRange($start, $end, 'date_and_time_range_with_tz', 'America/Toronto', $langcode);
    

    Firstly, what is the value of $langcode at this point?

    Second, please can you paste the contents of daterange_compact.format.date_and_time_range_with_tz.yml?

  • πŸ‡ΈπŸ‡ͺSweden erik.erskine

    $language_manager->setConfigOverrideLanguage($language_manager->getLanguage('fr'));

    You shouldn't need to do this. The low level formatter should set this (and set it back afterwards). There is precedence for this in core, in user_mail(), which does something similar.

    Calling formatDateRange($start, $end, 'date_and_time_range_with_tz', NULL, 'fr') should be enough and do what you expect.

    I think the current MR fixes this.

  • πŸ‡¨πŸ‡¦Canada joseph.olstad

    Testing this and it fixes the language issue however I have a fix for timezone.

  • πŸ‡¨πŸ‡¦Canada joseph.olstad

    Patch from MR

  • πŸ‡¨πŸ‡¦Canada joseph.olstad

    Sorry I don't have any test code to offer atm, but probably pretty easy to cook up.

  • Status changed to Needs work 20 days ago
  • πŸ‡ΈπŸ‡ͺSweden erik.erskine

    Thanks @joseph.olstad, glad to hear the language part is working :)

       public function formatDateRange(string $startDate, string $endDate, string $type = 'medium_date', $timezone = NULL, $langcode = NULL): FormattedDateTimeRange {
    -    $startTimestamp = (new DrupalDateTime($startDate, $timezone))->getTimestamp();
    -    $endTimestamp = (new DrupalDateTime($endDate, $timezone))->getTimestamp();
    +    $startTimestamp = (new DrupalDateTime($startDate))->getTimestamp();
    +    $endTimestamp = (new DrupalDateTime($endDate))->getTimestamp();
         return $this->formatTimestampRange($startTimestamp, $endTimestamp, $type, $timezone, $langcode);
       }
    

    Why was $timezone removed here? It is breaking some tests.

    On reflection, simply having any timezone parameter in formatDate() was wrong. But it is there now, and not easy to remove. So the best we can do is pass it through unchanged.

    I added TimezoneTest to help get to the bottom of this. It calls the formatDate and formatTimestamp with various timezone values. It's failing (but passes if I revert #7). Can we start there and see if a) what that test expects is correct and b) if it covers your particular issue?

  • πŸ‡¨πŸ‡¦Canada joseph.olstad

    @erik.erskine it was 2 months ago now. From two months organic memory banks in my brain I do recall working on this and I recall the timezone getting double shifted before I made that change.

    The timezone needs to be set once not twice.

    With that said, it was 2 months ago.

    However our approach was refactored and instead of using formatters we ended up using views instead to format our dates so we're no longer using the above patch due to our strict requirements of localisation. It had to be 100% localised perfectly to our spec for both our languages and at the time there were some edge cases that we solved using views instead.

Production build 0.71.5 2024