Date formats for locale

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Adrian Parker

    Date formats for locale

    I have a server app which is sent a date in the local format of the client
    machine. I've no control over the client app at all, so have to code at the
    server end to cope with any problems. The server is in the US, so any
    dates need to be in US format before they will convert using strtotime()

    Here is what i'm doing at the moment..

    // need to convert date to use USA mm/dd/yyyy format on server
    $split = explode(",",$_S ERVER[HTTP_ACCEPT_LAN GUAGE]);

    switch ($split[0]) {
    case "en-us":
    break;
    case "en-gb":
    $lt = substr($lt,3,3) . substr($lt,0,3) . substr($lt,6);
    break;
    case "da":
    case "pt":
    $lt = substr($lt,3,2) . "/" . substr($lt,0,2) . "/" . substr($lt,6);
    break;
    }
    $ustime = strtotime($lt);

    As you can see, the switch could get huge.. Is there any easier way ?

    Thanks
    Adrian






  • Henk Verhoeven

    #2
    Re: Date formats for locale

    Hi Adrian,

    Suppose you have a DateFormatter class, then you could define an array
    with a date format for each locale, and one with separators, like:

    function initFormatsAndS eparators () {
    $this->dateformats["en-us"] = "mm/dd/yyyy";
    $this->dateSeparato rs["en-us"] = '/'.
    $this->dateformats["du-nl"] = "yyyy-mm-dd";
    $this->dateSeparato rs["du-nl"] = '-'.
    }
    now you can split a date like this:

    function splitDT($value, $locale)
    {
    $expr = '['.$this->dateSeparato rs[$locale].']';
    $arr = split($expr, $value);
    $formatArray = split($expr, $this->dateformats[$locale]);
    for ($i=0; $i<count($forma tArray); $i++)
    $result[$formatArray[$i]] = $arr[$i];
    return $result;
    }

    This gives you an array like:
    array('yyyy' => '2004', 'mm' => '7', 'dd' => '18')

    formatting suchg a splitted date into another format can then be done like:

    function formatDate($spl ittedDate, $locale)
    {
    $result = $this->dateFormats[$locale];
    forEach($splitt edDate as $key => $value)
    $result = str_replace($ke y, $value, $result);
    return $result;
    }

    Of course there will be more to it then this, for example you may want
    to convert 'mm' => '7' into 'mm' => '07' and check that the value for
    'mm' is no larger then 12. Or you might want to process month names.
    This will probably lead to a case switch with a case for 'mm' and one
    for for 'yyyy' etc. that you run through while looping through the
    $splittedDate array. But at least that case switch will be a lot smaller
    then a case for each and every locale.

    BTW, did you check out http://pear.php.net/package/Date ?
    (please let me know if you find a workaround for it's dependency on
    setLocale based functions ;-) )

    Greetings,

    Henk Verhoeven,
    www.pphPeanuts.org.

    // Copyright (c) the partners of MetaClass, 2003, 2004
    // Licensed under the Academic Free License version 2.0

    For working code (but no direct support of locale's) see:



    Adrian Parker wrote:
    [color=blue]
    > I have a server app which is sent a date in the local format of the client
    > machine. I've no control over the client app at all, so have to code at the
    > server end to cope with any problems. The server is in the US, so any
    > dates need to be in US format before they will convert using strtotime()
    >
    > Here is what i'm doing at the moment..
    >
    > // need to convert date to use USA mm/dd/yyyy format on server
    > $split = explode(",",$_S ERVER[HTTP_ACCEPT_LAN GUAGE]);
    >
    > switch ($split[0]) {
    > case "en-us":
    > break;
    > case "en-gb":
    > $lt = substr($lt,3,3) . substr($lt,0,3) . substr($lt,6);
    > break;
    > case "da":
    > case "pt":
    > $lt = substr($lt,3,2) . "/" . substr($lt,0,2) . "/" . substr($lt,6);
    > break;
    > }
    > $ustime = strtotime($lt);
    >
    > As you can see, the switch could get huge.. Is there any easier way ?
    >
    > Thanks
    > Adrian
    >
    >
    >
    >
    >
    >[/color]

    Comment

    • Adrian Parker

      #3
      Re: Date formats for locale

      Henk,

      Yeah, I know I can do what you suggest, it's more the fact of having to
      specify the format for all possible locales which seems to be a huge hole in
      php.

      -Adrian


      "Henk Verhoeven" <news1@phppeanu tsREMOVE-THIS.org> wrote in message
      news:cljpkt$2s0 $1@news3.zwoll1 .ov.home.nl...[color=blue]
      > Hi Adrian,
      >
      > Suppose you have a DateFormatter class, then you could define an array
      > with a date format for each locale, and one with separators, like:
      >
      > function initFormatsAndS eparators () {
      > $this->dateformats["en-us"] = "mm/dd/yyyy";
      > $this->dateSeparato rs["en-us"] = '/'.
      > $this->dateformats["du-nl"] = "yyyy-mm-dd";
      > $this->dateSeparato rs["du-nl"] = '-'.
      > }
      > now you can split a date like this:
      >
      > function splitDT($value, $locale)
      > {
      > $expr = '['.$this->dateSeparato rs[$locale].']';
      > $arr = split($expr, $value);
      > $formatArray = split($expr, $this->dateformats[$locale]);
      > for ($i=0; $i<count($forma tArray); $i++)
      > $result[$formatArray[$i]] = $arr[$i];
      > return $result;
      > }
      >
      > This gives you an array like:
      > array('yyyy' => '2004', 'mm' => '7', 'dd' => '18')
      >
      > formatting suchg a splitted date into another format can then be done
      > like:
      >
      > function formatDate($spl ittedDate, $locale)
      > {
      > $result = $this->dateFormats[$locale];
      > forEach($splitt edDate as $key => $value)
      > $result = str_replace($ke y, $value, $result);
      > return $result;
      > }
      >
      > Of course there will be more to it then this, for example you may want to
      > convert 'mm' => '7' into 'mm' => '07' and check that the value for 'mm' is
      > no larger then 12. Or you might want to process month names.
      > This will probably lead to a case switch with a case for 'mm' and one for
      > for 'yyyy' etc. that you run through while looping through the
      > $splittedDate array. But at least that case switch will be a lot smaller
      > then a case for each and every locale.
      >
      > BTW, did you check out http://pear.php.net/package/Date ?
      > (please let me know if you find a workaround for it's dependency on
      > setLocale based functions ;-) )
      >
      > Greetings,
      >
      > Henk Verhoeven,
      > www.pphPeanuts.org.
      >
      > // Copyright (c) the partners of MetaClass, 2003, 2004
      > // Licensed under the Academic Free License version 2.0
      >
      > For working code (but no direct support of locale's) see:
      > http://www.phppeanuts.org/site/index...Converter.html
      >
      >
      > Adrian Parker wrote:
      >[color=green]
      >> I have a server app which is sent a date in the local format of the
      >> client machine. I've no control over the client app at all, so have to
      >> code at the server end to cope with any problems. The server is in the
      >> US, so any dates need to be in US format before they will convert using
      >> strtotime()
      >>
      >> Here is what i'm doing at the moment..
      >>
      >> // need to convert date to use USA mm/dd/yyyy format on server
      >> $split = explode(",",$_S ERVER[HTTP_ACCEPT_LAN GUAGE]);
      >>
      >> switch ($split[0]) {
      >> case "en-us":
      >> break;
      >> case "en-gb":
      >> $lt = substr($lt,3,3) . substr($lt,0,3) . substr($lt,6);
      >> break;
      >> case "da":
      >> case "pt":
      >> $lt = substr($lt,3,2) . "/" . substr($lt,0,2) . "/" . substr($lt,6);
      >> break;
      >> }
      >> $ustime = strtotime($lt);
      >>
      >> As you can see, the switch could get huge.. Is there any easier way ?
      >>
      >> Thanks
      >> Adrian
      >>
      >>
      >>
      >>
      >>
      >>[/color]
      >[/color]


      Comment

      • Henk Verhoeven

        #4
        Re: Date formats for locale

        Hi Adrian,

        Sorry for the late reaction (working in phpPeanuts AND meeting a project
        deadline...). I did some googling, maybe the following leads to some
        parsable open source locale definitions (see below).

        Greetings,

        Henk Verhoeven.



        I'm writing to suggest that the default output format of 'date' (when
        | neither '-R' nor '-I' option is given) has to be made locale-dependent
        | using gettext().
        |
        | date.c (in sh-utils-2.0) has the following:
        |

        Thanks for the suggestion.
        That problem was addressed by this change:

        2000-03-29 Paul Eggert

        * src/date.c: Include <langinfo.h> if it exists.
        (DATE_FMT_LANGI NFO): New macro.
        (show_date): Use it to get the locale-specific default format for
        "date" if it exists.



        Comment

        Working...