Google API TimeStamp protocol - php

I'm trying to retrieve metrics from Google My Business API.
However I cant figure out what to pass as a timestamp for the time periods.
The error I'm getting is this...
Invalid value at 'basic_request.time_range.end_time' (type.googleapis.com/google.protobuf.Timestamp),
Field 'endTime', Invalid data type for timestamp, value is 1606780800
My code is this
$time = new \Google_Service_MyBusiness_TimeRange;
$start = strtotime("2020-01-01");
$end = strtotime("2020-12-01");
$time->setStartTime($start);
$time->setEndTime($end);
In the class for the TimeRange it shows they simply must be timestamps
class Google_Service_MyBusiness_TimeRange extends \Google_Model
{
protected $internal_gapi_mappings = array( );
/* #params Unix Timestamps */
private $endTime;
private $startTime;
However... I was looking at this.
https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp
And it shows that you have to pass something on the lines of Timestamp(seconds, nanos).
So it seems like google wants an array of the seconds, and the nano seconds??
Heres other docs to help
https://developers.google.com/my-business/reference/rpc/google.mybusiness.v4#google.mybusiness.v4.TimeRange
Anyone run into this problem?

The documentation you link to says:
Range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
Suggesting that you should use a similar format.
$time = new \Google_Service_MyBusiness_TimeRange;
$start = \DateTime::createFromFormat(
"y-m-d H:i:s",
"2020-01-01 00:00:00",
new \DateTimeZone("UTC")
)
->format("Y-m-d\TH:i:s\Z");
$end = \DateTime::createFromFormat(
"y-m-d H:i:s",
"2020-11-30 23:59:59",
new \DateTimeZone("UTC")
)
->format("Y-m-d\TH:i:s\Z");
$time->setStartTime($start);
$time->setEndTime($end);
I wasn't able to find much about this library online, but what little there is does follow this format. "Z" at the end indicates UTC, and I've hard-coded it in my example. It should be able to get replaced with your local timezone, but you may have to try perhaps "O" or "P" in the format string.

Here is some working code:
Note, $startDate and $endDate are just strings passed in from a jQuery calendar, ex "12/27/2020".
The key here is to use DATE_ATOM, which produces a timestamp in the format 2020-12-27T13:22:12+00:00
$gmbStartDate = date(DATE_ATOM, strtotime($startDate . " 12:01 AM "));
$gmbEndDate = date(DATE_ATOM, strtotime($endDate . " 11:59 PM "));
$time = new Google_Service_MyBusiness_TimeRange();
$time->setStartTime($gmbStartDate);
$time->setEndTime($gmbEndDate);
$basicMetricsRequest->setTimeRange($time);
Note that the timestamps are expressed as UTC, so in this example, the insights may be slightly off based on the time zone for the business. If you want to get the insights for your time zone, you'll have to add/subtract the appropriate number of seconds for your timezone.

Related

getting only time timestamp from string

Suppose I have a time string '9:30' which I want to convert to timestamp.
What I do right now is extracting it and manually calculate the timestamp.
list($hour, $minute) = explode(':', '9:30');
$timestamp = $hour * 3600 + $minute * 60;
I'm wondering whether there is a smart way using Carbon or DateTime object.
use strtotime()
manual
$time = '9:30';
$timestamp = strtotime($time);
echo date('H:i',$timestamp);
I don't think you'll be able to get a timestamp from only hour or minute, as timestamp is number of seconds from 00:00:00 Thursday 1 January 1970 (check wikipedia link for more details). So without the date part you can't have a timestamp. Could you please explain how you're planning to use this?
If you're planning to calculate a different timestamp from a given datetime, then you can just do it differently. Say you're planning to get the timestamp 1 day or 24 hours after given time, then you can do it like this (non object oriented way):
$givenTimestamp = strtotime('17-06-2018 09:30:00');
$dayInSeconds = 24*60*60;
$calculatedTimeStamp = $givenTimestamp + $dayInSeconds;
If you're just trying to get how many seconds has been passed for the time section of the timestamp (like 9:30 in your example for a given day), then you can just do it like this:
list($hour, $minute) = explode(':', date ('H:i', strtotime('2018-06-16 09:30:00')));
$secondsSinceStartOfDay = intval($hour)*60*60 + intval($minute) * 60;
You may get the same result without using the intval on $hour and $minute, but it would be better to use intval on them to avoid possible issues in some cases.
Update with Carbon
From Carbon documentation, it seems like you still need the date part to generate the timestamp. So if you have your $date like this '2018-06-16' and $time like this '09:30', then you can recreate your datetime like this:
$dateTimeString = $date .' '. $time .':00';
$carbonDateTime = Carbon::parse($dateTimeString);
// $carbonDateTime will now have your date time reference
// you can now get the timestamp like this
echo $carbonDateTime->timestamp;

Convert User Submitted Date To UTC

I'm trying to figure out how to accept a date/time from a form, which is consequently in the user's timezone, and change it to UTC before inserting it into the database. For some reason, no amount of searching has netted me an answer.
My form will POST whatever date is selected by the user to my code, so I expect to be able to do something like this. Note: the $userDate may be relative to any number of timezones based on user's location
$userDate = $_POST['user_date'] // 2014-05-15 16:37:23
I anticipate using Date().getTimezoneOffset() on my form to also submit the users UTC offset (as detailed here).
$userOffset = $_POST['user_offset']
Then before inserting the date into my database, I would like to convert it to UTC -- but I am stumped on how to do that with PHP (I'm actually using Laravel so if you know of a way using Carbon, that would be even easier, but I couldn't find it in their docs).
I've been half tempted to manually parse the offset and convert it to number of seconds and add or subtract it to strtotime() output of the $userDate and then convert it back into a date format using date() -- but there has to be a better way!
What am I missing here? Does PHP have a function I just don't know about that lets me do something like:
$userDate = '2014-05-15 16:37:23';
$userOffset = '+04:00';
$utcDate = date_apply_offset($userDate, $userOffset);
echo $utcDate; // Outputs: 2014-05-15 20:37:23
Or am I making this harder than it has to be?
EDIT
Based on the solution provided by #vascowhite, I went with the following (added into question to improve answers for those seeking guidance)
I ended up using a function from moment.js since I was already using it to convert UTC to user's timezone on display.
HTML:
<input id="user_offset" type="hidden" name="user_offset" value="">
Javascript:
var offset = moment().format('ZZ');
$('#user_offset').val(offset);
PHP (in a custom date class):
class MyDate {
/**
* Convert Date to UTC
*
* #param string $date Any date parsable with strtotime()
* #param string $offset UTC offset of date
*/
public static function toUTC($date, $offset = '+0:00')
{
if ($timestamp = strtotime($date) && ! empty($offset) )
{
$newDate = date('Y-m-d H:i:s', $timestamp);
$newDate = new \DateTime($date . ' ' . $offset);
$newDate->setTimezone(new DateTimeZone('UTC'));
$date = $newDate->format('Y-m-d H:i:s');
}
return $date;
}
}
// To convert
$userDate = trim($_POST['user_offset']);
$userOffset = trim($_POST['user_date']);
$utc = MyDate::toUTC($userDate, $userOffset)
That class method isn't perfect, and in the event something goes wrong, it just returns the date back -- when really it should throw an exception.
This is a simple task with the DateTime classes:-
$userDate = '2014-05-15 16:37:23';
$userOffset = '+04:00';
$date = new \DateTime($userDate . ' ' . $userOffset);
var_dump($date);
$date->setTimezone(new \DateTimeZone('UTC'));
var_dump($date);
You can then format the date as you wish for output eg:-
echo $date->format('Y-m-d H:i:s');
or:-
$utcDate = $date->format('Y-m-d H:i:s');
echo $utcDate; // Outputs: 2014-05-15 20:37:23
See it working.
If you are doing any work with dates and times in PHP it is worth taking the time to become familiar with these extremely useful classes.
For all sorts of date/time manipulations you can make use of moment.php
For your example all what is needed are two lines of code:
$m = new \Moment\Moment('2014-05-15 16:37:23', '+0400');
echo $m->setTimezone('UTC')->format(); // 2014-05-15T12:37:23+0000
There is much more which helps to deal with date/time issues: https://github.com/fightbulc/moment.php
Cheers

Adjust a PHP date to the current year

I have a PHP date in a database, for example 8th August 2011. I have this date in a strtotime() format so I can display it as I please.
I need to adjust this date to make it 8th August 2013 (current year). What is the best way of doing this? So far, I've been racking my brains but to no avail.
Some of the answers you have so far have missed the point that you want to update any given date to the current year and have concentrated on turning 2011 into 2013, excluding the accepted answer. However, I feel that examples using the DateTime classes are always of use in these cases.
The accepted answer will result in a Notice:-
Notice: A non well formed numeric value encountered......
if your supplied date is the 29th February on a Leapyear, although it should still give the correct result.
Here is a generic function that will take any valid date and return the same date in the current year:-
/**
* #param String $dateString
* #return DateTime
*/
function updateDate($dateString){
$suppliedDate = new \DateTime($dateString);
$currentYear = (int)(new \DateTime())->format('Y');
return (new \DateTime())->setDate($currentYear, (int)$suppliedDate->format('m'), (int)$suppliedDate->format('d'));
}
For example:-
var_dump(updateDate('8th August 2011'));
See it working here and see the PHP manual for more information on the DateTime classes.
You don't say how you want to use the updated date, but DateTime is flexible enough to allow you to do with it as you wish. I would draw your attention to the DateTime::format() method as being particularly useful.
strtotime( date( 'd M ', $originaleDate ) . date( 'Y' ) );
This takes the day and month of the original time, adds the current year, and converts it to the new date.
You can also add the amount of seconds you want to add to the original timestamp. For 2 years this would be 63 113 852 seconds.
You could retrieve the timestamp of the same date two years later with strtotime() first parameter and then convert it in the format you want to display.
<?php
$date = "11/08/2011";
$time = strtotime($date);
$time_future = strtotime("+2 years", $time);
$future = date("d/m/Y", $time_future);
echo "NEW DATE : " . $future;
?>
You can for instance output it like this:
date('2013-m-d', strtotime($myTime))
Just like that... or use
$year = date('Y');
$myMonthDay = date('m-d', strtotime($myTime));
echo $year . '-' . $myMonthDay;
Use the date modify function Like this
$date = new DateTime('2011-08-08');
$date->modify('+2 years');
echo $date->format('Y-m-d') . "\n";
//will give "2013-08-08"

Creating a php date object current date without seconds

I need a date object that has a time of 12:00:00am for the current day (meaning no seconds). I am converting that to that to the number of seconds and passing it in another function. It is eventually used for a report filter using date = "someDateHere' off the database, and the hanging seconds in the field are screwing up the report.
I'm not sure what to put in the second parameter in the time function - leaving it blank will use the current time, which is what I do not want. I can't find examples or anything in the php doc. If there is another function that will do the job, I am open to suggestions. This should be simple, but it is alluding me.
date_default_timezone_set('America/Detroit');
$now = date("Y-m-d 0:0:0");
echo $now . '<br/>';
$now = time($now,0);
echo $now . '<br/>';
Thanks in advance.
edit: Please note: I need to convert that date object to seconds. That is where the timestamp is screwing me up with strtotime function and time function. Even though I am passing it a dateobject without a timestamp, converting it into seconds not-so-conveniently is inserting the timestamp as the second parameter which defaults to the current time.
There are lots of available options here, since PHP accepts a wide variety of time formats.
$midnight = strtotime('midnight');
$midnight = strtotime('today');
$midnight = strtotime('12:00am');
$midnight = strtotime('00:00');
// etc.
Or in DateTime form:
$midnight = new DateTime('midnight');
$midnight = new DateTime('today');
$midnight = new DateTime('12:00am');
$midnight = new DateTime('00:00');
// etc.
See time formats and relative formats in the manual for a complete list of formats with descriptions.
Oh, I'd stop using those functions entirely, and start taking advantage of the DateTime class!
$date = new DateTime("now", new DateTimeZone("America/Detroit"));
echo $date->format("Y-m-d");
http://php.net/manual/en/class.datetime.php
time() takes no arguments. what you're doing is pointless. why not just strtotime(date('Y-m-d')) to get the unix timestamp for midnight?
i think mktime() is just what you need http://www.php.net/manual/en/function.mktime.php
<?php
// Set the default timezone to use. Available as of PHP 5.1
date_default_timezone_set('UTC');
// Prints: July 1, 2000 is on a Saturday
echo "July 1, 2000 is on a " . date("l", mktime(0, 0, 0, 7, 1, 2000));
// Prints something like: 2006-04-05T01:02:03+00:00
echo date('c', mktime(1, 2, 3, 4, 5, 2006));
?>

In an LDAP 'lastlogon' lookup how do I decipher the result?

I'm using a PHP script to grab data from Active Directory using LDAP..
When I get the user values for 'lastlogon' I get a number like 129937382382715990
I've tried to figure out how to get the date/time from this but have no idea, can anybody help?
Read this comment on the PHP: LDAP Functions page.
All of them are using "Interval" date/time format with a value that represents the number of 100-nanosecond intervals since January 1, 1601 (UTC, and a value of 0 or 0x7FFFFFFFFFFFFFFF, 9223372036854775807, indicates that the account never expires): https://msdn.microsoft.com/en-us/library/ms675098(v=vs.85).aspx
So if you need to translate it from/to UNIX timestamp you can easily calculate the difference with:
<?php
$datetime1 = new DateTime('1601-01-01');
$datetime2 = new DateTime('1970-01-01');
$interval = $datetime1->diff($datetime2);
echo ($interval->days * 24 * 60 * 60) . " seconds\n";
?>
The difference between both dates is 11644473600 seconds. Don't rely on floating point calculations nor other numbers that probably were calculated badly (including time zone or something similar).
Now you can convert from LDAP field:
<?php
$lastlogon = $info[$i]['lastlogon'][0];
// divide by 10.000.000 to get seconds from 100-nanosecond intervals
$winInterval = round($lastlogon / 10000000);
// substract seconds from 1601-01-01 -> 1970-01-01
$unixTimestamp = ($winInterval - 11644473600);
// show date/time in local time zone
echo date("Y-m-d H:i:s", $unixTimestamp) ."\n";
?>
This is the number 100-nanosecond ticks since 1 January 1601 00:00:00 UT.
System time article in Wikipedia can give you more details.
What about this:
$timeStamp = 129937382382715990;
echo date('Y-m-d H:i:s', $timeStamp);
EDIT ------
I just tried the following and noticed that this method wont work unless the clock on your machine is set 10 years in the future. Below is the code I used to prove the above pretty much useless unless you do more processing maybe..
$time = time();
echo date('Y-m-d H:i:s', $time);
echo "<br />";
$timeStamp = 129937382382715990;
echo date('Y-m-d H:i:s', $timeStamp);
In my case I'm using Pentaho. With a Modified Javascript value you can convert the values, lastLogon is the column I wanna convert from data stream:
calendar = java.util.Calendar.getInstance();
calendar.setTime(new Date("1/1/1601"));
base_1601_time = calendar.getTimeInMillis();
calendar.setTime(new Date("1/1/1970"));
base_1970_time = calendar.getTimeInMillis();
ms_offset = base_1970_time - base_1601_time;
calendar.setTimeInMillis( lastLogon / 10000 - ms_offset); //lastLogon is a column from stream
var converted_AD_time = calendar.getTime(); // now just add this variable 'converted_AD_time' to the 'Fields' as a show in the image below

Categories