Order weekly international events saved only with day, hour, minute? - php

I have weekly international events saved with day, hour, minute, somewhat like this:
Array
(
[0] => Array
(
[event] => Pear festival
[city] => London
[country] => UK
[local-day] => Saturday
[local-time] => 09:00
)
[1] => Array
(
[event] => Apple festival
[city] => New York
[country] => US
[local-day] => Saturday
[local-time] => 10:00
)
[2] => Array
(
[event] => Kiwi festival
[city] => Wellington
[country] => NZ
[local-day] => Saturday
[local-time] => 11:00
)
)
I'm trying to figure out a way to order these chronologically by UTC. I guess this is easy enough if I add the current local time zone to each event before the data is saved. However, countries have summer time and standard time. For example, New Zealand is currently on NZST, which is UTC+13, but after March they return to DST UTC+12.
Anyhow, as things currently stand (January 2021), these events would be ordered:
Array
(
[0] => Array
(
[event] => Kiwi festival
[city] => Wellington
[country] => NZ
[utc-day] => Friday
[utc-time] => 22:00
)
[1] => Array
(
[event] => Pear festival
[city] => London
[country] => UK
[utc-day] => Saturday
[utc-time] => 09:00
)
[2] => Array
(
[event] => Apple festival
[city] => New York
[country] => US
[utc-day] => Saturday
[utc-time] => 14:00
)
)
But after March, the NZ time would be an hour out, and the same for the other countries when they switch to summer time.
Any ideas how to solve this?

I would suggest to add a column in the events table which will store timestamp of your event in UTC no matter this the region event is happening in.
You can use PHP's default DateTime class or widely accepted libraries like Carbon to get the UTC timestamp from a date. You already have the countries and the time in the table. So when you save the event, generate its UTC timestamp and save. And for already existing events, you can do that in bulk once.
This way you can just order your events directly by the UTC timestamps column. This will also help you a lot in longer run if you want to get all events which will happen on a specific date and time, you can check that directly using the UTC timestamp column.
On a side note, this is also helpful in a way that you would have no date logic in your MySQL query other than the one to order results.

Related

CalendarView get only today's events

I am working with the graph in PHP, and building a calendar widget for a site that should pull only today's events, including all day events.
Everything works, however it also pulls all day events for yesterday and I cannot figure out what I am doing wrong.
$today = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) );
$tomorrow = new DateTime( 'tomorrow', new DateTimeZone( 'America/New_York' ) );
$start_date = $today->format('Y-m-d');
$end_date = $tomorrow->format('Y-m-d');
$events = ms_get_data_as_json( 'calendarview?startdatetime=' . $start_date . '&enddatetime=' . $end_date . '&$orderby=start/DateTime' );
the formatted request string outputs as calendarview?startdatetime=2018-05-18&enddatetime=2018-05-19&$orderby=start/DateTime which would appear to work correctly, however sending this request, the first object returned is an all day event for the previous day. See sample output:
[0] => stdClass Object
(
[createdDateTime] => 2018-05-18T13:30:37.8672462Z
[lastModifiedDateTime] => 2018-05-18T13:34:25.2248155Z
[categories] => Array
(
)
[originalStartTimeZone] => UTC
[originalEndTimeZone] => UTC
[reminderMinutesBeforeStart] => 1080
[isReminderOn] =>
[hasAttachments] =>
[subject] => Test yesterday
[bodyPreview] =>
[importance] => normal
[sensitivity] => normal
[isAllDay] => 1
[isCancelled] =>
[isOrganizer] => 1
[responseRequested] => 1
[seriesMasterId] =>
[showAs] => free
[type] => singleInstance
[onlineMeetingUrl] =>
[recurrence] =>
[responseStatus] => stdClass Object
(
[response] => organizer
[time] => 0001-01-01T00:00:00Z
)
[body] => stdClass Object
(
[contentType] => html
[content] =>
)
[start] => stdClass Object
(
[dateTime] => 2018-05-17T00:00:00.0000000
[timeZone] => UTC
)
[end] => stdClass Object
(
[dateTime] => 2018-05-18T00:00:00.0000000
[timeZone] => UTC
)
)
The start property is clearly for the prior date.
I've tried to change my query to include timestamps startdatetime=2018-05-18T00:00:01Z&enddatetime=2018-05-18T23:59:59Z yet I still get the same results. I've tried to change my $today and $tomorrow variables to use UTC, as the returned result says OriginalStartTimeZone is UTC, but I still get the same results.
Any help is appreciated.
I think there's a bit of an inequality problem in the way the apply the start/end dates filters, and it ends up including events that end on the start time (or start on the end time).
At the moment, it seems the solution is to add 1 second to the filter's start time, and subtract 1 second from the filter's end time. You'll still get all-day events for the requested date, but not all-day events for the previous or next day.
Let us know if you find situations which don't work with this method!

Get Zenith value and GMT Offset by IP, latitude and longitude

I want to use date_sunset and date_sunrise php's functions but the result is not accurate .. I have the user's IP, Longitude, Latitude and i googled how to calculate Zenith value but found nothing.
And the final value in those functions is GMT Offset that i couldn't get it also.
This is available values that i can get for any client and want to use it to get Zenith and GMT Offset ..
geoiprecord Object (
[country_code] => EG
[country_code3] => EGY
[country_name] => Egypt
[region] => C
[city] => Cairo
[postal_code] =>
[latitude] => 30.0771
[longitude] => 31.2859
[area_code] =>
[dma_code] =>
[metro_code] =>
[continent_code] => AF
[region_name] => Cairo Governorate
[timezone] => Africa/Cairo
)
Just leave the $zenith and $gmt_offset parameters at their defaults. The result of these functions is an integer timestamp which is in terms of UTC. Simply convert the result to the time zone you have in your data "Africa/Cairo".
See this answer for a good example of how to convert timestamp to a specific time zone in PHP.

Remove array index based on date

I am working with Symfony framework and I have a Controller whose job is to fetch the RSS feeds.
Once I have the fetched feeds in a set of array, I would like to remove those feeds whose date is greater than the date I provide.
So this is the array of object that I get when I fetch the feeds
Array
(
[0] => AppBundle\Entity\Rss Object
(
[id:AppBundle\Entity\Rss:private] =>
[feedItemTitle:AppBundle\Entity\Rss:private] => Project Manager, Investments Business Management - Prudential - Madison, NJ
[feedItemDescription:AppBundle\Entity\Rss:private] => Globally, PREI has offices in Munich, Frankfurt, London, Paris, Luxembourg, Singapore, Seoul, Tokyo, Sydney, and Mexico City....
From Prudential - 30 Jul 2015 20:00:31 GMT
- View all Madison jobs
[feedItemLink:AppBundle\Entity\Rss:private] => http://www.indeed.com/job/Project-Manager-at-Prudential-in-Madison,-NJ-27eedeae3104d1be
[feedItemPubDate:AppBundle\Entity\Rss:private] => DateTime Object
(
[date] => 2015-07-30 20:00:31.000000
[timezone_type] => 1
[timezone] => +00:00
)
)
[1] => AppBundle\Entity\Rss Object
(
[id:AppBundle\Entity\Rss:private] =>
[feedItemTitle:AppBundle\Entity\Rss:private] => Client Services Specialist - Prudential - Madison, NJ
[feedItemDescription:AppBundle\Entity\Rss:private] => Globally, PREI has offices in Munich, Frankfurt, London, Paris, Luxembourg, Singapore, Seoul, Tokyo, Sydney, and Mexico City....
From Prudential - 03 Aug 2015 19:59:34 GMT
- View all Madison jobs
[feedItemLink:AppBundle\Entity\Rss:private] => http://www.indeed.com/job/Client-Service-Specialist-at-Prudential-in-Madison,-NJ-51ad596876a01466
[feedItemPubDate:AppBundle\Entity\Rss:private] => DateTime Object
(
[date] => 2015-08-03 19:59:34.000000
[timezone_type] => 1
[timezone] => +00:00
)
)
[2] => AppBundle\Entity\Rss Object
(
[id:AppBundle\Entity\Rss:private] =>
[feedItemTitle:AppBundle\Entity\Rss:private] => Manager, Client Services - Prudential - Madison, NJ
[feedItemDescription:AppBundle\Entity\Rss:private] => Globally, PREI has offices in Munich, Frankfurt, London, Paris, Luxembourg, Singapore, Seoul, Tokyo, Sydney, and Mexico City....
From Prudential - 03 Aug 2015 19:59:32 GMT
- View all Madison jobs
[feedItemLink:AppBundle\Entity\Rss:private] => http://www.indeed.com/job/Manager-at-Prudential-in-Madison,-NJ-c0452d58384711e7
[feedItemPubDate:AppBundle\Entity\Rss:private] => DateTime Object
(
[date] => 2015-08-03 19:59:32.000000
[timezone_type] => 1
[timezone] => +00:00
)
)
[3] => AppBundle\Entity\Rss Object
(
[id:AppBundle\Entity\Rss:private] =>
[feedItemTitle:AppBundle\Entity\Rss:private] => Technical Sales Representative, Cell Culture Products - STEMCELL Technologies Inc - United States
[feedItemDescription:AppBundle\Entity\Rss:private] => We create novel, useful, standardized products of unfailing quality and deliver them to more than 70 countries via our many regional offices plus distribution...
From STEMCELL Technologies Inc - 01 Aug 2015 01:16:36 GMT
- View all jobs
[feedItemLink:AppBundle\Entity\Rss:private] => http://www.indeed.com/job/Technical-Sales-Representative-at-STEMCELL-Technologies-in-United-States-f4c10a0e10852686
[feedItemPubDate:AppBundle\Entity\Rss:private] => DateTime Object
(
[date] => 2015-08-01 01:16:36.000000
[timezone_type] => 1
[timezone] => +00:00
)
)
[4] => AppBundle\Entity\Rss Object
(
[id:AppBundle\Entity\Rss:private] =>
[feedItemTitle:AppBundle\Entity\Rss:private] => Technical Sales Representative, Cell Separation Products - STEMCELL Technologies Inc - United States
[feedItemDescription:AppBundle\Entity\Rss:private] => We create novel, useful, standardized products of unfailing quality and deliver them to more than 70 countries via our many regional offices plus distribution...
From STEMCELL Technologies Inc - 31 Jul 2015 01:13:35 GMT
- View all jobs
[feedItemLink:AppBundle\Entity\Rss:private] => http://www.indeed.com/job/Technical-Sales-Representative-at-STEMCELL-Technologies-in-United-States-b8c62120268afb55
[feedItemPubDate:AppBundle\Entity\Rss:private] => DateTime Object
(
[date] => 2015-07-31 01:13:35.000000
[timezone_type] => 1
[timezone] => +00:00
)
)
[5] => AppBundle\Entity\Rss Object
(
[id:AppBundle\Entity\Rss:private] =>
[feedItemTitle:AppBundle\Entity\Rss:private] => Accounting Intern - Code Corp - Draper, UT
[feedItemDescription:AppBundle\Entity\Rss:private] => Would love someone that is interested in International Accounting processes because this position will work with our China, Singapore & Europe office....
From Code Corp - 31 Jul 2015 21:13:43 GMT
- View all Draper jobs
[feedItemLink:AppBundle\Entity\Rss:private] => http://www.indeed.com/job/Accounting-Intern-at-Code-in-Draper,-UT-0e0aca45e988cc89
[feedItemPubDate:AppBundle\Entity\Rss:private] => DateTime Object
(
[date] => 2015-07-31 21:13:43.000000
[timezone_type] => 1
[timezone] => +00:00
)
)
)
As you will notice date in above array.
I am passing the above array and date (not the date from an array above but the $date that i would like to match the array date with to exclude the feed or not) in a parameter to a function below
public function isValid($feed, $date)
{
foreach ($feed as $item) {
if ($item->getfeedItemPubDate()->date < $date) {
echo $item->getfeedItemPubDate()->date;
echo "<br>";
}
}
}
I am able to get the list of feeds whose date from array are smaller than $date but what I am stuck at is how to remove those feeds from the array ? and then pass back the new set of array back to the controller.
You can remove array item by unset function. To know key of that item change a little foreach loop. As so, for example
public function isValid($feed, $date)
{
foreach ($feed as $key => $item)
if ($item->getfeedItemPubDate()->date < $date)
unset ($feed[$key]);
}
You can also try the array_filter function to which you provide a callback function, in your case something like
$feed = array_filter($feed, function($item) use($date) {
return ($item->getfeedItemPubDate()->date < $date);
});
where $date is a variable you set before
Try:
public function isValid($feed, $date)
{
foreach ($feed as $item) {
if (strtotime($item->getfeedItemPubDate()->date) < strtotime($date)) {
echo $item->getfeedItemPubDate()->date;
echo "<br>";
}
}
}

PHP & MySQL, laying out in CSV format with special parameters

I have a database that has budgets in them (for this, I have modified the budgets to be fake).
Long story short, I am attempting to run the following SQL query on the database, and then display a report based on it.
Here is the query: SELECT MONTHNAME(date) AS month, product, SUM(amount) AS spend FROM client_budgets WHERE advertiser_id = '$advertiser_id' GROUP BY MONTHNAME(date), product ORDER BY MONTH(date) ASC
I then clean the data a little, here is the code for that:
foreach($data AS $key => $val) {
$clean_data[] = $val;
}
From this, I get the following (this is a PHP array of the data. I have cut it off since it has about 100K rows in the database currently).
Array
(
[0] => Array
(
[month] => January
[product] => Internet
[spend] => 12000.00
)
[1] => Array
(
[month] => January
[product] => Radio
[spend] => 12250.00
)
[2] => Array
(
[month] => February
[product] => Billboards
[spend] => 6000.00
)
[3] => Array
(
[month] => February
[product] => Internet
[spend] => 16000.00
)
)
My goal is to end up being able to display in a CSV (I already have the headers set for the CSV), the following:
Month, Internet, Radio, Billboards, Television
January, 12000, 12250, 6000, 0
February, 16000, 7000, 6000, 2000
....
I am stuck right now trying to sort the data correctly, and if there is no data for Television for instance one month, to display a 0. Any help would be appreciated! I have been attempting this for almost 3 days now.

PHP SQL Combine Records Within Foreach()

I'm revisiting this as I'm working on another page that I want to use the same concept.
This page shows the output that I'm currently getting from my MSSQL server.
I have a table of venue information (name, address, etc...) that our events happen on. Separately, I have a table of the actual events that are scheduled (an event may happen multiple times in one day and/or over multiple days). I join those tables with a query (as seen below).
<?php
try {
$dbh = new PDO("sqlsrv:Server=localhost;Database=Sermons", "", "");
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT TOP (100) PERCENT dbo.TblSermon.Day, dbo.TblSermon.Date, dbo.TblSermon.Time, dbo.TblSermon.Speaker, dbo.TblSermon.Series, dbo.TblSermon.Sarasota, dbo.TblSermon.NonFlc, dbo.TblJoinSermonLocation.MeetingName, dbo.TblLocation.Location, dbo.TblLocation.Pastors, dbo.TblLocation.Address, dbo.TblLocation.City, dbo.TblLocation.State, dbo.TblLocation.Zip, dbo.TblLocation.Country, dbo.TblLocation.Phone, dbo.TblLocation.Email, dbo.TblLocation.WebAddress
FROM dbo.TblLocation RIGHT OUTER JOIN dbo.TblJoinSermonLocation ON dbo.TblLocation.ID = dbo.TblJoinSermonLocation.Location RIGHT OUTER JOIN dbo.TblSermon ON dbo.TblJoinSermonLocation.Sermon = dbo.TblSermon.ID
WHERE (dbo.TblSermon.Date >= { fn NOW() })
ORDER BY dbo.TblSermon.Date, dbo.TblSermon.Time";
$stmt = $dbh->prepare($sql);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach ($stmt as $row) {
echo "<pre>";
print_r($row);
echo "</pre>";
}
unset($row);
$dbh = null;
}
catch(PDOException $e) {
echo $e->getMessage();
}
?>
So, as it loops through the query results, it creates an array for each record.
Array
(
[Day] => Tuesday
[Date] => 2012-10-30 00:00:00.000
[Time] => 07:00 PM
[Speaker] => Keith Moore
[Location] => The Ark Church
[Pastors] => Alan & Joy Clayton
[Address] => 450 Humble Tank Rd.
[City] => Conroe
[State] => TX
[Zip] => 77305.0
[Phone] => (936) 756-1988
[Email] => info#thearkchurch.com
[WebAddress] => http://www.thearkchurch.org
)
Array
(
[Day] => Wednesday
[Date] => 2012-10-31 00:00:00.000
[Time] => 07:00 PM
[Speaker] => Keith Moore
[Location] => The Ark Church
[Pastors] => Alan & Joy Clayton
[Address] => 450 Humble Tank Rd.
[City] => Conroe
[State] => TX
[Zip] => 77305.0
[Phone] => (936) 756-1988
[Email] => info#thearkchurch.com
[WebAddress] => http://www.thearkchurch.org
)
Array
(
[Day] => Tuesday
[Date] => 2012-11-06 00:00:00.000
[Time] => 07:00 PM
[Speaker] => Keith Moore
[Location] => Fellowship Of Faith Christian Center
[Pastors] => Michael & Joan Kalstrup
[Address] => 18999 Hwy. 59
[City] => Oakland
[State] => IA
[Zip] => 51560.0
[Phone] => (712) 482-3455
[Email] => ffcc#frontiernet.net
[WebAddress] => http://www.fellowshipoffaith.cc
)
Array
(
[Day] => Wednesday
[Date] => 2012-11-14 00:00:00.000
[Time] => 07:00 PM
[Speaker] => Keith Moore
[Location] => Faith Family Church
[Pastors] => Michael & Barbara Cameneti
[Address] => 8200 Freedom Ave NW
[City] => Canton
[State] => OH
[Zip] => 44720.0
[Phone] => (330) 492-0925
[Email] =>
[WebAddress] => http://www.myfaithfamily.com
)
What I'm wanting to do is combine those arrays, in some fashion, so that the venue information isn't repeated every time, but each date/time is show.
I tried typing it out in array style, but couldn't figure out the appropriate multi-dimensionality for it. I'm just pasting how I would like it to display, since that is how it will end up.
The Ark Church
Contact:
Alan & Joy Clayton
450 Humble Tank Rd.
Conroe, TX 77305
(936) 756-1988
info#thearkchurch.com
http://www.thearkchurch.org
Meetings:
Tuesday, 2012-10-30 07:00 PM
Wednesday, 2012-10-31 07:00 PM
Fellowship Of Faith Christian Center
Contact:
Michael & Joan Kalstrup
18999 Hwy. 59
Oakland, IA 51560
(712) 482-3455
ffcc#frontiernet.net
http://www.fellowshipoffaith.cc
Meetings:
Tuesday, 2012-11-06 07:00 PM
Faith Family Church
Contact:
Michael & Barbara Cameneti
8200 Freedom Ave NW
Canton, OH 44720
(330) 492-0925
http://www.myfaithfamily.com
Meetings:
Wednesday, 2012-11-14 07:00 PM
It doesn't necessarily have to end up like that, but it should give a good idea of what I'm looking for.
I don't necessarily have to create a new array. I just want to not show the same information over and over and over.
I was thinking that I could just do some form of compare, in foreach() that says something along the lines of "if Location is the same as previous Location", but I haven't figured out how to do it (is there a way to cache a previous variable with doing $location1 = [Location], $location2 = [Location], etc...?
One thing to note...
These examples don't have different speakers, but sometimes there are. I would like to be able to access the speaker, somehow. I assume that I would want it bound to the actual event.
JJ
One technique: if you have a loop like this:
while ($row = $query->fetch(PDO::FETCH_NUM) ) {
list($time,$place,$etc) = $row;
// display formatted data
}
try this instead:
$row = $query->fetch();
do {
list($time,$place,$etc) = $row;
$row = $query->fetch(PDO::FETCH_NUM);
if ($time != $row[0] && $place != $row[1] && $etc != $row[2]) {
// display formatted data
}
} while ($row);
I usually would approach a problem like this by creating a two-dimensinoal array, indexed by date then ID or in your case by ID then date.
Loop through events (the first dimension) and print out the contents of that event - while in there loop through the dates on that event and print those out as a list as in your example.

Categories