I have a string
$string="2012-1-12 51:00:00.5";
How can i explode this to date,month,year,hour,minutes,second without using date function.
I was trying like this please let me know the feasible solution for this,
My try:
$string="2012-1-12 51:00:00.5";
$pieces = explode(" ", $date);
$pieces = explode("-", $date);
$pieces = explode(":", $date);
Out Put:
Array
(
[0] => Array
(
[0] => 2012-1-12
[1] => 51:00:00.5
)
[1] => Array
(
[0] => 2012
[1] => 1
[2] => 12 51:00:00.5
)
[2] => Array
(
[0] => 2012-1-12 51
[1] => 00
[2] => 00.5
)
)
You can use preg_split since you need to explode on 3 parameters, This works -
$string="2012-1-12 51:00:00.5";
$pieces = preg_split("/[-: ]/", $string);
var_dump($pieces);
/*
array
0 => string '2012' (length=4)
1 => string '1' (length=1)
2 => string '12' (length=2)
3 => string '51' (length=2)
4 => string '00' (length=2)
5 => string '00.5' (length=4)
*/
As mentioned in the comment to your query three explodes would be needed:
list($date, $time) = explode(" ", $string);
list($year, $month, $day) = explode("-", $date);
list($hours, $mins, $sec) = explode(":", $time);
/*print the values of $year, $date and so on*/
Hope this helps. Of course this would work assuming all date-time values in your application are in the above format.
Related
I'm trying to create an array where the Month is the key and each key contains one or more dates within them. I start with an array that looks like $arr below. Sidenote: I do not control how the original array is structured as it comes from an API. I merely added the below $arr to illustrate and make it easier for people to understand and debug.
$arr = array(
0 => array(
'date' => '2020-12-07'
),
1 => array(
'date' => '2020-12-19'
),
2 => array(
'date' => '2021-01-03'
),
3 => array(
'date' => '2020-01-18'
)
);
Because I need to display the dates differently than this, I need to construct an array which contains the Month name and a formated date:
$sorted = array(); // This is the array I will return later.
foreach ( $arr as $day ) {
setlocale(LC_TIME, 'sv_SE');
$month = strftime( '%B', strtotime( $day['date'] ) );
$display_date = trim( strftime( '%e %b', strtotime( $day['date'] ) ) );
}
Everything I've tried doing here so far has failed. I can't even remember all methods to be honest. The last I tried was this (within the foreach()):
array_push($sorted, array(
$month => $display_date
));
The var_dump() of that, generated an enumerated array:
array (size=4)
0 =>
array (size=1)
'December' => string '7 Dec' (length=5)
1 =>
array (size=1)
'December' => string '19 Dec' (length=6)
2 =>
array (size=1)
'Januari' => string '3 Jan' (length=5)
3 =>
array (size=1)
'Januari' => string '18 Jan' (length=6)
What I'm trying to achieve is this:
All $display_date's should sit under its $month key. The $month key must be unique and contain all dates for that month.
Thankful for any help that gets me in the right direction here because I feel like I'm doing something fundamentally wrong.
You are appending new array with month and date every loop, replace array_push() with $sorted[$month][] = $display_date;
foreach ( $arr as $day ) {
setlocale(LC_TIME, 'sv_SE');
$month = strftime( '%B', strtotime( $day['date'] ) );
$display_date = trim( strftime( '%e %b', strtotime( $day['date'] ) ) );
$sorted[$month][] = $display_date;
}
print_r($sorted);
Output:
Array
(
[december] => Array
(
[0] => 7 dec
[1] => 19 dec
)
[januari] => Array
(
[0] => 3 jan
[1] => 18 jan
)
)
Input string:
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
And I'm trying to convert it into an array that should look like this:
Array
(
[0] => Array
(
endTime => "2017-03-29T17:15:00.000+11:00"
startTime => "2017-03-29T17:00:00.000+11:00"
)
[1] => Array
(
endTime => "2017-03-31T17:15:00.000+11:00"
startTime => "2017-03-31T17:00:00.000+11:00"
)
[2] => Array
(
endTime => "2017-04-01T12:15:00.000+11:00"
startTime => "2017-04-01T12:00:00.000+11:00"
)
)
I've tried exploding, combining and all sorts but my code is so messy that I'm sure there must be a better and cleaner way?
This is MY cleanest starting point, but even this not clean, yes?
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
$timesarr = explode("},{", $times);
foreach ($timesarr as $i => $item) {
$timesarr[$i] = str_replace("{", "", $item);
$timesarr[$i] = str_replace("}", "", $timesarr[$i]);
$timesarr[$i] = explode(",", $timesarr[$i]);
}
echo '<pre>'; print_r($timesarr); echo '</pre>';
Improvements done:
Appended square braces at starting and end.
Replaced words with [a-zA-Z]+ with "[a-zA-Z]+" making it a valid json than json_decode
PHP code demo
<?php
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
$times=$times."]";
$times="[".$times;
$jsonString=preg_replace("/([a-zA-Z]+\s*)\:/", '"$1":', $times);
print_r(json_decode($jsonString,true));
This code will replace 'endTime' with '"endTime"' and same for startTime. I don't recommend you doing it this way, but it will work for you in this situation:
$times='{"endTime":"2017-03-29T17:15:00.000+11:00","startTime":"2017-03-29T17:00:00.000+11:00"},{"endTime":"2017-03-31T17:15:00.000+11:00","startTime":"2017-03-31T17:00:00.000+11:00"},{"endTime":"2017-04-01T12:15:00.000+11:00","startTime":"2017-04-01T12:00:00.000+11:00"}';
$times=str_replace("endTime",'"endTime"',$times);
$times=str_replace("startTime",'"startTime"',$times);
$times="[$times]";
echo "<h2><pre>";
print_r(json_decode($times,true));
This will output this:
Array
(
[0] => Array
(
[endTime] => 2017-03-29T17:15:00.000+11:00
[startTime] => 2017-03-29T17:00:00.000+11:00
)
[1] => Array
(
[endTime] => 2017-03-31T17:15:00.000+11:00
[startTime] => 2017-03-31T17:00:00.000+11:00
)
[2] => Array
(
[endTime] => 2017-04-01T12:15:00.000+11:00
[startTime] => 2017-04-01T12:00:00.000+11:00
)
)
Try this
First make the string a valid json string.
Add [ at start and ] at end. So your code will be
$times = '[{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}]';
$result = json_decode($times, true);
This is not valid JSON, it looks like a bunch of JS variables concatenated together. You need a heavily customised parser:
<?php
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
$times = str_replace(["{","}"],["\0","\0"],$times); //replace {} with null bytes (they're hopefully unique and will be used as delimiters)
$csv = str_getcsv($times,",","\0"); //Treat string as a CSV enclosed in those null bytes
$csv = array_map(function ($v) {
$vars = explode(",",$v);
$arr = [];
foreach ($vars as $var) {
$parts = str_getcsv($var,":","\""); // endTime:"2017-03-29T17:15:00.000+11:00" is like a CSV split by : and enclosed in "
$arr[$parts[0]] = $parts[1];
}
return $arr;
},$csv);
print_r($csv);
Result:
Array
(
[0] => Array
(
[endTime] => 2017-03-29T17:15:00.000+11:00
[startTime] => 2017-03-29T17:00:00.000+11:00
)
[1] => Array
(
[endTime] => 2017-03-31T17:15:00.000+11:00
[startTime] => 2017-03-31T17:00:00.000+11:00
)
[2] => Array
(
[endTime] => 2017-04-01T12:15:00.000+11:00
[startTime] => 2017-04-01T12:00:00.000+11:00
)
)
Alternately walk away from this mess and demand your data be properly formatted as JSON.
I am getting nested array reply. It is contain date, time and day I want to break that. How can i do that.
This is my reply
Array
(
[code] => 202
[message] => Accepted
[data] => Array
(
[result] => Array
(
[15:45~31-10-2016 Mon] => Array
(
[Sday] =>
[Ttime] => 15:45
[Smonth] =>
"[15:45~31-10-2016 Mon] => Array" how to assign variable and how can i break this into day ,date and time variable
As mentioned in Mohammad's comment on your question,
You should use preg_split function.
$str = key($array['data']['result']); // 15:45~31-10-2016 Mon
$res = preg_split("/[~\s]/", $str);
echo '<pre>'; print_r($res);
output:-
Array
(
[0] => 15:45
[1] => 31-10-2016
[2] => Mon
)
If you have only single element in result array, use extract and explode to retrieve the values from man array: Something like -
$result = $array['data']['result'];
$date = key($result);
$day = extract($result[$date]);
var_dump($date); // 15:45~31-10-2016 Mon
var_dump($Ttime); // will output 15:45
$date = explode(' ', $date);
$dateString = substr($date[0], strpos($date[0], "{$Ttime}~") + 1); //31-10-2016
$week = $date[1]; // var_dump($week); will give `Mon`
Given:
$result = array(
'code' => '202',
'message' => 'Accepted',
'data' => array(
'result' => array(
'15:45~31-10-2016 Mon' => array(
'Sday' => '',
'Ttime' => '15:45',
'Smonth' => ''
)
)
)
);
you can do this:
$data = $result['data']['result'];
$dateKey = key($data);
$dateString = preg_split("/[~\s]/", $dateKey);
$date = array(
'day' => $dateString[2],
'date' => $dateString[1],
'time' => $dateString[0]
);
var_dump($date);
or this:
$data = $result['data']['result'];
$dateKey = key($data);
$dateString = preg_replace("/[~\s]/", ' ', $dateKey);
$dateObj = DateTime::createFromFormat('H:i d-m-Y D', $dateString);
$date = array(
'day' => $dateObj->format('D'),
'date' => $dateObj->format('m-d-Y'),
'time' => $dateObj->format('H:i')
);
var_dump($date);
I have the following array:
Array
(
[0] => 10-7
[1] => 11-3
[2] => 11-7
[3] => 12-3
[4] => 12-7
[5] => 13-3
[6] => 13-7
[7] => 14-3
[8] => 14-7
[9] => 15-7
)
that I need to split into two arrays using "-" as delimiter:
Array
(
[0] => 10
[1] => 11
[2] => 11
[3] => 12
[4] => 12
[5] => 13
[6] => 13
[7] => 14
[8] => 14
[9] => 15
)
and
Array
(
[0] => 7
[1] => 3
[2] => 7
[3] => 3
[4] => 7
[5] => 3
[6] => 7
[7] => 3
[8] => 7
[9] => 7
)
Is there anything like array_explode that does what I want? or a combination of php array functions? I'd like to do this without going through my own for/each loop, if possible, or at least minimize having to reinvent the wheel when something (pseudo)in-built is already out there. I already did this with a for loop. But I can't shake the feeling that there's a more elegant way that smartly uses array functions or anything of that kind. Thanks so much, guys.
Additional info:
Not sure if it matters, but I'm actually after the unique values in the resulting two arrays:
Array
(
[0] => 10
[1] => 11
[2] => 12
[3] => 13
[4] => 14
[5] => 15
)
and
Array
(
[0] => 7
[1] => 3
)
The unique values don't need to be sorted, the keys may be preserved or not, and the legal values of the first array range from 0 to 23, while those of the second 1 to 7. However it's possible to have values other than these (0 to 23 and 1 to 7 or even undelimited stray strings or other data types beyond my control), which I would definitely want to throw out.
The magic bullet you're looking for is array_reduce(), e.g. (PHP 5.3+):
list( $left, $right ) = array_reduce( $input,
function( $memo, $item ) {
list( $l, $r ) = explode( '-', $item );
$memo[0][$l] = $memo[1][$r] = true;
return $memo;
},
array( array(), array() )
);
var_dump( array_keys( $left ), array_keys( $right ) );
You can see it in action here.
With PHP <5.3 you'll have to declare the function ahead of time:
function my_reducer( $memo, $item ) {
list( $l, $r ) = // ...
// ... as above ...
}
list( $left, $right ) = array_reduce(
$input, 'my_reducer',
array( array(), array() )
);
http://codepad.org/TpVUIhM7
<?php
$array = array('7-10','7-11','5-10');
foreach($array as $a){list($x[], $y[]) = explode("-", $a);}
print_r(array_unique($x));
print_r(array_unique($y));
?>
Here Is your Solution, Try to implement following code.
Should work for you.
$main_array = array(
'0' => '10-7',
'1' => '11-3',
'2' => '11-7',
'3' => '12-3',
'4' => '12-7',
'5' => '13-3',
'6' => '13-7',
'7' => '14-3',
'8' => '14-7',
'9' => '15-7',
);
foreach($main_array as $key=>$value)
{
$arr_value = explode('-',$value);
$arr_temp1[] = $arr_value[0];
$arr_temp2[] = $arr_value[1];
}
$arr_temp1_unique = array_unique($arr_temp1);
$arr_temp2_unique = array_unique($arr_temp2);
print "<pre>";
print_r($main_array);
print_r($arr_temp1);
print_r($arr_temp2);
print_r($arr_temp1_unique);
print_r($arr_temp2_unique);
print "</pre>";
As far as I know, there is no suitable PHP function that you can use in this situation.
Functions like array_walk() and array_map() result in a single array, not in multiple arrays.
You said you already have tried a sollution with a loop, but for the sake of helping, here is how I would solve this:
//$data contains the array you want to split
$firstItems = array();
$secondItems = array();
foreach($data as $item)
{
list($first, $second) = explode('-', $item, 2);
$firstItems[$first] = true;
$secondItems[$second] = true;
}
//Now you can get the items with array_keys($firstItems) and array_keys($secondItems);
I'm treating the PHP array as a set by setting the keys instead of the values. This makes that you don't have to use array_unique() to get the unique items.
Try:
foreach($old_array as $array){
$new_2d_array = explode('-', $array);
$new_array_1[] = $new_2d_array[0];
$new_array_2[] = $new_2d_array[1];
}
$new_array_1 = array_unique($new_array_1);
$new_array_2 = array_unique($new_array_2);
Okay, if "The unique values don't need to be sorted, the keys may be preserved or not", then I am going to apply the values to the result arrays as both keys and values to ensure uniqueness without any more function calls after the initial loop.
You can use explode() or sscanf(). explode() has a simpler syntax and only requires the glue substring, whereas sscanf() must parse the whole string and therefore needs a more complicated pattern to match with.
If you didn't need uniqueness, you could simply use:
$hours = [];
$days = [];
foreach ($array as $item) {
sscanf($item, '%d-%d', $hours[], $days[]);
}
or
$hours = [];
$days = [];
foreach ($array as $item) {
[$hours[], $days[]] = explode('-', $item);
}
To ensure uniqueness, just use the isolated values as keys as well.
sscanf() allows you to cast the parsed values directly to integers (Demo)
$hours = [];
$days = [];
foreach ($array as $item) {
[0 => $hour, 1 => $day, 0 => $hours[$hour], 1 => $days[$day]] = sscanf($item, '%d-%d');
}
explode() will only produce string-type values. (Demo)
$hours = [];
$days = [];
foreach ($array as $item) {
[0 => $hour, 1 => $day, 0 => $hours[$hour], 1 => $days[$day]] = explode('-', $item);
}
All of the above snippets rely on "array destructuring" syntax instead of calling list(). If you are wondering why the keys are repeated while destructuring, see this post.
I am trying to build a php function that would return an array with the start date and end date of the last n number of weeks. this would include the current week. It would look something like this:
function lastnweeks(n)
{
//the code. I am not asking for the code itself but ideas on how to accomplish this
return $array;
}
$lastnweeks =lastnweeks(2);
print_r($lastnweeks);
this would print:
Array (
[0] => Array (
[0] => 2010/09/20
[1] => 2010/09/26
)[1] => Array (
[0] => 2010/09/13
[1] => 2010/09/19
))
I wouldn't use an absolute number of seconds because of daylight savings time and leapyears/leapseconds. You can let PHP's strtotime() function take care of this for you by using relative dates. Each iteration through a loop you can simply tell the function to find "Last Monday", and then use that result as your starting point for the next iteration.
The code:
$past_weeks = 7;
$relative_time = time();
$weeks = array();
for($week_count=0;$week_count<$past_weeks;$week_count++) {
$monday = strtotime("last Monday", $relative_time);
$sunday = strtotime("Sunday", $monday);
$weeks[] = array(
date("Y-m-d", $monday),
date("Y-m-d", $sunday),
);
$relative_time = $monday;
}
var_dump($weeks);
The output:
array
0 =>
array
0 => string '2010-09-20' (length=10)
1 => string '2010-09-26' (length=10)
1 =>
array
0 => string '2010-09-13' (length=10)
1 => string '2010-09-19' (length=10)
2 =>
array
0 => string '2010-09-06' (length=10)
1 => string '2010-09-12' (length=10)
3 =>
array
0 => string '2010-08-30' (length=10)
1 => string '2010-09-05' (length=10)
4 =>
array
0 => string '2010-08-23' (length=10)
1 => string '2010-08-29' (length=10)
5 =>
array
0 => string '2010-08-16' (length=10)
1 => string '2010-08-22' (length=10)
6 =>
array
0 => string '2010-08-09' (length=10)
1 => string '2010-08-15' (length=10)
Use strtotime to get the monday and then subtract the number of seconds for each week:
function lastnweeks($n) {
$time = strtotime('Monday 00:00:00+0000');
$arr = array();
while ($n-- > 0) {
$arr[] = array_reverse(array(
date('Y/m/d', $time-=86400), // sunday
date('Y/m/d', $time-=6*86400) // monday
));
}
return $arr;
}
array_reverse is used to reverse the array as the calculation walks backwards.
Take your pick
$last_week = strtotime('last Week');
echo "Last Week ".date("Y/m/d", $last_week)."<br />\n";
or
$last_week = mktime(0,0,0,date("m"),date("d")-7,date("Y"));
echo "Last Week ".date("Y/m/d", $last_week)."<br />\n";