Nik has asked for the wisdom of the Perl Monks concerning the following question:

Ok, iam having 2 problems with the following lines:
my $date = strftime('%a %d %b, %I:%M %p', localtime); Encode::from_to($date, 'ISO-8859-7', 'utf8');
a) $date in this format wont get inserted into a mysql datetime field and the cgi script gives me this error: DBD::mysql::st execute failed: Incorrect datetime value: 'Σαβ 27 Μαϊ, 07:35 μμ' for column 'date' at ...
I must insert it thw way i want although mysql wants the timestamp like '%y-%m-%d %H:%M:%S' but i dont want to enter ti that way because later it would need retransfomration. Is there a way to make perl insert this to the mysql datetime filed thae way i want it to eb inserted?

b) in order to be able to view corectly my $date with print $date i must re-encode it to Greek iso other wise i get question marks although iam using print header( -charset=>'utf8' );

How do you explain this?

Replies are listed 'Best First'.
Re: datetime insertion problem
by Zaxo (Archbishop) on May 27, 2006 at 17:06 UTC

    I think we'd have to know more about both your environment and the MySQL server's to answer the "Why?". POSIX::strftime honors locale, so the value of $date depends on your LC_foo environment variables. MySQL may be compiled to store utf-8 or some other character encoding.

    Question a): I think you should store datetime fields the way MySQL wants, as a datetime column type. Storing them as strings denies you the very useful builtin date & time functions of MySQL. You can retrieve datetimes with MySQL's DATE_FORMAT() function to get most any representation you want. If you have serious encoding problems, you can fall back on unix epoch time for retrieval and then apply localtime.

    Question b): Some browsers pretty much ignore http headers. Try specifying the character encoding in the html tag, as well.

    After Compline,
    Zaxo

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: datetime insertion problem
by CountZero (Bishop) on May 27, 2006 at 17:09 UTC
    If you want to keep your datetime value in your own format, you better store it in a CHAR or VARCHAR type of field rather than in a DATETIME or timestamp type of field.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: datetime insertion problem
by CountZero (Bishop) on May 27, 2006 at 21:46 UTC
    From the docs of MySQL:

    DATE_FORMAT(date,format)

    Formats the date value according to the format string.

    The following specifiers may be used in the format string. The ‘%’ character is required before format specifier characters.

    Specifier Description
    %a Abbreviated weekday name (Sun..Sat)
    %b Abbreviated month name (Jan..Dec)
    %c Month, numeric (0..12)
    %D Day of the month with English suffix (0th, 1st, 2nd, 3rd, ...)
    %d Day of the month, numeric (00..31)
    %e Day of the month, numeric (0..31)
    %f Microseconds (000000..999999)
    %H Hour (00..23)
    %h Hour (01..12)
    %I Hour (01..12)
    %i Minutes, numeric (00..59)
    %j Day of year (001..366)
    %k Hour (0..23)
    %l Hour (1..12)
    %M Month name (January..December)
    %m Month, numeric (00..12)
    %p AM or PM
    %r Time, 12-hour (hh:mm:ss followed by AM or PM)
    %S Seconds (00..59)
    %s Seconds (00..59)
    %T Time, 24-hour (hh:mm:ss)
    %U Week (00..53), where Sunday is the first day of the week
    %u Week (00..53), where Monday is the first day of the week
    %V Week (01..53), where Sunday is the first day of the week; used with %X
    %v Week (01..53), where Monday is the first day of the week; used with %x
    %W Weekday name (Sunday..Saturday)
    %w Day of the week (0=Sunday..6=Saturday)
    %X Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
    %x Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
    %Y Year, numeric, four digits
    %y Year, numeric (two digits)
    %% A literal ‘%’ character
    %x x, for any ‘x’ not listed above

    Ranges for the month and day specifiers begin with zero due to the fact that MySQL allows the storing of incomplete dates such as '2004-00-00'.

    mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
            -> 'Saturday October 1997'
    mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
            -> '22:23:00'
    mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
    
                              '%D %y %a %d %m %b %j');
            -> '4th 97 Sat 04 10 Oct 277'
    mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                              '%H %k %I %r %T %S %w');
            -> '22 22 10 10:23:00 PM 22:23:00 00 6'
    mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
            -> '1998 52'
    mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
    
            -> '00'
    

    This allows you to format your DATETIME or TIMESTAMP fields, but it doesn't seem to honor your locale setting. As a matter of fact, MySQL does not seem to know how to set the locale at all. It can however set on a per table basis the character set to use (latin1, UTF8, ...).

    If you really want to have your DATETIME fields in Greek, have a look at DBIx::Class and its inflate/deflate mechanism or the ColumnHandlers method from DBIx::DataModel which can transform your fields in pretty any way you like.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      And why do i need to use encode to switch from greek => utf8?
        I'm not the big expert on encoding, but I think the whole encoding thing must be perfectly aligned for it to work. It is best to have the same encoding set on both the input machine/layer, the storage layer ( i.e. the database) and the output machine/layer. If somewhere in this chain of things there is a different encoding then you get "funny" characters. So if you start with "greek" encoding, you better have this all the way through to avoid problems.

        Other monks much more versed in the ways of Unicode and the like probably can tell you more about it or you can have a look at perluniintro and perlunicode.

        CountZero

        "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: datetime insertion problem
by TedPride (Priest) on May 27, 2006 at 20:26 UTC
    Pardon me for asking stupid questions, but why aren't you just doing something like:
    INSERT INTO mytable (mydatetimefield) values (NOW());
    mySQL accepts NOW() input for datetime fields, and there's no need to mess with formatting it yourself.
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: datetime insertion problem
by stonecolddevin (Parson) on May 28, 2006 at 01:08 UTC
    how about:
    sub now { my @time = localtime; return sprintf '%d-%02d-%02d %02d:%02d:%02d', $time[5]+1900, $time[4]+1, $time[3], $time[2], $time[1], $ +time[0]; # year month day hour min +sec }
    ?
    meh.