|
Page 1 of 1 |
|
Posted: Wed, 18th Mar 2015 11:18 Post subject: [php] Find the closest date to today from given info |
|
 |
This problem is killing me. I know what to do in theory, but I cannot execute it properly, and I'm wasting time.
A client has a training website, and we have a plugin that creates the training dates etc. All this is in custom post type (wordpress). So I can query it, get the id of the posts and all the goodies inside.
But the big problem, that I cannot pass, are dates. The dates of the trainings are in this format:
Code: |
2015-06-15T13:00:00Z | 2015-06-15T17:00:00
2015-06-16T13:00:00Z | 2015-06-16T21:00:00
2015-06-17T13:00:00Z | 2015-06-17T21:00:00
or
1/19/2015 9:00 AM | 1/19/2015 4:00 PM
1/20/2015 9:00 AM | 1/20/2015 4:00 PM
1/21/2015 9:00 AM | 1/21/2015 4:00 PM
|
So i created a while loop that goes through posts, and I created array for each post that contains id and date like this
Code: | Array
(
[2885] => 2015-05-26T15:00:00Z | 2015-05-26T16:00:00Z
2015-05-27T15:00:00Z | 2015-05-27T16:00:00Z
2015-05-28T15:00:00Z | 2015-05-28T16:00:00Z
2015-05-29T15:00:00Z | 2015-05-29T16:00:00Z
) |
The key is the post id, and the value are the dates.
The goddamn date is killing me. It needs to be in this stupid format for some reason (some other plugin is using it or something like this).
So I can get the dates, but what I need is basically to separate this stupid string with regex or something from this
Code: | 2015-05-26T15:00:00Z | 2015-05-26T16:00:00Z
2015-05-27T15:00:00Z | 2015-05-27T16:00:00Z
2015-05-28T15:00:00Z | 2015-05-28T16:00:00Z
2015-05-29T15:00:00Z | 2015-05-29T16:00:00Z |
to this
Code: | 2015-05-26
2015-05-27
2015-05-28
2015-05-29 |
And then from these find the lowest one (this can be converted to unix timestamp).
Once I have this, I could create new array that has the keyes that are id's of posts and values are lowest date from that post.
Then I need to find which of these is the most recent one (the one closest to the current date given with time()). With this I can then retrieve the id of that post, and from that it's a piece of cake, since I can then pull all the necessary info I'll output on the frontend.
So any help on how to get the array that has post id associated with the lowest time of that post?
What I need I guess is a way to get the unix date. That is from string like this
Code: | 2015-05-26T15:00:00Z | 2015-05-26T16:00:00Z
2015-05-27T15:00:00Z | 2015-05-27T16:00:00Z |
get the first part - regex that will get first 10 characters of one line is
, but I don't know how to get first 10 characters of every line. I should explode the date, with it then implode...
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
|
Posted: Wed, 18th Mar 2015 12:09 Post subject: |
|
 |
Your regex is correct, but add /m option to the end of it (this means that ^ will match start of each line, instead start of the entire string), and use preg_match_all (or whatever it's called, my php knowledge is rusty)
Otherwise you could just explode the string using a newline as the separator, and then use your regex individually on each of the pieces (i.e. lines).
|
|
Back to top |
|
 |
|
Posted: Wed, 18th Mar 2015 12:22 Post subject: |
|
 |
Yeah, boss said: just explode it with "\r\n", then loop again, and explode at "|" and then strtotime works.
Love how when you know what you're doing (my boss) you do something in like a minute ... *feels stupid as fuck*
Thnx Bearish 
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
Werelds
Special Little Man
Posts: 15098
Location: 0100111001001100
|
Posted: Wed, 18th Mar 2015 12:27 Post subject: |
|
 |
Code: |
// I assume dates are in $dates for demo purposes, change that to wherever you keep it obviously
// Oldest = infinity ;)
$oldest = INF;
// Split into separate lines
foreach(explode("\n", $dates) as $line) {
// Now split the first and second part of each line; I assume this is some start/end date pair
foreach (explode(" | ", $line) as $date) {
// Simple mathematical minimum determination
// strtotime() takes any date string and converts it to UNIX timestamp
// And because we set $oldest to infinity at first, the first timestamp will work too
$oldest = min($oldest, strtotime($date));
}
}
// $oldest now holds the oldest UNIX timestamp, so you can just do this for example:
echo date('Y-m-d H:i:s', $oldest);
|
There
Edit: not a single line is tested of course, but you get the idea 
|
|
Back to top |
|
 |
|
Posted: Wed, 18th Mar 2015 12:46 Post subject: |
|
 |
This is basically what I'm working on, I just have one question:
Code: |
$post = new WP_Query( $args );
$current_time = time();
if ($post->have_posts()){
while ($post->have_posts()){
$post->the_post();
$id = get_the_ID();
$custom = get_post_custom($id);
$date = $custom["gtt_training_dates"][0];
$times = explode("\r\n", $custom['gtt_training_dates'][0]);
foreach ($times as $time) {
if ($time != ''){
$session_time = explode(" | ", $time);
$train_date = strtotime($session_time[0]);
}
}
$training_array[$id] = $train_date;
}
}
|
$times will give array of times with |, then I go with them in foreach and explode further to values without |, which I convert to unix time with strtotime. But the issue is since I'm just equating my variable, when i create an array
Code: | $training_array[$id] = $train_date; |
I'm getting the last date, and I want to get the first one.
So $times will give from this
Code: |
2015-05-26T15:00:00Z | 2015-05-26T16:00:00Z
2015-05-27T15:00:00Z | 2015-05-27T16:00:00Z
2015-05-28T15:00:00Z | 2015-05-28T16:00:00Z
2015-05-29T15:00:00Z | 2015-05-29T16:00:00Z
|
to this:
Code: |
Array(
[0] => 2015-05-26T15:00:00Z | 2015-05-26T16:00:00Z,
[1] => 2015-05-27T15:00:00Z | 2015-05-27T16:00:00Z,
[2] => 2015-05-28T15:00:00Z | 2015-05-28T16:00:00Z,
[3] => 2015-05-29T15:00:00Z | 2015-05-29T16:00:00Z,
[4] =>
|
Then with foreach I can get the values, and explode those to timestamps, but = always returns the last date, so in the end I'm getting unix date from 2015-05-29T15:00:00Z, and I need 2015-05-26T15:00:00Z.
Is there a way to get that? I tried set delayed .= but that was messy, I should probably try to target only the first $time, but how exactly?
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
|
Posted: Wed, 18th Mar 2015 12:51 Post subject: |
|
 |
Look at werelds post. you have to go through EACH of your lines in that array and do the explode.
|
|
Back to top |
|
 |
|
Posted: Wed, 18th Mar 2015 13:03 Post subject: |
|
 |
PumpAction wrote: | Look at werelds post. you have to go through EACH of your lines in that array and do the explode. |
Tried that but didn't get what I needed :\
EDIT: If I use
foreach($array as $key => $value){}
Can I target only first key somehow? The [0] one?
EDIT2: I can! if($key == 0) 
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
Werelds
Special Little Man
Posts: 15098
Location: 0100111001001100
|
Posted: Wed, 18th Mar 2015 13:34 Post subject: |
|
 |
Yeah, but that would be counter productive. In theory you could have an array with millions of entries and you'd still iterate over each of them.
Instead, store the explode() result in a variable and reference [0] directly. Here's some cleaned up code for you, with the minimal date calculation included again:
Code: |
$post = new WP_Query( $args );
$current_time = time();
if ($post->have_posts()){
while ($post->have_posts()){
$post->the_post();
$id = get_the_ID();
$custom = get_post_custom($id);
$date = $custom["gtt_training_dates"][0];
$train_date = INF;
$times = explode("\r\n", $custom['gtt_training_dates'][0]);
foreach ($times as $time) {
if (empty($time)) {
continue;
}
$session_time = explode(" | ", $time);
$train_date = min($train_date, strtotime($session_time[0]));
}
$training_array[$id] = $train_date;
}
}
|
The whole key to what you're trying to do is in that min() call and you omitted that 
|
|
Back to top |
|
 |
|
Posted: Wed, 18th Mar 2015 21:49 Post subject: |
|
 |
I got what I need in the end. I'll see tomorrow at work, about your tweaks, but in the end I got what I needed
Thanks for the help 
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
|
Posted: Thu, 19th Mar 2015 08:19 Post subject: |
|
 |
I did it like this (it works so I'm afraid to change it xD)
Code: |
$post = new WP_Query( $args );
$current_time = time();
if ($post->have_posts()){
while ($post->have_posts()){
$post->the_post();
$id = get_the_ID();
$custom = get_post_custom($id);
$dates = $custom["gtt_training_dates"][0];
$times = explode("\r\n", $dates);
foreach ($times as $key => $time) {
if ($key == 0){
$session_time = explode(" | ", $time);
$train_date = strtotime($session_time[0]);
}
}
$training_array[$id] = $train_date;
}
}
natsort($training_array);
foreach($training_array as $k => $time) {
if( $time < $current_time ) {
continue;
} else {
$key = $k;
break;
}
}
$next_training_id = $key;
|
I'll try to implement your method and see if it'll work (it probably will)
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
Werelds
Special Little Man
Posts: 15098
Location: 0100111001001100
|
Posted: Thu, 19th Mar 2015 09:27 Post subject: |
|
 |
Here's a minimal version of your code:
Code: | <?php
$post = new WP_Query( $args );
$first_timestamp = INF;
if ($post->have_posts()){
while ($post->have_posts()){
$post->the_post();
$id = get_the_ID();
$custom = get_post_custom($id);
$times = explode("\r\n", $custom["gtt_training_dates"][0]);
$first_timestamp = min($first_timestamp, $times[0]);
}
} |
I quietly assumed you don't actually need $training_array since I don't see that used for anything other than your sorting.
And yeah, your method takes about 3 times as long as it needs to
When looping over $times you ignore 50% of the entries, that loop is completely pointless. Then you do a recursive loop (that's what natsort() is internally, as any sorting method is) followed by another regular loop 
|
|
Back to top |
|
 |
|
Posted: Thu, 19th Mar 2015 10:05 Post subject: |
|
 |
Training array is used for sorting, that is I'm putting the id of posts, and the most recent date I have in that array, then use it for comparison, to get the id of the post that has the time closest to today, so that I can pull info out of that post.
EDIT: Your loop returns the earliest date of post even if it was in the past (I don't need training that happened in December 2014). I need the post that is next to happen 
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
Werelds
Special Little Man
Posts: 15098
Location: 0100111001001100
|
Posted: Thu, 19th Mar 2015 10:30 Post subject: |
|
 |
Updated for you then:
Code: | <?php
$post = new WP_Query( $args );
$first_timestamp = INF;
if ($post->have_posts()){
while ($post->have_posts()){
$post->the_post();
$id = get_the_ID();
$custom = get_post_custom($id);
$lines = explode("\r\n", $custom["gtt_training_dates"][0]);
$times = explode(" | ", $lines);
$ts = strtotime($times[0]);
$first_timestamp = max(time(), min($first_timestamp, $ts));
}
} |
I actually forgot an explode and the strtotime() call before too. And you yourself don't seem to be splitting by the pipe (|) anymore either? I added both back in. Still omitting $training_array since you just said you only used it to figure out this timestamp, so we don't need it at all.
So what this does (after the necessary exploding ):
- Compare the timestamp from the date we're looking at to our "earliest" saved timestamp; lowest of the 2 gets selected, which may or may not be before present time
- Compare the newly acquired earliest timestamp to the current time and select the highest value, this ensures that all selected timestamps are in the future
The last bit could be achieved with an if statement, but this is faster 
|
|
Back to top |
|
 |
|
Posted: Thu, 19th Mar 2015 11:59 Post subject: |
|
 |
You exploded an array with
Code: |
$lines = explode("\r\n", $custom["gtt_training_dates"][0]);
$times = explode(" | ", $lines);
|
Exploding array, is that even possible?
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
Werelds
Special Little Man
Posts: 15098
Location: 0100111001001100
|
Posted: Thu, 19th Mar 2015 12:04 Post subject: |
|
 |
Whoops, that should've been inside a loop, goddamned.
Code: | <?php
$post = new WP_Query( $args );
$first_timestamp = INF;
if ($post->have_posts()){
while ($post->have_posts()){
$post->the_post();
$id = get_the_ID();
$custom = get_post_custom($id);
$lines = explode("\r\n", $custom["gtt_training_dates"][0]);
foreach ($lines as $line) {
$times = explode(" | ", $line);
$ts = strtotime($times[0]);
$first_timestamp = max(time(), min($first_timestamp, $ts));
}
}
} |
Like that.
|
|
Back to top |
|
 |
|
Posted: Thu, 19th Mar 2015 13:48 Post subject: |
|
 |
Tried your code and I put my array
Code: | $training_array[$id] = $first_timestamp; |
But it returns date in april, and there is earlier date in a few days.
I don't think that my shoddy code will have major effect on database It works, so that's good xD
"Quantum mechanics is actually, contrary to it's reputation, unbeliveably simple, once you take the physics out."
Scott Aaronson chiv wrote: | thats true you know. newton didnt discover gravity. the apple told him about it, and then he killed it. the core was never found. |
|
|
Back to top |
|
 |
Page 1 of 1 |
All times are GMT + 1 Hour |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB 2.0.8 © 2001, 2002 phpBB Group
|
|
 |
|