This is a proof of concept for presenting datetime stamps on a website in the correct time for all users where correct means the moment in 4D it happened (according to their system clock, anyway).

For this to work we assume the datetime stamps in the DB records are normalized to UTC. The demo uses Template so perl can write the JS and Time::Piece for date objects b/c it's a convention when using Class::DBI (not used here but where I'll be applying this concept myself after breaking things into their proper constituents).

Eg, user in PST posts something at 1pm. The DB marks it as posted at 8pm (all times in DB are normalized to UTC). Then when the date is fetched for a webpage, it is wrapped in a JavaScript function to print it as local time. The user in EST now sees the time as 4pm which is really the time it was in EST when the original post was made.

Aren't dates fun? I hope I'm not breaching etiquette too much by posting a largely JavaScript solution to this problem but it's only really addressed by client side information. This was prompted by User's time.

# Declarations #================================================================= use warnings; no warnings 'uninitialized'; use strict; use CGI (); use Template; use Time::Piece; # Program proper #================================================================= my $template = Template->new(); my $utc_date_from_a_db = '2004-10-18 03:32:11'; my $data = { utc_date => Time::Piece->strptime($utc_date_from_a_db, "%Y-%m-%d %k:%M:%S"), }; print CGI::header(), CGI::start_html('Localized Date with JavaScript via Perl'); $template->process(\*DATA, $data); __END__ <script type="text/javascript"> Date.prototype.siteFormat = function() { var date = new Array ( this.getMonth() ,this.getDate() ,this.getFullYear() ); var seconds = this.getSeconds() > 10 ? this.getSeconds() : '0'+this. +getSeconds() var minutes = this.getMinutes() > 10 ? this.getMinutes() : '0'+this. +getMinutes() var hours = this.getHours() > 10 ? this.getHours() : '0'+this.getHou +rs() var time = new Array ( hours ,minutes ,seconds ); return date.join('/') + ' ' + time.join(':') }; // This isn't used here but it's useful enough to include Date.prototype.getMonthName = function() { var Months = new Array( 'January' ,'February' ,'March' ,'April' ,'May' ,'June' ,'July' ,'August' ,'September' ,'October' ,'November' ,'December' ); var month = this.getMonth(); return Months[month] || '' }; </script> <h3>Perl date object from DB: [% utc_date.mdy('/') %] [% utc_date.hms() %]</h3> <h3> [% date_parts = utc_date.datetime.split(' ') %] [% date = date_parts.0.split('\D') %] <script type="text/javascript"> document.write ('JavaScript adjusted for TZ: ') var now = new Date () var offset = Math.floor( now.getTimezoneOffset() / 60 ) var offset_milliseconds = offset * 60 * 60 * 1000 var utc_date = new Date( [% date.join(',') %] ) var local_time = utc_date.getTime() - offset_milliseconds var local_date = new Date ( local_time ) document.write( local_date.siteFormat() ) </script> <noscript> JavaScript is off so same, same: [% utc_date.mdy('/') %] [% utc_date.hms() %] UTC </noscript> </h3>

Also, you might find this additional snippet helpful for datetime normalization if you're using Class::DBI like I am. In a table with a 'created' field it automatically stamps the time to UTC when a new object (record) is created (MySQL version shown). You'll need to see the Class::DBI docs if you don't know them already.

my $utc_offset = abs( ( Date::Calc::Timezone() )[3] ); __PACKAGE__->set_sql(MakeNewObj => <<"SQL"); INSERT INTO __TABLE__ (created, \%s) VALUES (DATE_ADD(NOW(), INTERVAL $utc_offset HOUR), \%s) SQL

In reply to Perl + JavaScript to display "correct" local times for datetimes by Your Mother

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.