Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    Regular Coder
    Join Date
    Sep 2011
    Posts
    428
    Thanks
    18
    Thanked 26 Times in 26 Posts

    Best method for logging timestamps

    I am looking for the bet way to save a timestamp for any action that would happen on a site. It needs to be timezone and daylight savings friendly. So far I've just used time() but I'm looking to make it more user friendly.

    I set the default time zone on my site to UTC using the date_default_timezone_set() function. I now need to know what the best way to store the actions for users in the database so it can be seen in the proper timezone with adjustments made in addition to daylight savings when applied. So if it says that a user was last active at 7PM EST it will display 4PM PST and 12AM GMT.

    I haven't played around with it too much, especially since it's hard to test without forcing daylight savings switches. So far the function I have came up with to change the time to the user's timezone is this:
    PHP Code:
    function setTimeZone($time$timezone)
    {
        global 
    $user$timezones;
        if(!
    $time)
            
    $time time();
        if(!
    $timezone && $user->time_zone)
            
    $timezone $user->time_zone;
        if(!
    $timezone)
            
    $timezone $_COOKIE['time_zone'];
        if(!
    in_array($timezone$timezones))
            die(
    'Invalid timezone');
        
    $date = new DateTime('@'.$time);
        
    $date->setTimeZone(new DateTimeZone($timezone));
        
    $str $date->format('c');
        return 
    $str;

    It works to an extent, but the time ends up with -4 as the offset instead of -5 because of daylight savings taking into effect.


    Please let e know what the best method of running this would be, and if there's a better way to store the timezone to the users instead of using the long names like EST instead of America/New_York

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    UTC is the correct way to store it, either as a unix timestamp or preferably a datetime.
    Use only an integer generated from a time() or the DateTime objects. Never deal with strings except for on output. Timezone can be changed at any time since that affects the output of the format functions, NOT the time itself. Then you simply adjust your timezones as you see fit using date_default_timezone_set with time, or DateTime::setTimezone on the object itself (recommended). The underlying time should always be stored in UTC (I'm quite sure its always stored in UTC regardless of what timezone you specified in date_default_timezone_set or DateTimeZone since that would make the most sense). So therefore the most userfriendly way to store your time is either in a unix timestamp (limited to 2038 on an x86 system), or as a DATETIME. If you're in a database, DateTime is available in MySQL, Oracle, SQLServer for sure. I'm not 100% sure if its standard datatype or not, but it's in at least those three.
    Then when you want to display, simply set the timezone of the user. Ask them for that when they create an account (assuming its account based?).
    Then you can swap it as you see fit:
    PHP Code:
    $dt = new DateTime('2013-06-26 08:00:00', new DateTimeZone('America/Regina'));

    printf("It's %s (%d) in %s (offset: %0.1f)" PHP_EOL$dt->format('F j Y H:i:s'), $dt->getTimestamp(), $dt->getTimezone()->getName(), ($dt->getTimezone()->getOffset($dt) / 3600));

    $dt->setTimezone(new DateTimeZone('UTC'));

    printf("It's %s (%d) in %s (offset: %0.1f)" PHP_EOL$dt->format('F j Y H:i:s'), $dt->getTimestamp(), $dt->getTimezone()->getName(), ($dt->getTimezone()->getOffset($dt) / 3600));

    $dt->setTimezone(new DateTimeZone('Asia/Calcutta'));

    printf("It's %s (%d) in %s (offset: %0.1f)" PHP_EOL$dt->format('F j Y H:i:s'), $dt->getTimestamp(), $dt->getTimezone()->getName(), ($dt->getTimezone()->getOffset($dt) / 3600)); 
    Would output:
    Code:
    It's June 26 2013 08:00:00 (1372255200) in America/Regina (offset: -6.0)
    It's June 26 2013 14:00:00 (1372255200) in UTC (offset: 0.0)
    It's June 26 2013 19:30:00 (1372255200) in Asia/Calcutta (offset: 5.5)
    You'll notice the underlying timestamp does not change.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #3
    Regular Coder
    Join Date
    Aug 2012
    Posts
    142
    Thanks
    39
    Thanked 3 Times in 3 Posts
    if you're adding data to a table then you can use phpMyAdmin to add a timestamp column and set the default to Current time Stamp. This will embed current server time to each new entry.

    You then may retrieve the current local time using code similar to the code above.

  • #4
    Senior Coder
    Join Date
    Feb 2011
    Location
    Your Monitor
    Posts
    4,352
    Thanks
    61
    Thanked 528 Times in 515 Posts
    I've always preferred the unix integer timestamp myself. Not only does it sort easily via phpmyadmin (just like the datetime it uses) but php itself can also order them in an array easily too.
    See my new CodingForums Blog: http://www.codingforums.com/blogs/tangoforce/

    Many useful explanations and tips including: Cannot modify headers - already sent, The IE if (isset($_POST['submit'])) bug explained, unexpected T_CONSTANT_ENCAPSED_STRING, debugging tips and much more!

  • #5
    Regular Coder
    Join Date
    Sep 2011
    Posts
    428
    Thanks
    18
    Thanked 26 Times in 26 Posts
    I know this is an old post, but I found a working function to solve my problem and thought I should share it for those who come across the same issue. This seems to work with time zones and daylight savings also, so here it is:

    PHP Code:
    function timestamp($time$timezone 'UTC')
    {
        
    #Include the year if not the same
        
    if(date('Y'$time) != date('Y'))
            
    $dformat = array('value' => 'F j, Y ''parse' => true);
        
    #Show as "Today"
        
    elseif(date('md'$time) == date('md'))
            
    $dformat = array('value' => 'Today ''parse' => false);
        
    #Show as "Yesterday"
        
    elseif(date('md'$time) == date('md'strtotime('yesterday')))
            
    $dformat = array('value' => 'Yesterday ''parse' => false);
        
    #Day and date for same week
        
    elseif(date('mw'$time) == date('mw'))
            
    $dformat = array('value' => 'D j ''parse' => true);
        
    #Month and day
        
    else
            
    $dformat = array('value' => 'F j ''parse' => true);
        
    #Append the time
        
    $tformat 'g:i a';
        
    $datetime = new DateTime();
        
    $datetime->setTimestamp($time);
        
    $datetime->setTimeZone(new DateTimeZone($timezone));
        
    $timestamp = ($dformat['parse'] ? $datetime->format($dformat['value']) : $dformat['value'])."at ".$datetime->format($tformat);
        return 
    $timestamp;

    Adjust the $format variable to how you would like the format to come out, but so far the date and time were correct when running off a unix timestamp.
    Last edited by Dubz; 07-05-2013 at 08:55 PM.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •