Parse formatted datetime expression and assign numbers to variables - php

I have this string from eBay Web-Service.
// 2Days 23Hours 37Minutes 50Seconds
$string = P2DT23H37M50S
I was using the following code to extract and time and date:
$daysLeft = substr($string, 1, 1) . " Days";
$hoursLeft = substr($string, 4, 2) . " Hours";
$minutesLeft = substr($string, 7, 2) . " Minutes";
$secondsLeft = substr($string, 10, 2) . " Seconds";
But the problem is, When the hours, minutes and dates are only 1 Digit, the strings gets all messed up, I had it working initially, but I'm kind of stuck to find a simple way to do it, I was going to write it in a bunch of If statements, but really want a more simple way to do this.

How about using sscanf (the opposite of sprintf)?
list($daysLeft, $hoursLeft, $minutesLeft, $secondsLeft) = sscanf($string, "P%dDT%dH%dM%DS ");

If you now that all fields always is there, just preg_split the string on non-numbers:
$fields = preg_split('[^0-9]+', $string);
$daysLeft = $fields[1] . " Days";
$hoursLeft = $fields[2] . " Hours";
$minutesLeft = $fields[3] . " Minutes";
$secondsLeft = $fields[4] . " Seconds";

Related

How can I make an array instead of calling date() 3 times?

$this_year = date('Y');
$days_this_year = 365 + date('L');
$day_number = date('z') + 1;
Can I make an array instead of calling date() 3 times? I tried a few times, but could not figure out the syntax I needed
This approach creates a string with the values separated by spaces and explodes it into an array.
$values = date('Y L z');
$items = explode(' ',$values);
echo 'Year: '.$items[0].PHP_EOL;
echo 'Days this year: '.($items[1]+365).PHP_EOL;
echo 'Day number: '.$items[2].PHP_EOL;
Try this
list($this_year,$days_this_year,$day_number) = preg_split("/[\s]/",date('Y L z'));
echo $this_year . PHP_EOL;
echo ($days_this_year + 365) . PHP_EOL;
echo ($day_number + 1) . PHP_EOL;
Probably not the most readable, but just for fun, here's a one-liner:
$array = array_map('array_sum', array_map('array_merge', [[0], [365], [1]], json_decode(date('[[Y],[L],[z]]'), true)));

Filter based on days of the week in a PHP foreach

I am getting from Facebook Graph API the last 3 months page views information from all the accounts that I am admin with the following method:
$since_date = date('Y-m-d', strtotime('-3 months'));
$until_date = date('Y-m-d');
$page_views = $facebook->api('/' . $account['id'] . '/insights/page_views?since=' . $since_date . '&until=' . $until_date . '','GET');
After that I am using a php foreach loop (actually two) to get the desired information (page views and the date) in a required format (an array) like this:
foreach ($page_views['data'] as $page_view) {
$i = 0;
$len = count($page_view['values']);
foreach($page_view['values'] as $key => $page_view_values) {
$end_time = strval($page_view_values['end_time']);
$value = intval($page_view_values['value']);
echo '[\'' . substr($end_time, 0, -14) . '\', ' . $value . ']';
if ($i == $len - 1) {
continue;
} else {
echo ', ';
}
$i++;
}
Which output for further needs the following array:
(.....],['2013-04-02', 21], ['2013-04-03', 7], ['2013-04-04', 2], ['2013-04-05', 0], ['2013-04-06', 2], ['2013-04-07', 3], ['2013-04-08', 1], ['2013-04-09', 2], ['2013-04-10', 5], ['2013-04-11', 1], ['2013-04-12', 11], ['2013-04-13', 0],[.....)
All is working like it should, with the above array. I render a very nice chart but I want to filter it if I could based on days of the week. For exemple: I want an array like the one above with only the dates from Monday or Tuesday and so on... I need to filter somewhere in the second php foreach to return only the days that I want but how? What condition is used for this kind of needs? Or I should use other method, for example, query something else from the Facebook Graph Api? Any guidance is more than welcomed.
You could do for example a switch case based on the 3-letter code of the week day, and do something like this for each day:
$tempDate = '2012-07-10';
echo date('D', strtotime( $tempDate));
It will output: Tue
This will allow you to filter by the week day. For example, you would only add to the array if the weekday code is Tue. All others will be skipped.
Added #arraintxo note:
date('N', strtotime($tempDate))
would return a numeric value of the week day (1 to 7, 1 being Monday and 7 Sunday), easier to compare.
I'd suggest something similar to the current reply, with slight adjustments:
$first=false; $cache=array(); $conv=new \Date('2000-01-01T00:00:00Z');
foreach ($page_views['data'] as $page_view) {
foreach($page_view['values'] as $key => $page_view_values) {
$end_time = strval($page_view_values['end_time']);
$ds=substr($end_time, 0, -14);
$value = intval($page_view_values['value']);
if(!isset($cache[$ds])
$cache[$ds]=(int)$conv->modify($ds)->format('N');
if($first){ echo ', '; $first=false; }
echo '[\'' . $ds . '\', ' . $value . ', '.$cache[$ds].']';
}
}
The day indices are now present as the third items of the arrays. Notice 1: a cache is used so that you look up every date only once. Notice 2: using a bool to not add leading separators is much cheaper than counting down from a count which is in turn cheaper than counting up to a count (what you did in the first place). Notice 3: This modifies the $conv object again and again, because I don't like creating many objects, and this ought to perform at least as well as the procedural style (date() and strtotime()).
In the first place I want to thank you all for the prompt replies, it was a great help received and I am very grateful for it. Based on your guidelines I solve my "issue" in the following manner:
$since_date = date('Y-m-d', strtotime('-3 months'));
$until_date = date('Y-m-d');
$page_views = $facebook->api('/' . $account['id'] . '/insights/page_views?since=' . $since_date . '&until=' . $until_date . '','GET');
foreach ($page_views['data'] as $page_view) {
$i = 0;
foreach($page_view['values'] as $key => $page_view_values) {
$end_time = strval($page_view_values['end_time']);
$ds = substr($end_time, 0, -14);
$value = intval($page_view_values['value']);
if (date('N', strtotime($ds)) != 1) {
continue;
} else {
if ($i==1) {
echo ', ';
}
$i=1;
echo '[\'' . $ds . '\', ' . $value . ']';
}
}
}
I can do this for every day of the week by using date('N', strtotime($ds)) for the corresponding number of the day. I receive the array that I want but if I can, i want to know if is possible to sum the numbers in the variables called $page_view_values['value'] (i want to make a comparison between the days in the week).

php - timestamp - interval between days not always 86400 seconds - why?

Supplementry Question to timestamp - php incrementing time stamp error
Whilst accepting that class DateTime may provide a resolution to my original query there remains the unexplained variance in the timestamps. I really would like to understand this variance, whether there are other such timestamp "adjustments" and how they arise.
Please consider the following:
/*
* test time stamp variances
*/
$time_Stamp_1 = mktime(0,0,0,10,15,2012);echo "15/10/12: " . $time_Stamp_1;
$time_Stamp_2 = mktime(0,0,0,10,16,2012);echo "<br/>16/10/12: " . $time_Stamp_2 . "increment= " . ($time_Stamp_2 - $time_Stamp_1);
$time_Stamp_3 = mktime(0,0,0,10,17,2012);echo "<br/>17/10/12: " . $time_Stamp_3 . "increment= " . ($time_Stamp_3 - $time_Stamp_2);
$time_Stamp_4 = mktime(0,0,0,10,18,2012);echo "<br/>18/10/12: " . $time_Stamp_4 . "increment= " . ($time_Stamp_4 - $time_Stamp_3);
$time_Stamp_5 = mktime(0,0,0,10,19,2012);echo "<br/>19/10/12: " . $time_Stamp_5 . "increment= " . ($time_Stamp_5 - $time_Stamp_4);
$time_Stamp_6 = mktime(0,0,0,10,20,2012);echo "<br/>20/10/12: " . $time_Stamp_6 . "increment= " . ($time_Stamp_6 - $time_Stamp_5);
$time_Stamp_7 = mktime(0,0,0,10,21,2012);echo "<br/>21/10/12: " . $time_Stamp_7 . "increment= " . ($time_Stamp_7 - $time_Stamp_6);
$time_Stamp_8 = mktime(0,0,0,10,22,2012);echo "<br/>22/10/12: " . $time_Stamp_8 . "increment= " . ($time_Stamp_8 - $time_Stamp_7);
$time_Stamp_9 = mktime(0,0,0,10,23,2012);echo "<br/>23/10/12: " . $time_Stamp_9 . "increment= " . ($time_Stamp_9 - $time_Stamp_8);
$time_Stamp_10 = mktime(0,0,0,10,24,2012);echo "<br/>24/10/12: " . $time_Stamp_10 . "increment= " . ($time_Stamp_10 - $time_Stamp_9);
$time_Stamp_11 = mktime(0,0,0,10,25,2012);echo "<br/>25/10/12: " . $time_Stamp_11 . "increment= " . ($time_Stamp_11 - $time_Stamp_10);
$time_Stamp_12 = mktime(0,0,0,10,26,2012);echo "<br/>26/10/12: " . $time_Stamp_12 . "increment= " . ($time_Stamp_12 - $time_Stamp_11);
$time_Stamp_13 = mktime(0,0,0,10,27,2012);echo "<br/>27/10/12: " . $time_Stamp_13 . "increment= " . ($time_Stamp_13 - $time_Stamp_12);
$time_Stamp_14 = mktime(0,0,0,10,28,2012);echo "<br/>28/10/12: " . $time_Stamp_14 . "increment= " . ($time_Stamp_14 - $time_Stamp_13);
$time_Stamp_15 = mktime(0,0,0,10,29,2012);echo "<br/>29/10/12: " . $time_Stamp_15 . "increment= " . ($time_Stamp_15 - $time_Stamp_14);
Reports:
15/10/12: 1350255600
16/10/12: 1350342000increment= 86400
17/10/12: 1350428400increment= 86400
18/10/12: 1350514800increment= 86400
19/10/12: 1350601200increment= 86400
20/10/12: 1350687600increment= 86400
21/10/12: 1350774000increment= 86400
22/10/12: 1350860400increment= 86400
23/10/12: 1350946800increment= 86400
24/10/12: 1351033200increment= 86400
25/10/12: 1351119600increment= 86400
26/10/12: 1351206000increment= 86400
27/10/12: 1351292400increment= 86400
28/10/12: 1351378800increment= 86400
29/10/12: 1351468800increment= 90000
Hence:
> 15/10/2012 1350255600 + 604800 does increment 1 week to 22/10/2012 ..
> 22/10/2012 1350860400 + 604800 does not increment 1 week to 29/10/2012
> because although this results in 1351465200 which should be 29/10/2012
> you can see from the above that it resolves to 28/10/2012 because for
> some unexplained reason an extra hour 3600sec has been added to the
> time stamp for 29/10/2012.
I want to know because from my reading of the documentation mktime should create a timestamp just as valid as say strtotime or DateTime.
Indeed using class DateTime method getTimestamp
28/10/2012 = 1351378800
29/10/2012 = 1351468800 an increment of 90000
So once again an hour has been added implying that I am correct in this assumption.
Obviously the class can deal with this. BUT no where up until this point has there been any mention of the fact that incrementing a timestamp however it is generated could result in an issue... thus making the use of the DateTime class or another approach mandatory to avoid issues such as have been encountered.
If I have to convert the code you use the class so be it. But I would like to know why this is necessary.
Due to a daylight savings shift, 28/10/12 has an extra hour in your timezone. There are 25 hours between midnight 28/10 and midnight 29/10.
You will also find a day with 23 hours in spring.
If this is not what you expect, change the timezone to something that has no DST. UTC is one option:
php > echo mktime(0,0,0,10,29,2012) - mktime(0,0,0,10,28,2012);
90000
php > ini_set('date.timezone', 'UTC');
php > echo mktime(0,0,0,10,29,2012) - mktime(0,0,0,10,28,2012);
86400
I'm going to take a stab at this. October 29th is exactly 1 week before daylight savings time (unless you are in a country with a different daylight savings time). But falling back 1 hour would cause a day to have 1 more hour.

Schedule Post - Displaying Some Content only for Some time or any time in future or Repitative

I am trying to display some content only for some time or some days
I have start time, start date, end time and end date in database so that when the data is fetched from database this time and dates should be checked and display the content accordingly
My code that i have tried
$startDateTime = strtotime($result['StartDate']." ".$result['StartTime']);
$endDateTime = strtotime($result['EndDate']." ".$result['EndTime']);
$now = time();
echo "START : ".$startDateTime;
echo "<br/>END : ".$endDateTime;
echo "<br/>CURRENT : ".$now;
if($now >= $startDateTime && $now <= $endDateTime){
echo $result['content'];
}
But its not working its displaying the content every time
Please Help Me
Thanks in advance
output a list of your $result['StartDate']." ".$result['StartTime'] I think you'll find that it might be leaving off leading 0's or something which would give it trouble casting it as a time.
Rather than using the time() function - try creating '$now' as strtotime("now").
Also, as a debugging step, it probably would have helped you to echo the comparisons to see if they evaluated the way that you expected.
Actually - I just tried your code exactly as it was...Except that I had hard coded values for the starting and ending dates and times. And it worked, so switching to use strtotime("now") will probably not make a difference.
What are the values that were printed out? You didn't tell us.
So VoronoiPotato is probably right...The values you are storing for StartDate/StartTime and EndDate/EndTime must have something wrong with them.
What is the output of your program if you change it like this (to add more debugging):
$startDateTime = $result['StartDate'] . " " . $result['StartTime'];
$endDateTime = $result['EndDate'] . " " . $result['EndTime'];
$now = time();
echo "START : " . $startDateTime."<br />\n";
echo "END : " . $endDateTime . "<br />\n";
$startDateTime = strtotime($startDateTime);
$endDateTime = strtotime($endDateTime);
echo "Start as time: " . $startDateTime . "<br />\n";
echo "End as time: " . $endDateTime . "<br />\n";
echo "CURRENT : " . $now . "\n";
if (($now >= $startDateTime) && ($now <= $endDateTime)) {
echo $result['content'];
}

Efficient way to parse "ddmmyyyyThhmm" string to workable date string

I have the following types of strings:
17082011T1015
In other words: day month year T hours minutes.
What would be an efficient way to parse these strings in such a way that I end with something like a MySQL-like date:
`2011-08-17 10:15`
(There's no MySQL involved here by the way)
It's for Windows PHP < 5.3 so strptime() and date_parse_from_format()/DateTime::createFromFormat() are NOT an option.
It's just rearranging a string.
$date = "17082011T1015";
$day = substr($date, 0, 2);
$month = substr($date, 2, 2);
$year = substr($date, 4, 4);
$hour = substr($date, 9, 2);
$minute = substr($date, 11, 2);
echo $year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute;
I think I'll end up using this solution:
sscanf( '17082011T1015', '%02s%02s%04sT%02s%02s', $day, $month, $year, $hours, $minutes );
$datetime = $year . '-' . $month . '-' . $day . ' ' . $hours . ':' . $minutes;
Before asking the question I didn't realize I could utilize the optional arguments to sscanf() to my advantage, and thought I would have to resort to something like this:
$parsed = sscanf( '17082011T1015', '%02s%02s%04sT%02s%02s' );
$datetime = $parsed[ 2 ] . '-' . $parsed[ 1 ] . '-' . $parsed[ 0 ] . ' ' . $parsed[ 3 ] . ':' . $parsed[ 4 ];
Not too bad either, but I like to be pretty clear as possible with named variables, so that it's obvious what this little routine does.
If you are using PHP >= 5.3.0, you may use DateTime::createFromTimeFormat to create ordinary DateTime object from that string.
Should be something like:
$str = "17082011T1015";
$date = DateTime::createFromFormat($str,'DDMMYYYYThhII');
echo $date->format("Y-m-d H:i:s");
Can't test it here, only have PHP 5.2. But I think you could figure the right format yourself.

Categories