How do I rotate an image at 12 midnight every day? - php

I need to rotate an image at 12 midnight every day from a group of 5-10 images. How can I go about doing this with JavaScript or jQuery or even PHP?

At a basic level what you want to do is define an array of image names then take the number of days from a given point in time then modulo (remainder after division) by the number of images and access that index in the array and set the image, e.g. (untested code)
var images = new Array("image1.gif", "image2.jpg", "sky.jpg", "city.png");
var dateDiff = new Date() - new Date(2008,01,01);
var imageIndex = Math.Round(dateDiff/1000/60/60/24) % images.length;
document.GetElementById('imageId').setAttribute('src', images[imageIndex]);
Bear in mind that any client-side solution will be using the date and time of the client so if your definition of midnight means in your timezone then you'll need to do something similar on your server in PHP.

Maybe I don't understand the question.
If you just want to change the image write a batch file/cron job and have it run every day.
If you want to display a certain image on Monday, and a different one of Tuesday then do something like this:
<?php
switch(date('w'))
{
case '1':
//Monday
break;
case '2':
//Tuesday:
break;
...
}
?>

I'd do it on first access after midnight.

It doesn't even have to be in cron:
<?php
// starting date for rotation
$startDate = '2008-09-15';
// array of image filenames
$images = array('file1.jpg','file2.jpg',...);
$stamp = strtotime($startDate);
$days = (time() - $stamp) / (60*60*24);
$imageFilename = $images[$days % count($images)]
?>
<img src="<?php echo $imageFilename; ?>"/>

Edit: I totally misread this question as "without using javascript/PHP". So disregard this response. I'm not deleting it, just in case anyone was crazy enough to want to use this method.
Doing it without Javascript, PHP, or any other form of scripting language could be difficult. Well actually, it would just be very contrived, since it would be trivial with even the most basic JS/PHP.
Anyway, to actually answer your question, the only way I can think of doing it with vanilla HTML is to set up a shell script to run at midnight. That script would just rename your files. Do this with cron (on linux) or Windows Task Scheduler with a script kinda like this: (dodgy pseudo code follows, convert to whatever you're comfortable with).
let number_of_files = 5
rename current.jpg to number_of_files.jpg
for (x = 2 to number_of_files)
rename x.jpg to (x-1).jpg
rename 1.jpg to current.jpg
In your HTML, just do this:
<img src="path/to/current.jpg" />
And every day, current.jpg should change to something new. If you're using any sort of cache-control, make sure to change it so that it doesn't get cached for longer than a few hours.

If you are running a linux system you can set a Cron Job or you can use the windows task scheduler if you are on windows

You have two options.
In JavaScript, you basically have it choose an image based on the day of the week or day of the month if you have more than 7 images. Day of the month modulo by the length of the image array should let you pick the right array element.
You need something a bit more stateful to track what's going on... using SQL you can track when images are used and pick from the rotating list. You could also use a text file maintained by PHP to track the ordered list.
The old school way is to have a cron job rotate the image, but I'd avoid that these days.

That depends on how you are rotating them - sequentially, randomly, or what?
There are a number of options. You can determine which image you want in PHP, and dynamically change your <img> element to point to the correct location. This is best if you are already generating your pages dynamically.
You can always point to a single URL, which is a PHP file that determines which image to show and then performs a 302 redirect to it. This is better if you have static pages that you don't want to incur the overhead of dynamic generation for.
Don't make the image URL itself serve different images. You'll screw up your cache hit ratio for no good reason and incur unnecessary overhead on what should be a static resource.
Martin, "rotate" in this context means "change on a regular basis", not "turn around an axis".

It depends (TM) on what exactly you want to achieve. Just want to display a "random" image? Maybe this javascript snippet will get you started:
var date = new Date();
var day = date.getDate(); // thats the day of month, use getDays() for day of week
document.getElementById('someImage').src = '/images/foo/bar_' + (day % 10) + '.gif';

I assume by "rotate image" you mean "change the image in use" and not "rotational transformation about an axis" -- a simple way is to have a hash table that maps day modulo X to an image name.
$imgs = array("kitten.jpg", "puppy.gif","Bob_Dole.png");
$day_index = 365 * date("Y") + date("Z")
...
<img src="<? $imgs[$day_index % count($imgs)] ?>" />
(sorry if I got the syntax wrong, I don't really know PHP))

Set up a directory of images.
Select seven images and name them 0.jpg, 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, 6.jpg,
Using mootools Javascript framework with an image tag in HTML with id "rotatingimage":
var d=new Date();
var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
var offset = -10; // set this to your locale's UTC offset
var desiredTime = utc + (3600000*offset);
new dd = new Date(desiredTime);
$('rotatingimage').setProperty('src', dd.getDay() + '.jpg');

Here's a solution which will choose a random image per day from a directory, which might be easier than some other solutions posted here, since all you have to do to get something into the rotation is upload it, rather than edit an array, or name the files in arbitrary ways.
function getImageOfTheDay() {
$myDir = "path/to/images/";
// get a unique value for the day/year.
// 15th Jan 2008 -> 10152008. 3 Feb -> 10342008, 31 Dec -> 13662008
$day = sprintf("1%03d%d", date('z'), date('Y'));
// you could of course get gifs/pngs as well.
// i'm just doing this for simplicity
$jpgs = glob($myDir . "*.jpg");
mt_srand($day);
return $jpgs[mt_rand(0, count($jpgs) - 1)];
}
The only thing is that there's a possibility of seeing the same image two days in a row, since this picks it randomly. If you wanted to get them sequentially, in alphabetical order, perhaps, then use this. (only the last two lines are changed)
function getImageOfTheDay() {
$myDir = "path/to/images/";
$day = sprintf("1%03d%d", date('z'), date('Y'));
$jpgs = glob($myDir . "*.jpg");
return $jpgs[$day % count($jpgs)];
}

How to rotate the images has been described in a number of ways. How to detect when to trigger the rotate depends on what you are doing (please clarify and people can provide a better answer).
Options include:
Trigger the rotate on 'first access after midnight'. Assumes some sort of initiating event (eg user access)
Use the OS scheduling capabilities to trigger the rotate (cron on *nix, at/task scheduler on Windows)
Write code to check time & rotate
Option 3 has the risk that a poorly coded solution could be overly resource intensive.

Related

Find how many minutes old a file is

First of all, I know I am not supposed to as "code sample" here. Sadly, I am not a programmer and I have a situation where I need to update a line in a report to present to the customer, but I do not know how to do it.
I have access to PHP file report.php. In the same server and folder as report.php there is a file called report.csv. When report.php is loaded in browser, I want to show one line which will say:
Report.cvs is X minutes old that is all.
If the report is 10 days old, then also I can show the age in minutes. I dont need any complicated X days, Y hours, Z mins etc.
I am worried i might break something in server if I try to add myself since I am not programmer. Is there anyone who can show me what I need to add to report.php to make this work?
Looking through the documentation http://php.net/manual/en/function.fstat.php you might find that filectime ( string $filename ) may be useful.
Now if the file is consistently updated by users you may find that storing the creation/upload time in a Database like SQL/sqlite may be useful.
Ok so basically you need to get the time when the file was last modified, subtract it from the current time, convert the result to minutes and voilĂ .
Here's what that should look like:
$file = ''; // --- Path to the file
$filetime = filemtime($file); // --- File time
$now = time(); // --- Current Time
$fileAge = round(($now - $filetime)/60); // --- Subtract file time from current time, divide by 60 for the minutes and round the result.
echo basename($file).' is '.$fileAge.' minutes old.';

How to create a PHP script that will generate new text daily?

I've researched this a lot but can't find a satisfactory answer; how do I create a PHP script that will generate a new number each day? Obviously I'm using this for a reason other than to generate a random number daily, but I won't go into that reason, it'll just make this question more complicated. So I'm asking this: How do I generate a random number which will change each day in PHP? Using MySQL will be no problem, but it must be automatic so I won't have to manually change it daily. (Here's my 'script' to generate a random number)
<?php
echo rand(1,100)
?>
Any answers are appreciated, Thanks
- Hugh
Use time() function to generate seed, then use regular rand.
This way you should't to store it anywhere and you always can regenerate it when needed.
function randomEveryDay()
{
$now = time();
$today = $now - ($now % 86400); //86400 = 1 day in seconds
srand($today);
return rand();
}
Or more interesting example without random at all.
function randomEveryDay() {
$now = time();
$today = $now - ($now % 86400);
$hash = sha1('salt string'.$today);
return intval('0x' . substr($hash, 6, 8));
}
Every day you will get the same number in $today, then use any cryptographic\non cryptographic hash function to generate "random".
This is fairly a simple task as long as you understand the basics of crontabs.
Step One: Create the script. This is basically going to be what creates the "text" then inputs it into the database via mysqli. For example, if we are generating a random number, what you have so far is good, you will just need to insert it into a database table. I recommend using a time stamp to give what day it was generated on
Step Two: Create a cronjob. Use the servers crontab to run a task every day, this can be done by adding this to the cron file: This will run a cron each new day.
00 01 * * * php path/to/your/generate.php
Step Three Fetch result from database by using the current date. If you are needing to display that text, pull it from the database using whatever the current day is from date() or DateTime
It's impossible to give a good answer without knowing exactly what you want to do, so this will generate a new number every day:
echo date('Ymd');

PHP server side incremental counter

sorry I am new to PHP and need some help/guidance on creating a counter that will work server side, so I guess update an initial value?
I need for example to start with a base number of 1500 and have that number increase by 1 every 2 minutes, obviously so any visitors will see an increased number each time the visit.
Would the initial value need to be stored in sql or can a txt file be updated?
Any help would be great,
Thanks
It can be done in SQL if you want it but a text file is OK too, just save a value (1500), then create a cronjob and let it execute a PHP file where you'll have to set up the code that executes an SQL query which updates that value OR the code to update that text file every 2 minutes.
Example:
# Every two minutes
*/2 * * * * /your/path/too/this/file/updatecode.php
In your PHP file:
$SQL = "UPDATE table SET columnname = columname + 1";
// etc...
// OR the text file update code
If you don't need to store it specifically for some reason, then you don't need to run cron etc... Take a time stamp of a specific point in time you want to start at. Then calculate minutes since and add it to your start number (1500)
//Start Number
$n = 1500;
$cur_time = time();
$orig_time = strtotime("2013-10-21 10:00:00");
//New Number + difference in minutes (120 seconds for 2 mins) since start time
$newn = $n + round(abs($cur_time - $orig_time) / 120,0);
// Output New Number
echo $newn;
And if you wanted it in one line for copy/paste
echo 1500 + round(abs(time() - strtotime("2013-10-21 10:00:00")) / 120,0);
You could do this without a database just using dates. work out the difference in time between two dates (the current date and the starting date when you created the script), then divide that down into the correct amount of milliseconds for 2 minutes, and add that to your initial 1500.
If storing it is needed a SQL database for this is probably overkill.
Create you number, serialize it and store it to a file. Load it from the file next time, unserialize, increment, serialize and save.
You can save a time stamp along with the number to the file to avoid having to run some job every 2 minutes and instead calculate the correct value when you load the number back from the file.
Something like this (but error checking etc should be added and I haven't actually tried it to make sure the calculation is correct... but the main idea should be visible).
<?php
if(file_exists('mydatafile')) {
$data = unserialize(file_get_contents('mydatafile'));
// Calculate correct value based on time stamp
$data['number'] += round((time() - $data['timestamp']) / 120);
}
else {
// Init the number
$data["number"] = 1500;
}
// Print it if you need to here
// Update time stamp
$data["timestamp"] = time();
// Serialize and save data
file_put_contents('mydatafile', serialize($data)));

Split a time range into pieces by other time ranges

I have a complicated task that I have been beating my head against the wall now for a few days. I've tried about 4 different approaches, however each seems to stall and it is becoming extremely frustrating.
I have a time range. For example, 14:30:00 until 18:30:00. Consider this time range somebody's work shift. During this time range, they state they cannot work from 15:30:00 until 16:30:00 and from 17:30:00 until 18:30:00. I need to modify the original shift's start and end times to remove the conflicting shifts.
The original shift array looks like this:
$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '18:30:00';
And the time ranges to be removed from the original shift look like this:
$subshift[0]['start'] = '15:30:00';
$subshift[0]['end'] = '16:30:00';
$subshift[1]['start'] = '17:30:00';
$subshift[1]['end'] = '18:30:00';
Here is a visualization:
So, I basically need my original shift to look like this when I'm done:
$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '15:30:00';
$original_shift[1]['start'] = '16:30:00';
$original_shift[1]['end'] = '17:30:00';
Some complications that I also need to consider are:
These time ranges may be any times (not constrained to the half hour as I have used in my example), however I will know with 100% certainty the the unavailable time ranges will always start and end on or in between the original shift's start and end times.
Unavailable times may butt up and/or take the entire original shift's time up.
I'm not looking for someone to "write my code" as much as I am looking for someone who has dealt with something like this in the past and may have some insight on how they accomplished it.
As you specifically asked for "some insight" rather than a full working answer, I'd personally go with arrays populated with "minutes".
$shift = array(
'start' => '15:30:00',
'end' => '18:30:00',
'original' => array(),
'unavailable' => array(),
'modified' => array()
);
You'd then do some jiggery pokery to convert 15:30:00 into 930 and 18:30:00 into 1110 (number of minutes) which will give you the difference between start and end times.
Use range() to quickly fill up the original array, load in your unavailable in a similar format and then use things like array_intersect() and array_diff() to work out which minutes from the original shift are unavailable.
From that, build up the modified array, and read directly from there to your output.
You need to do calculations of time-ranges. As the image shows this seems like a simple subtraction. It would be nice to just have objects that do these.
I had no code for this ready, so the following concept is a bit rough although probably not that bad.
A Range type that represents a time from-to. Those are as DateTime so that the benefits of these existing types can be used. I didn't use much of the benefits so far, however for the rest of the application this can make sense.
The Range type already contains some basic comparison methods I thought were useful to do parts of the calculations.
However as an object can not divide itself into two I also created a Ranges type which can represent one or more Ranges. This was necessary to have something that can be "divided".
I cheated a little here because I implemented the difference calculation as a member of Range, returning an array with one or multiple Range objects. The final calculation then is just having a shift and substract the unavailable ranges from it:
$shift = new Ranges(new DateTime('14:30:00'), new DateTime('18:30:00'));
$unavailables = new Ranges([
new Range(new DateTime('15:30:00'), new DateTime('16:30:00')),
new Range(new DateTime('17:30:00'), new DateTime('18:30:00')),
]);
$shift->subtract($unavailables);
The shift then spans:
14:30:00 - 15:30:00
16:30:00 - 17:30:00
Demo; Gist
I can not say if it is worth the abstraction, what is nice with DateTime objects is that you can compare them with >, < and =. The real benefit from these classes might shed into light when you need more calculations between Range and Ranges. Maybe the interface is not sweet yet, however the basic calculations behind are outlined in the code already.
One caveat: The difference between 14:00-15:00 and 14:00-15:00 in my code will result to 14:00-14:00. I keep the start time to not run empty, but you can run empty, too. The Ranges object should handle it nicely.
The code should speak for itself:
$original_shift[0]['start'] = '14:30:00';
$original_shift[0]['end'] = '18:30:00';
$breaks[0]['start'] = '14:30:00';
$breaks[0]['end'] = '15:30:00';
$breaks[1]['start'] = '16:30:00';
$breaks[1]['end'] = '17:30:00';
$modified_shift = array(
array('start' => $original_shift[0]['start'])
);
for($x = 0, $y = count($breaks), $z = 0; $x < $y; $x++){
$modified_shift[$z]['end'] = $breaks[$x]['start'];
if($modified_shift[$z]['end'] != $modified_shift[$z]['start']){
$z++;
}
$modified_shift[$z]['start'] = $breaks[$x]['end'];
}
$modified_shift[$z]['end'] = $original_shift[0]['end'];
if($modified_shift[$z]['end'] == $modified_shift[$z]['start']){
unset($modified_shift[$z]);
}

PHP image hourly

I have a PHP file that randomly generates an image from a folder on every refresh. I downloaded it from here (which also has an explanation).
Instead of randomly choosing images, how can I have it change the image hourly? For example, I would like it have the same image for an hour, and then change when that hour is up. Basically, a new image based on some time interval.
Thanks for the help.
Find line
$imageNumber = time() % count($fileList);
And replace it with
$imageNumber = (date(z) * 24 + date(G)) % count($fileList);
That should work for you.
I'd say you need a random oracle function. Basically, it's a random() function that takes an input and generates a random number, with the guarantee that all calls with the same input will give the same output.
To create the value you pass into the oracle, use something that'll change hourly. I'd use julian_day_number * 24 + hour_number or something of that variety (just hour_number isn't good enough, as it'll repeat itself every 24 hours).
Then, whenever your page loads, generate your hour number, pass it through your oracle, and use the result just like you use your random value now. It'll still appear random, and it'll change once an hour.
Hope that helps!
Edit: Random oracles don't need to be fancy - they can be as simple as (stolen blatantly from this answer to a different question):
int getRand(int val)
{
//Not really random, but no one'll know the difference:
return ((val * 1103515245) + 12345) & 0x7fffffff;
}
Keeping it simple, put 8 different pics in img/ named from 1.jpg to 8.jpg, then:
$imagePath = sprintf("img/%s.jpg", (date('G') %8) +1);
with G param being:
24-hour format of an hour without leading zeros.
Now you are sure that you have a different pic every hour, and everybody sees the same.
EDIT: narrow or widen the repetition period adjusting modulo, 24 has a few divisors [1, 2, 3, 4, 6, 8, 12].

Categories