Avatar billede Mik2000 Professor
09. februar 2020 - 22:45 Der er 7 kommentarer og
5 løsninger

IntlDateFormatter - month year

Hej

Jeg har leget lidt med intldateformatter https://www.php.net/manual/en/class.intldateformatter.php da jeg skal bruge nogle datoer på forskellige sprog

Det er super smart fordi jeg kan bruge SHORT, FULL, LONG, NONE og MEDIUM til at få vist forskellige formater på de forskellige sprog

Men kan man lave andre formater som f.eks. måned og år?
Jeg er klar over man kan bruge f.eks. MM-Y til at få måned også, men så tilpasser den sig ikke til andre sprog i måden den er sat op

Ved I om det er muligt at få den til det?
Avatar billede Slater Ekspert
09. februar 2020 - 23:15 #1
Mener du du vil have den uden dagen, altså f.eks. i stedet for "9. februar 2020" vil du bare have "februar 2020"?

I så fald kan du bruge $pattern argumentet, men naturligvis kan den ikke finde ud af at bytte rundt på rækkefølgen af tingene, hvis den burde det til et bestemt sprog. Det kan den kun med de prædefinerede patterns.

$idf = new IntlDateFormatter('da_DK', IntlDateFormatter::NONE, IntlDateFormatter::NONE, NULL, NULL, 'MMMM Y');

echo $idf->format(0);
Avatar billede arne_v Ekspert
10. februar 2020 - 02:31 #2
Der er næppe nogen pæn løsning, fordi normalt bruger man et format kendt fra et land eller så bruger man sit eget format - et eget format baseret på et kendt format fra et land er en underlig hybrid.

Men vil man er er naturligvis visse muligheder for at lave noget gris:


<?php
function test($locale, $t, $strip = '') {
    echo "Locale: $locale\r\n";
    $idf = new IntlDateFormatter($locale, IntlDateFormatter::LONG, IntlDateFormatter::NONE);
    echo $idf->format($t) . "\r\n";
    $pattern = $idf->getPattern();
    $pattern = preg_replace('/[' . $strip . ']/', '', $pattern);
    $idf->setPattern($pattern);
    echo $idf->format($t) . "\r\n";
}

$t = time();
foreach (['da_DK', 'en_US', 'fr_FR', 'de_DE'] as $locale) {
    test($locale, $t, 'y,');
}
?>


9. februar 2020
9. februar
Locale: en_US
February 9, 2020
February 9
Locale: fr_FR
9 février 2020
9 février
Locale: de_DE
9. Februar 2020
9. Februar
Avatar billede Mik2000 Professor
10. februar 2020 - 12:47 #3
Hej

Tak for svar :).

Arne - det lader sig næste gøre
Dog vil jeg også gerne kunne gøre det i short format og der er den lidt svære da den jo kan være
19/05/2019
2019-05-19
05/19-2019
osv.

Er det umuligt at fjerne år derfra også uden det går ud over det andet
Avatar billede arne_v Ekspert
10. februar 2020 - 15:52 #4
Alt er muligt hvis man vil lave nok krumspring.

:-)


<?php
interface PatternModifier {
    public function replace($pattern);
}

class RegexRemove implements PatternModifier {
    private $stripchars;
    public function __construct($stripchars) {
        $this->stripchars = $stripchars;
    }
    public function replace($pattern) {
        return  preg_replace('/[' . $this->stripchars . ']/', '', $pattern);
    }
}

class StartEndTrim implements PatternModifier {
    private $skipstart;
    private $skipend;
    public function __construct($skipstart, $skipend) {
        $this->skipstart = $skipstart;
        $this->skipend = $skipend;
    }
    public function replace($pattern) {
        return substr($pattern, $this->skipstart, -$this->skipend);
    }
}

class Combined implements PatternModifier {
    private $modifiers;
    public function __construct($modifiers) {
        $this->modifiers = $modifiers;
    }
    public function replace($pattern) {
        $result = $pattern;
        foreach($this->modifiers as $m) {
            $result = $m->replace($result);
        }
        return $result;
    }
}

function test($locale, $t, $format, $pattern_modifier) {
    echo "Locale: $locale\r\n";
    $idf = new IntlDateFormatter($locale, $format, IntlDateFormatter::NONE);
    echo $idf->format($t) . "\r\n";
    $pattern = $idf->getPattern();
    $pattern = $pattern_modifier->replace($pattern);
    $idf->setPattern($pattern);
    echo $idf->format($t) . "\r\n";
}

$t = time();
foreach (['da_DK', 'en_US', 'fr_FR', 'de_DE'] as $locale) {
    test($locale, $t, IntlDateFormatter::LONG, new RegexRemove('y,'));
    test($locale, $t, IntlDateFormatter::SHORT, new Combined([new RegexRemove('y'), new StartEndTrim(0, 1)]));
}
?>


Locale: da_DK
10. februar 2020
10. februar
Locale: da_DK
10/02/2020
10/02
Locale: en_US
February 10, 2020
February 10
Locale: en_US
2/10/20
2/10
Locale: fr_FR
10 février 2020
10 février
Locale: fr_FR
10/02/2020
10/02
Locale: de_DE
10. Februar 2020
10. Februar
Locale: de_DE
10.02.20
10.02
Avatar billede Mik2000 Professor
10. februar 2020 - 18:19 #5
Super cool Arne.

Jeg har nu prøvet at sidde og skille det lidt ad, så jeg kan få det sat sammen med det jeg har i forvejen, men synes ikke rigtig det lykkedes at gennemskue ;)

Jeg har en kode hvor der står
if($stripYear) {
    if($patternDate != "SHORT") {
        // Her gør den det fra dit tidligere svar som virker super fint
        $pattern = $IntlDateFormatter->getPattern();
        $pattern = preg_replace('/[\/y]/', '', $pattern);
        $IntlDateFormatter->setPattern($pattern);
    } else {
    // Her vil jeg gerne have den til at "do the magic" når det er SHORT og man har valgt at år ikke skal være med             
    }
}

Men kan simpelthen ikke få det til at virke - nok fordi jeg ikke er helt sikker på hvordan jeg skal tage det fra klasserne og derind ;)

Kan du hjælpe med det også
Avatar billede arne_v Ekspert
10. februar 2020 - 19:19 #6
Det kan jo laves på mange måder.

Men er er:


<?php
interface PatternModifier {
    public function replace($pattern);
}

class RegexRemove implements PatternModifier {
    private $stripchars;
    public function __construct($stripchars) {
        $this->stripchars = $stripchars;
    }
    public function replace($pattern) {
        return  preg_replace('/[' . $this->stripchars . ']/', '', $pattern);
    }
}

class StartEndTrim implements PatternModifier {
    private $skipstart;
    private $skipend;
    public function __construct($skipstart, $skipend) {
        $this->skipstart = $skipstart;
        $this->skipend = $skipend;
    }
    public function replace($pattern) {
        return substr($pattern, $this->skipstart, -$this->skipend);
    }
}

class Combined implements PatternModifier {
    private $modifiers;
    public function __construct($modifiers) {
        $this->modifiers = $modifiers;
    }
    public function replace($pattern) {
        $result = $pattern;
        foreach($this->modifiers as $m) {
            $result = $m->replace($result);
        }
        return $result;
    }
}

function mik_date($locale, $t, $format, $pattern_modifier = null) {
    $idf = new IntlDateFormatter($locale, $format, IntlDateFormatter::NONE);
    if($pattern_modifier != null) {
        $pattern = $idf->getPattern();
        $pattern = $pattern_modifier->replace($pattern);
        $idf->setPattern($pattern);
    }
    return $idf->format($t);
}

$t = time();
echo mik_date('da_DK', $t, IntlDateFormatter::LONG) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::LONG) . "\r\n";
echo mik_date('da_DK', $t, IntlDateFormatter::LONG, new RegexRemove('y,')) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::LONG, new RegexRemove('y,')) . "\r\n";
echo mik_date('da_DK', $t, IntlDateFormatter::SHORT) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::SHORT) . "\r\n";
echo mik_date('da_DK', $t, IntlDateFormatter::SHORT, new Combined([new RegexRemove('y'), new StartEndTrim(0, 1)])) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::SHORT, new Combined([new RegexRemove('y'), new StartEndTrim(0, 1)])) . "\r\n";
?>
Avatar billede arne_v Ekspert
10. februar 2020 - 19:28 #7
Eller hvis du lider af allergi mod klasser:


<?php
function mik_date($locale, $t, $format, $stripchars = null, $skipstart = 0, $skipend = -100) {
    $idf = new IntlDateFormatter($locale, $format, IntlDateFormatter::NONE);
    if($stripchars != null) {
        $pattern = $idf->getPattern();
        $pattern = substr(preg_replace('/[' . $stripchars . ']/', '', $pattern), $skipstart, -$skipend);
        $idf->setPattern($pattern);
    }
    return $idf->format($t);
}

$t = time();
echo mik_date('da_DK', $t, IntlDateFormatter::LONG) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::LONG) . "\r\n";
echo mik_date('da_DK', $t, IntlDateFormatter::LONG, 'y,') . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::LONG, 'y,') . "\r\n";
echo mik_date('da_DK', $t, IntlDateFormatter::SHORT) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::SHORT) . "\r\n";
echo mik_date('da_DK', $t, IntlDateFormatter::SHORT, 'y', 0, 1) . "\r\n";
echo mik_date('en_US', $t, IntlDateFormatter::SHORT, 'y', 0, 1) . "\r\n";
?>
Avatar billede Mik2000 Professor
11. februar 2020 - 00:06 #8
Hej Arne

Jeg kan egentlig godt lide klasser men har lige nemmest ved at forstå funktionaliteten i det andet eksempel må jeg være ærlig at indrømme ;)
Er super glad for du gider bruge tid på at hjælpe

Det virker super godt. Dog et enkelt problem mere hvis du har tålmodighed snart :) :) :)

I nogle tilfælde vil jeg gerne have tiden med hvilket resulterer i f.eks
da_DK
12/01/ 12.18
12/01/ 12.18.15
12/01/ 12.18.15 CET

en_US
1/12/, 12:18
1/12/, 12:18:15
1/12/, 12:18:15 PM GMT+1

Hvor der kommer noget komma og slash
Kan man klare det også, eller er det umuligt når man tager højde for forskellige formater?
Avatar billede arne_v Ekspert
11. februar 2020 - 02:25 #9

<?php
interface PatternModifier {
    public function replace($pattern);
}

class RegexRemove implements PatternModifier {
    private $stripchars;
    public function __construct($stripchars) {
        $this->stripchars = $stripchars;
    }
    public function replace($pattern) {
        return  preg_replace('/[' . $this->stripchars . ']/', '', $pattern);
    }
}

class StartEndTrim implements PatternModifier {
    private $skipstart;
    private $skipend;
    public function __construct($skipstart, $skipend) {
        $this->skipstart = $skipstart;
        $this->skipend = $skipend;
    }
    public function replace($pattern) {
        return substr($pattern, $this->skipstart, -$this->skipend);
    }
}

class RegexReplace implements PatternModifier {
    private $search;
    private $replace;
    public function __construct($search, $replace) {
        $this->search = $search;
        $this->replace = $replace;
    }
    public function replace($pattern) {
        return  preg_replace('/' . $this->search . '/', $this->replace, $pattern);
    }
}

class Combined implements PatternModifier {
    private $modifiers;
    public function __construct($modifiers) {
        $this->modifiers = $modifiers;
    }
    public function replace($pattern) {
        $result = $pattern;
        foreach($this->modifiers as $m) {
            $result = $m->replace($result);
        }
        return $result;
    }
}

function mik_date($locale, $t, $format, $pattern_modifier = null) {
    $idf = new IntlDateFormatter($locale, $format, IntlDateFormatter::NONE);
    if($pattern_modifier != null) {
        $pattern = $idf->getPattern();
        $pattern = $pattern_modifier->replace($pattern);
        $idf->setPattern($pattern);
    }
    return $idf->format($t);
}

function mik_time($locale, $t, $format, $pattern_modifier = null) {
    $idf = new IntlDateFormatter($locale, IntlDateFormatter::NONE, $format);
    if($pattern_modifier != null) {
        $pattern = $idf->getPattern();
        $pattern = $pattern_modifier->replace($pattern);
        $idf->setPattern($pattern);
    }
    return $idf->format($t);
}

function mik_datetime($locale, $t, $date_format, $time_format, $delim = ' ', $date_pattern_modifier = null, $time_pattern_modifier = null) {
    return mik_date($locale, $t, $date_format, $date_pattern_modifier) . $delim . mik_time($locale, $t, $time_format, $time_pattern_modifier);
}

$t = time();
echo mik_datetime('da_DK', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM) . "\r\n";
echo mik_datetime('en_US', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM) . "\r\n";
echo mik_datetime('da_DK', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM, ' ', new Combined([new RegexRemove('y'), new StartEndTrim(0, 1)]), new Combined([new RegexReplace('mm[:\.]ss', 'mm')])) . "\r\n";
echo mik_datetime('en_US', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM, ' ', new Combined([new RegexRemove('y'), new StartEndTrim(0, 1)]), new Combined([new RegexReplace('mm[:\.]ss', 'mm')])) . "\r\n";
?>



<?php
function mik_date($locale, $t, $format, $stripchars = null, $skipstart = 0, $skipend = -100) {
    $idf = new IntlDateFormatter($locale, $format, IntlDateFormatter::NONE);
    if($stripchars != null) {
        $pattern = $idf->getPattern();
        $pattern = substr(preg_replace('/[' . $stripchars . ']/', '', $pattern), $skipstart, -$skipend);
        $idf->setPattern($pattern);
    }
    return $idf->format($t);
}

function mik_time($locale, $t, $format, $search = null, $replace = null) {
    $idf = new IntlDateFormatter($locale, IntlDateFormatter::NONE, $format);
    if($search != null) {
        $pattern = $idf->getPattern();
        $pattern = preg_replace('/' . $search . '/', $replace, $pattern);
        $idf->setPattern($pattern);
    }
    return $idf->format($t);
}

function mik_datetime($locale, $t, $dateformat, $timeformat, $delim = ' ', $stripchars = null, $skipstart = 0, $skipend = -100, $search = null, $replace = null) {
    return mik_date($locale, $t, $dateformat, $stripchars, $skipstart, $skipend) . $delim . mik_time($locale, $t, $timeformat, $search, $replace);
}

$t = time();
echo mik_datetime('da_DK', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM) . "\r\n";
echo mik_datetime('en_US', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM) . "\r\n";
echo mik_datetime('da_DK', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM, ' ', 'y', 0, 1, 'mm[:\.]ss', 'mm') . "\r\n";
echo mik_datetime('en_US', $t, IntlDateFormatter::SHORT, IntlDateFormatter::MEDIUM, ' ', 'y', 0, 1, 'mm[:\.]ss', 'mm') . "\r\n";
?>
Avatar billede Mik2000 Professor
11. februar 2020 - 14:09 #10
Tak for hjælpen - så spiller det hele :)
Avatar billede Mik2000 Professor
11. februar 2020 - 14:09 #11
Er virkelig glad for den store hjælp du kom med her :)
Avatar billede arne_v Ekspert
12. februar 2020 - 00:35 #12
Og for at der ikke skal være nogen tvivl: de her manipulationer ag dato formater er ikke helt fine i kanten. De ser ud til at virke med de gængse sprog, men jeg vil ikke udelukke problemer i mere eksotiske sprog.

Hvis jeg skulle reviewe sådan noget kode ville jeg stille spørgsmåltegn ved om det var den rigtige løsning.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester