3

I'm using the Twitter API to show my latest tweets on my website using PHP.

This is the part where I show the timestamp:

echo '<time data-original="'.$tweets[$i]['created_at'].'" title="'.date('l, j F Y', strtotime($tweets[$i]['created_at'])).' at '.date('g:ia', strtotime($tweets[$i]['created_at'])).'" datetime="' .date('Y-m-d', strtotime($tweets[$i]['created_at'])). 'T' . date('H:i:s', strtotime($tweets[$i]['created_at'])). 'Z" pubdate>"';

What I have noticed is that the dates are incorrect. For example for a tweet that was ACTUALLY posted at 11.51pm the following is parsed by the above code:

<time data-original="Sun May 04 22:51:43 +0000 2014" title="Sunday, 4 May 2014 at 3:51pm" datetime="2014-05-04T15:51:43Z" pubdate=""><a target="_blank" href="#">19 hours ago</a></time>

So first of all the data-original is one hour out (perhaps due to DST, but why hasn't the API handled this? As it knows my location via my timezone settings right?).

The second issue is that due to me formatting the dates in a certain way it seems to be switching the dates to the location of the hosting server so moving them back several hours.

Any ideas on how to fix this?


What I'm trying using JavaScript:

var d = new Date();

var n = d.getTimezoneOffset();

$('time').each(function(){

    var time = $(this);

    var timeOriginal = time.attr('data-original');
    var timeDateTime = time.attr('datetime');
    var timeTitle = time.attr('title');
    var timeText = time.find('a').html(); // because the text is inside an anchor

    timeOriginal = '';
    timeDateTime = '';
    timeTitle = '';
    timeText = '';

});

So using that offset declared at the top of the page, I need to update the times so they become local rather than the server times. Not quite sure how best to approach this.

Cameron
  • 27,963
  • 100
  • 281
  • 483

4 Answers4

4

You do need to account for the timezone being UTC but you can do that without changing the default time zone if you use the DateTime class

<?php

// Twitter time is UTC
$utc = new DateTimeZone('UTC');

foreach ($tweets as $i => $tweet) {
    $datetime = new DateTime($tweet['created_at'], $utc);

    //test to see the value
    echo $datetime->format('Y-md') . 'T' . $datetime->format('H:i:s');
}
Oscar M.
  • 1,076
  • 7
  • 9
2

"Problem" 1: Tweets are always send to you with the UTC/GMT timestamp.

"Problem" 2: As the manual for strtotime clearly states, it always uses the default timezone to parse date.

So what you need to do is simple, you need to change the timezone to UTC before you use the strtotime function. If you change the timezone for your server all over, there is a change other date calculation will be wrong. You can use the following function to get the correct date/time.

This will display the time always in the same timezone, even if users view the site from different timezones. If you need a per user method, look below the PHP code.

<?php
function tweetStrToTime($t) {
  //store the current timezone
  $ctz = date_default_timezone_get();
  //switch to UTC
  date_default_timezone_set('UTC');
  //use strtotime
  $time = strtotime($t);
  //change back to the orignal timezone
  date_default_timezone_set($ctz);
  //return the result from strtotime
  return $time;
}

//a copy of your value in $tweets[$i]['created_at']
$tweettime = "Sun May 04 22:51:43 +0000 2014";

//test to see the value
echo date('Y-m-d', tweetStrToTime($tweettime)). 'T' . date('H:i:s', tweetStrToTime($tweettime))
?>

codepad example to see it in action. Keep in mind that codepad already uses UTC, so in this case it would also work with just using strtotime

Javascript solution:

If you want to start working with javascript to handle the timezone for each individual user, you could also try a library like momentjs which has some nice features for handling date/time. this question also has some other answers on handling timezone in javascript.

Community
  • 1
  • 1
Hugo Delsing
  • 13,803
  • 5
  • 45
  • 72
0

It seems that the API is sending you an universal time stamp. It is your job to print it in the correct time format for your timezone. If you use PHP 5.1 or higher you can use date_default_timezone_set() to set the timezone to use for your date() functions. You will have to parse the data-original too if you want that in your timezone as well.

http://php.net/manual/en/function.date-default-timezone-set.php

Chris
  • 1,068
  • 2
  • 14
  • 30
  • But this will depend where the current user viewing the website where this feed is being displayed is right? – Cameron May 08 '14 at 14:54
  • If your site is being accessed by users from multiple timezones, and you want to make sure it displays correctly for each user, then you need solve this with Javascript using: http://www.w3schools.com/jsref/jsref_gettimezoneoffset.asp. You need to store the parsed universal timestamp in a JS variable, determine the timezone of the user, adjust the time accordingly, and then assign the times into each attribute of your HTML node. You can also try to tell your server what the users timezone is with javascript, then store it in a session and do the parsing on the server. – Chris May 08 '14 at 15:00
  • I see in the W3C docs you can leave the time in the datetime attributes just as a universal time, but you need to convert the titles yourself. – Chris May 08 '14 at 15:04
  • Could you show an example of how I could use this offset to dynamically change the dates for the tweets? I'll update my question with what I have in my head so far. – Cameron May 08 '14 at 15:38
0

Another simple trick is to create your local date object with second parameter which is timezone object.

$user_status_created_at = $status['created_at'];
$local_date = date_timezone_set(date_create($user_status_created_at),timezone_open('Asia/Jakarta'));
abduljpwd
  • 21
  • 2