Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm creating a PHP script for a Christmas calendar which is supposed to only load the respective content (some text and images) based on the current (December) date.
For example, on the 1st December (based on the PHP script) only the specified content should be shown. On the 2nd December, the specific content for that day/date should be shown.
My problem now is to ensure that in Germany we, obviously, have a different time zone than in (for me important) Vancouver, Canada.
How can I get the script working with the right request/checks on loading for the timezone/date that in these two particular timezones the content is visible at all times (while it is for instance the 1st of December in one of these timezones)??
This answer is based on the assumption that you use a webpage to show the user timezone.
First note that you can not get the user timezone in PHP. But what you can do is tell the server what the user date is via JavaScript.
You can do something like this:
var currentdate = new Date();
if(currentdate.getMonth() === 11){ // note that January = 0, Feb = 1 etc. So December = 11
$.get( "//christmasServer.com/timezone.php?user_day=" + currentdate.getDate(), function( data ) { // send to server, getDate() will show the day, December 14 will just show 14
$('.Christmas').html( data ); // do something with the data, for example replace the div .Christmas
});
} else {
// It's not even december in your timezone :-o
}
In timezone.php you can now determine what the day is.
As addition:
You can set the timezone in the $_SESSION so that you only have to set it once.
timezone.php:
if(!isset($_SESSION['user_timezone'])){ // if timezone isn't set
session_start(); // start session
$_SESSION['user_timezone'] = $_GET['user_day'];
}
if($_SESSION['user_timezone']===1){ // if it's the first of December
echo 'I\'m shown December first';
} else if($_SESSION['user_timezone']===2){ // if it's the second of December
echo 'I\'m shown December second';
}
// etc...
You can now always use $_SESSION['user_timezone'] to get the users' timezone.
Update:
In my of index.php:
<script type="text/javascript">
var currentdate = new Date();
if(currentdate.getMonth() === 10){ // for testing with november (=10)
$.get( "/timezone.php?user_day=" + currentdate.getDate(), function( data ) { // correct for localhost testing version, so no domain yet?!
$('.Christmas').html( data ); // do something with the data, for example replace the div .Christmas
});
} else {
// It's not even december in your timezone :-o
}
</script>
Later in the index.php:
...
<div class="Christmas">
</div>
...
In my timezone.php (in same folder):
if(!isset($_SESSION['user_timezone'])){ // if timezone isn't set
session_start(); // start session
$_SESSION['user_timezone'] = $_GET['user_day'];}
if($_SESSION['user_timezone']===1){ // if it's the first of December
echo 'Im shown December first';} else if($_SESSION['user_timezone']===2){ // if it's the second of December
echo 'Im shown December second';}
Related
I am displaying a calendar server side with php. Now I would like to scroll the months with 2 buttons (<< / >>) without reloading the whole page. There are loads of questions and examples, and I found some very close around forms, however, I have not really understood how to adapt this to a button.
A very simple script to pass the request new data is
<script>
$(document).ready(function(){
$("moveCal").click(function(){
$("#calendar").load("/presentation/cal.php");
});
});
</script>
A previous attempt of the php to request another month looked like this
echo '<span onclick="updateCal(\''.$toMonth->format('mY').'\')">';
echo '<span class="calendar_month_link"> '.$toMonth->format('M').' ></span></span>';
But how do I connect the updateCal() function with $(document).ready(function(){?
And another thing I am a bit confused about: If I am not working with a session id stored in a cookie, the application server still serves only the requesting IP with the requested date, right? Other simultaneous users can select other dates to be shown?
You may want more detail, but here's the gist of it:
A user visits a webpage and the address points to a PHP file- the PHP file runs on the server. It runs once per request, so the output will only be served to the requestor. If the file is static, or if it always produces the same HTML output- it'll be the same for everyone.
In your case, it sounds like you want at least a month variable, maybe a year variable too. When a request comes in with a variable (like $('#calendar').load('/presentation/cal.php?month=10&year=2021')) you can use the variable value to change the output. Since the variable is from the request, the output will be specific to the passed variables- thus every user on the site can send a different request and all see unique output.
In the above example, the month and year are passed via GET (i.e. they're appended to the URL as opposed to being in a form or passed via POST AJAX like $.post('cal.php', {month: 10, year: 2021}, function(responseData) { /*...*/ });).
PHP in turn has the $_GET and $_POST arrays to hold parameters passed via GET and POST methods respectively. So in the PHP file being requested (cal.php) you could use $_GET['month'] and $_GET['year'] to access the requested month and year. You would want to check if they exist in the request, and if not, use a default. If they are in the request, you'll want to verify that they're legitimate values, and if not, resort to the defaults (or deliver the user an error message).
So the pseudo-code might look something like:
cal.php
<?php
$defaultMonth = date("n");
$defaultYear = date("Y");
$month = isset($_GET['month']) ? $_GET['month'] : $defaultMonth;
/* check that $month is 1 - 12 [or whatever format you're expecting] and if not, set it to $defaultMonth instead, same thing for year */
$year = isset($_GET['year']) ? $_GET['year'] : $defaultYear;
/* query your database for events occurring in month $month and year $year */
/* echo out your calendar HTML with the included events from the requested month/year */
?>
index.php:
<div id='calendar'></div>
<script src='/path/to/jquery.js'></script>
<script>
var defaultMonth = <?php echo date("n") ?>;
var defaultYear = <?php echo date("Y") ?>;
var currentMonth = defaultMonth;
var currentYear = defaultYear;
function UpdateCal() {
$('#calendar').load('cal.php?month=' + currentMonth + '&year=' + currentYear);
}
function NextMonth() {
currentMonth += 1;
if(currentMonth == 13) {
currentMonth = 1;
currentYear += 1;
}
UpdateCal();
}
function PrevMonth() {
currentMonth -= 1;
if(currentMonth == 0) {
currentMonth = 12;
currentYear -= 1;
}
UpdateCal();
}
</script>
i'm using jquery countdown with php. i have given an end date which is going to the countdown. my problem is lets suppose 1 hour left is showing in countdown but when a user change its system time the countdown changes. like if a user back his time 1 hour then the counter will display the 2 hours left. is there any way to get the server time for more accurate time not the user system time. please help.
how can i get server time not user system time?
below is my jquery code
if($(pluginsArray[6]).length){
$(pluginsArray[6]).each(function(){
var $this = $(this),
dateObj = $this.data();
var finalDate = new Date(dateObj.year, dateObj.month, dateObj.day, dateObj.hours, dateObj.minutes);
$this.countdown({
timezone: +4,
until : finalDate,
expiryText: '<div class="over">Closed.</div>',
onExpiry : function(){
setTimeout(function( ) { location.reload(); }, 5000);
},
format :'DHMS',
layout : '<b>{dn}</b> <span class="fs_medium d_inline_b m_right_5">days</span> <b>{hn}</b> <span class="fs_medium d_inline_b m_right_5">hrs</span> <b>{mn}</b> <span class="fs_medium d_inline_b m_right_5">min</span> <b>{sn}</b> <span class="fs_medium">sec</span>'
});
});
}
and here is what i did in php
<div class="countdown color_redc d_inline_m fs_large second_font lh_small f_xs_20" style="font-size:26px;" data-year="<?= $aDate[0] ?>" data-month="<?= ($aDate[1] - 1) ?>" data-day="<?= $aDate[2] ?>" data-hours="<?= $aDate[3] ?>" data-minutes="<?= $aDate[4] ?>"></div>
Solution without PHP
What you can do, without coding any server side is using a public API to get current time.
Found a similar topic on StackoverFlow : Free Rest API to get current time as string (timezone irrelevant)
TimezoneDb provides a free API: http://timezonedb.com/api
GenoNames also has a RESTful API available to get the current time for
a given location: http://www.geonames.org/export/ws-overview.html.
You can use Greenwich, UK if you'd like GMT.
GenoNames looks to be US only, TimezoneDb works you just need to register for a free public key.
Few people recommend timeapi.org but looks like they do not accept CROSS-DOMAIN request in Ajax, and the exemple they provide is no longer available.
Solution with PHP and jQuery Countdown configuration
Also you can ask jQuery CountDown to synchronyze with your server using serverSync option
$(selector).countdown({
until:liftoffTime, serverSync: serverTime});
function serverTime() {
var time = null;
$.ajax({url: 'http://myserver.com/serverTime.php',
async: false, dataType: 'text',
success: function(text) {
time = new Date(text);
}, error: function(http, message, exc) {
time = new Date();
}});
return time;
}
PHP file : serverTime.php
<?php
$now = new DateTime();
echo $now->format("M j, Y H:i:s O")."\n";
?>
BUT
Keep in mind your user will always be able to change your code and fake it ... so if you need to implement some security this is not enough and you will need to code some backend stuff.
So here's what I'm trying to do - I have the following code:
<div id="on">
<p>We are: <span class="onair">ON AIR</span></p>
</div>
<div id="off">
<p>We are: <span class="offair">OFF AIR</span></p>
</div>
And what I'd like to do is "show" the "on" div on Tuesday's from 3pm to 4pm (server time), while simultaneously hiding the "off" div - and then switch that around for every other date/time.
?
If you use PHP you can do logic statements on the server-side to render the exact information you need instead of calculating it later on the client side.
(Client side solutions work too if you dont care about where the time is coming from)
(1) You can have the server render javascript for you that you can use in a script
//if you want the server's time you can do this:
<?php $timestamp = time(); ?>
//render variables in javascript instead of html
<?php
echo <<<EOD
<script>
var timestamp = ${timestamp}
//then later in your javascript process the timestamp logic to update the dom
</script>
EOD;
?>
(2) You can also have the server render a className in the body tag based on whether or not a condition is true or false. (This is my preferred method usually)
//onAirClass( min, max, timestamp ) returns className
//this function returns onair or offair class if the timestamp is in range
function onAirClass( timeMin, timeMax, timestamp ){
if( timestamp >= timeMin && timestamp <= timeMax ){
return 'onair';
}
return 'offair'
}
//using onAirClass( min, max, timestamp )
<?php $bodyClass = $bodyClass . ' ' . onAirClass( $timestamp ); ?>
<?php echo "<body class='${bodyClass}'>"; ?>
then in your styles you can have the elements you want to hide or show based on class inheritance from the body tag.
Check out the PHP time function to create new time strings, and do time calculations for your onAirClass() function
How to check the time between a given time range
UPDATED
Corrected PHP syntax errors
#maerics solution is OK, depending on what you want to do, just don't EVER do anything like this:
var timestamp = $('#server-timestamp').text();
Ultimately, there are many ways to do the same thing, but some things are more 'right' than others.
There are reasons to do some calculations on the client side vs the server side, and vice versa. As a newbie developer, just make sure that whatever method you use:
is simple
is efficient (doesnt do anything unnecessary or redundant)
falls in line with best practices
Actually this can be accomplished using just JavaScript without any server-side code, by using your timezone offset.
Here's a function you can use:
var onAir = function (day, start, end, timezone) {
var local, utc, show, days, onAir, startValues, endValues, startTime, endTime, startMinutes, endMinutes, showMinutes;
// by default, we are not on air
onAir = false;
// map day numbers to indexes
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Firday', 'Saturday'];
// convert start/end times to date objects
startValues = start.split(':');
endValues = end.split(':');
startTime = new Date();
endTime = new Date();
startTime.setHours(startValues[0], startValues[1]);
endTime.setHours(endValues[0], endValues[1]);
// add the hours minutes together to get total minutes
startMinutes = (startTime.getHours() * 60) + startTime.getMinutes();
endMinutes = (endTime.getHours() * 60) + endTime.getMinutes();
// get the current local time
local = new Date();
// get the current time in the show's timezone
utc = local.getTime() + (local.getTimezoneOffset() * 60000);
show = new Date(utc + (3600000*timezone));
// convert the show hours + minutes to just minutes
showMinutes = (show.getHours() * 60) + show.getMinutes();
// test to see if the show is going on right now
if (days[show.getDay()] === day && (showMinutes >= startMinutes && showMinutes <= endMinutes)) {
onAir = true;
}
return onAir;
}
// example: Air time is Tuesday between 1-2pm Central Time (-6)
var texasShowOnAir = onAir('Tuesday', '13:00', '14:00', '-6'));
// now check if we are on air
if (texasShowOnAir) {
// do stuff here...
}
You can now use this function like this:
var check = onAir('DAY', 'STARTTIME', 'ENDTIME', 'YOURTIMEZONE');
This will return a true/false. Be sure and use 24 hour format.
I would even argue that this is better than using your server's timestamp, because often (especially if you have shared hosting), your server can be set in a different timezone than you.
Here's a demo fiddle: http://jsfiddle.net/stevenschobert/mv54B/
Have the server provide a timestamp when it generates the page and have the client also generate a timestamp when it loads the page so that you can calculate the time offset between the two systems.
Then you can call a function on some interval that checks the current server time to see if it is within the 3pm-4pm period and show/hide the target elements as needed.
From the server:
<div id="server-timestamp" style="display:none">2013-02-12T18:01:19Z</div>
On the client:
$(document).on('load', function() {
var serverTime = new Date($('#server-timestamp').text())
, clientTime = new Date()
, offsetMilliseconds = (clientTime - serverTime);
setInterval(function() {
// If server time is 3pm-4pm then hide/show divs...
}, 1000 /* every second */);
});
I have a quiz page with some questions (multiple choice, true-false). In the results after the submit of page i want to show something like this:
Started on Tuesday, 1 January 2013, 04:09 AM
Completed on Tuesday, 1 January 2013, 04:10 AM
Time taken 47 secs
Grade 7 out of a maximum of 10 (65%)
i dont know how to count start time and end time to show the above results and how to count the time from when user's load a page until they submit the form.
i'm new and i need your advise. i dont have problem if the problem solved with php or javascript or jquery
You can do something like this and the start and end timestamps will be submitted along with the form. You could then do the calculations with PHP.
var form = document.getElementById("form");
window.onload = function() {
var start = document.createElement("input");
start.type = "hidden";
start.name = "start";
start.value = +new Date()/1000; //unix timestamp
form.appendChild(start);
};
form.onsubmit = function() {
var stop = document.createElement("input");
stop.type = "hidden";
stop.name = "stop";
stop.value = +new Date()/1000;
form.appendChild(stop);
};
Ok here is my solution:
1- user starts the quiz and you put the time in $_SESSION var
$_SESSION['quiztime']=date("Y-m-d H:i:s");
2-User finishes the test and you check the time passed (this example is in minutes you don't have to divide it by 60 if you need seconds)
$to_time = strtotime(date("Y-m-d H:i:s"));
$from_time = strtotime($_SESSION['quiztime']);
echo round(abs($to_time - $from_time) / 60,2). " minutes";
I'd put the time started in a cookie or session, and then once they complete it, just subtract that time from the current time -- That's the time taken!
It may look like this:
Quiz page:
session_start();
$_SESSION['startTime'] = time();
// This is where the quiz would be displayed
Quiz results page:
session_start();
$totalTime = time() - $_SESSION['startTime'];
echo $totalTime;
My "bullet-proofer" solution would be to store the start time on the server, (in the session) associated with a unique id generated per-form and kept in an hidden field.
This way you prevent the user from tampering with it (he might change the unique id, but in that case the form would be invalid) and you don't depend on the client having javascript enabled.
<?php
$form_uuid = uniqid();
$_SESSION['quiz_start_time'][$form_uuid] = time();
Then, in your form, put something like this:
<input type="hidden" name="form_id" value="<?php print $form_uuid; ?>">
And in the form submit handler:
<?php
$form_uuid = $_POST['form_id'];
if (!isset($_SESSION['quiz_start_time'][$form_uuid])) {
// The user is trying to do something nasty (or the session just expired)
// Return something like a 400 error
}
else {
$start_time = $_SESSION['quiz_start_time'][$form_uuid];
// Do other form processing here..
}
I have a page that shows future events along with the date (server time).
I need some method to display the date in user time.
Example:
Oct, 26 13:48:23 (server)
Oct, 26 14:48:23 (user time (UTC +1)) -> event info
What I have so far:
<?php
$sql=mysql_query("SELECT * FROM table") or die("Come back later");
while($row=mysql_fetch_array($sql)) {
echo date('M, d H:i:s', strtotime ($row['date'])).' -> '.$row['info'];
}
?>
With the diffence I want to detect user timezone.
Thank you.
EDIT
I know I should not be using mysql_*
If you're ok with doing the conversion to the user's time zone in JavaScript, you could do the following:
PHP
<?php
$sql=mysql_query("SELECT * FROM table") or die("Come back later");
while($row=mysql_fetch_array($sql)) {
echo '<span class="date">' . date('M, d H:i:s', strtotime ($row['date'])) . ' UTC</span> -> '.$row['info'];
}
?>
JavaScript (With jQuery for Readability)
$(function(){
$('.date').each(function(){
var $this = $(this);
// Parse the date string (the format you've given will
// work, and the added UTC above will give JavaScript
// some context)
var dateVal = new Date($this.text());
// JavaScript will convert it to the user's timezone when
// stringifying it (helped by the server timezone specified
// in the PHP.
$this.text(dateVal.toString());
});
});
If you want to render the dates in the format: Oct, 26 13:48:23, you could do this:
var dateString = dateVal.toLocaleString();
var parts = /^\w+ (\w+ \d{1,2}) \d{4} (\d{2}:\d{2}:\d{2})/.exec(dateString);
dateString = parts[1] + ' ' + parts[2];
Then use $this.text(dateString); to inject it into the dom.
You need to create DateTime object from this date, and then apply DateTimeZone to that object.
You would need to get the timezone from the user.
You can accomplish this by offering a dropdown with timezones that the user can select and submit. To make this a little more user friendly you could use some of the geoip functions to detect country and region and then determine a default timezone for the user. Do keep in my that location by IP is not 100% accurate but is instead an educated guess as to where the user may be located.
Alternatively you can use ajax to send the timezone to the server and then update accordingly.