Create DateTime for JSON in PHP - php

I need to hit an API in PHP Laravel and passing Raw body date in it. It requires DataTime to be sent as required by json show in below format.
"ShippingDateTime": "\/Date(1484085970000-0500)\/",
How can I create date like this in PHP/Laravel where I can get any future date (current date + 1). Currently it's giving error that:
DateTime content '23-01-2021' does not start with '\/Date(' and end with ')\/' as required for JSON.

It looks like you have a Unix timestamp with milliseconds (the 000) on the end, plus a timezone identifier. You should be able to construct that with the date formatting flags UvO (unix time, milliseconds, timezone)
(These are in my timezone, -06:00)
echo date('UvO');
// 1611339488000-0600
// Surround it with the /Date()/ it requests
// Encode it as JSON wherever is appropriate in your code
echo json_encode('/Date(' . date('UvO') . ')/');
// "\/Date(1611339460000-0600)\/"
Assuming you have your dates in DateTime objects, call their format() method to produce your desired date format.
// create your DateTime as appropriate in your application
$yourdate = new \DateTime();
echo json_encode('/Date(' . $yourdate->format('UvO') . ')/');
// Set it ahead 1 day in the future
$yourdate->modify('+1 day');

Related

Converting a date from local timezone to UTC

I have a Laravel-based app that is used by people from various parts of the US.
I am capturing a timestamp in Javascript when the user takes a specific action, and then I am submitting that timestamp as form data, for the Laravel/PHP to process.
The timestamp that I am capture in Javascript is in typical "YYYY-MM-DD HH:MM:SS" format.
I have the timezone the user is in stored in a database.
I basically want to take that timestamp, and convert it to UTC time, so that all timestamps in the database are UTC.
That is where I am struggling.
I have the following PHP code:
$defaultTime = request('submitted-time-stamp'); //In this case, we'll say 2022-12-21 12:01:01
$defaultTZ = $user->time_zone; //Translates to America/Denver
$utcTime = new DateTime($defaultTime);
$convertedTime = $utcTime1->setTimeZone(new DateTimeZone('UTC'));
$formattedTime = $convertedTime->format("Y-m-d H:i:s");
echo $formattedTime;
This code – it isn't producing any errors per sé... but it is showing the wrong time. It's showing the time that it went in as, not the time converted to UTC.
Basically, if I submit "2022-12-21 12:01:01" as the time, the converted time SHOULD be "2022-12-21 19:01:01", but it's still just echoing out "2022-12-21 12:01:01".
What am I missing here?
setTimezone() changes the timezone of the object from whatever default it was created with. I.e., it means, "convert from the existing timezone to this new timezone." It does not mean, "interpret the time as if it were in this timezone." If the original string didn't contain some sort of timezone identifier, then that default is whatever your PHP config says.
$when = new DateTime('2022-12-21 12:01:01');
echo $when->getTimeZone()->getName();
This will be the same as:
echo date_default_timezone_get();
Which is probably not what you want unless all your users are in the same timezone as your server.
In order to create a DateTime object in a specific known timezone that is not the same as your server's default, you'll need one of two things -- either a timezone representation in the input string:
$when = new DateTime('2022-12-21 12:01:01 America/New_York');
Or an explicit default timezone passed as a second parameter to the DateTime constructor:
$userDefaultTzStr = 'America/New_York'; // read this value from the database
$defaultTz = new DateTimeZone($userDefaultTzStr);
$when = new DateTime('2022-12-21 12:01:01', $defaultTz);
This latter method is (probably) preferred. If the input string contains any sort of timezone identifier, that will be used and the second parameter will be ignored. But if the input string does not contain any sort of timezone identifier, then the string will be interpreted as if it were in the indicated timezone.
Using Carbon it's very trivial.
use Carbon\Carbon;
$date = Carbon::create(request('submitted-time-stamp'), $user->time_zone);
$date->tz('UTC');
echo $date->format('Y-m-d H:i:s');
It should be the same thing with Laravel's Date facade.
use Illuminate\Support\Facades\Date;
$date = Date::create(request('submitted-time-stamp'), $user->time_zone);
$date->tz('UTC');
echo $date->format('Y-m-d H:i:s');

Unix time stamp gives different results in PHP

I am using the following code to generate time stamps I always get different results for the same input on
$EventDateZone = new DateTime(str_replace('/', '-', $record['Date']), new DateTimeZone(Config::get('app.timezone')));
$EventDate = strtotime($EventDateZone->format("Y-m-d"));
$EventTimeZone = new DateTime($record['Time'], new DateTimeZone(Config::get('app.timezone')));
$EventTime = strtotime($EventTimeZone->format("H:i:s"));
The variables $record['Date] includes 01/04/2014 and $record['Time'] includes 09:26:00 AM and Config::get('app.timezone') is Asia/Dubai
The problem with the converted time it is always different here are the result for the converted time 1398576360 and 1398662760
I need the generated time stamp to be identical as this record will be stored in the database and I don't want to have it duplicated.
The date value does not contain a time, and the time value does not contain a date. UNIX timestamps however are compound values which are date-time values and must contain both. When you instantiate a new DateTime object and you give it an incomplete timestamp (i.e. missing either date or time), it fills in the missing values from the current time. And that will of course always be different.
You'll have to instantiate the DateTime object with both to get your UNIX timestamp. You cannot output a UNIX timestamp separately for date and time, because that doesn't make any sense. Your strtotime code doesn't make any sense. You can separate the DateTime object into date and time components again later if necessary, but not into two separate UNIX timestamps.
$event = DateTime::createFromFormat(
'd/m/Y H:i:s',
"$record[Date] $record[Time]",
new DateTimeZone(Config::get('app.timezone'))
);
echo $event->getTimestamp();
echo $event->format('Y-m-d');
echo $event->format('H:i:s');

Convert a timestamp to an .ics iCal compatible date format

I have a date that I am storing as a timestamp through the formatDate function in jQuery. I am then retriving this value to make an ics file, a calender file that adds the event time and details to the users calender. However the timestamp format isn't working in the ics file, the correct date isn't being added, so I need to convert it to a value that looks like 20091109T101015Z. It's current format as a timestamp looks like 1344466800000This is from this example which is what I am following to create my ics file.
My link to the php file is http:// domain. com/icsCreator.php?startDate=1344380400000&endDate=1345503600000&event=Space%20Weather%20Workshop&location=London
Current my ics file looks like
<?php
$dtStart=$_GET['startDate'];
$dtEnd=$_GET['endDate'];
$eventName=$_GET['event'];
$location=$_GET['location'];
...
echo "CREATED:20091109T101015Z\n";
echo "DESCRIPTION:$eventName\n";
echo "DTEND:$dtEnd\n";
echo "DTSTART:".$dtStart."\n";
echo "LAST-MODIFIED:20091109T101015Z\n";
echo "LOCATION:$location\n";
...
?>
See if this works:
date('Ymd\THis', $time)
Here $time could be startDate or endDate from your query string. If you don't want the time:
date('Ymd', $time)
NOTE (Thanks to Nicola) Here, $time must be a valid UNIX timestamp i.e. it must represent the number of seconds since the epoch. If it represents the number of milliseconds, you need to first divide it by 1000.
EDIT As pointed out by lars k, you need to add \Z to the end of both the strings.
EDIT As pointed out by Nicola, you don't really need it.
The \Z is telling the system the timezone. Z being Zulu or Universal time.
If you leave that out - then you are presuming that the timezone settings on the end users calendar application, match those of your system generating the timestamps.
In the USA alone there are multiple timezones - so you can't make that assumption just based on your users being in the same country as you.
In order for dates to go into the calendar correctly, you need to specify the timezone offset from UTC as plus or minus Hours and Minutes
NOTE:
date('Ymd\THisP') ; // P is an offset against GMT and should work for all calendar purposes.
That would out put somthing like this for a 1hr shift from GMT
20150601T10:38+01:00
When working with Dates in PHP it's best to use the DateTime object, then you can easily work with and change the timezones.
// Start with your local timezone e.g
$timezone = new \DateTimeZone('Europe/Amsterdam') ;
// Don't be tempted to use a timezone abbreviation like EST
// That could mean Eastern Standard Time for USA or Australia.
// Use a full timezone: http://php.net/manual/en/timezones.php
$eventdate = new DateTime ( '1st September 2015 10:30', $timezone);
// Convert the time to Universal Time
$eventdate->setTimezone( new DateTimeZone('UTC') ) ; // Universal / Zulu time
// Return Event Date/Time in calendar ICS friendly format
// comfortable in the knowledge that it is really in UTC time
return $eventdate->format('Ymd\THis\Z') ;

CodeIgniter/JQuery/MySQL DateTime

Within my CodeIgniter app, I'm using a Jquery calendar pop-up that also captures time as set by the user, so the end result looks like: MM-DD-YYYY HH:MM, and I'm storing this in MySQL into a DateTime field that is: YYYY-MM-DD HH:MM:SS. What is the best (most efficient) way to push the date/time into MySQL so that it saves properly, and to pull is back out of MySQL and render it on the screen in the reverse format? Thanks!
Most efficient way is to use the ISO 8601 standard to pass date values between the client and server. Since the client and server talks in strings you'd be parsing the date to a string before sending it either way. The best format I prefer is the combined date and time in UTC:
2011-06-14T13:57Z
There are no spaces and it's clean. Then you'll have to parse it on the server side (should be relatively easy using PHP) and parse it on the client side.
For displaying purposes, I prefer to extend JavaScript's Date.prototype to include a format function that imitates PHP's date format.
Once you include the linked script from above you could do this on the server side -
var today = new Date();
alert(today.format('m-d-Y H:i')); //displays "06-14-2011 11:18"
Good luck!
I think you should use the strptime() function to parse the date received from the jQuery calendar your using and using mktime():
// Parse the time based on your jQuery calendar's format
$parts = strptime($calendar_value, '%m-%d-%Y %H:%M');
if ( ! empty($parts) )
{
// Create a Unix timestamp
$timestamp = mktime($parts['tm_hour'], $parts['tm_min'], 0, $parts['tm_mon'] + 1, $parts['tm_mday'], $parts['tm_year'] + 1900);
// Create a string representation of the Unix timestamp
$date = date(DATE_ISO8601, $timestamp);
}
You'll want to use $date to insert in your database. There is a function called "strtotime" which will attempts to parse dates that are in human-readable format but I doubt it's able to determine if the month or day comes first, especially if they're both lower than 12 which is why I chose to use "strptime" instead.
When you pull the data from MySQL, you can then simply use the date() and strtotime() function to populate the calendar:
echo date('m-d-Y h:i', strtotime($mysql_date));

In PHP, how do I add 3 months to the purchase date retrieved from the iPhone InApp receipt?

After I have validated the receipt against the App Store from my PHP server, the App Store sends me back a JSON response with
"status" : 0
"receipt" : ( .... )
One of the receipt items is "purchase_date" which contains the following string (example) "2010-02-09 19:17:04 Etc/GMT"
I'm trying to establish a subscription service and would like to add 3 months to this date and then write that expiry date into a MySQL table.
Is there a string-to-date type function in PHP that can allow me to achieve the adding of 3 months?
I have found this example which looks like it adds 1 month to a date:
$date = date("Y-m-d");// current date
$date = strtotime(date("Y-m-d", strtotime($date)) . " +1 month");
But I'm not sure how I can turn the string passed by the App Store into a PHP recognised date.
You have already done it, you just added one step too many.
$purchase_date = "2010-02-09 19:17:04";
$purchase_date_timestamp = strtotime($purchase_date);
$purchase_date_3months = strtotime("+3 months", $purchase_date_timestamp);
echo "Purchase date + 3months = ".date("Y-m-d h:i:s", $purchase_date_3months);
this depends on strtotime recoginzing your time string - try it out first. But usually, strtotime can recognize any properly formatted anglo-american date/time string. If in doubt, check the manual.
Don't treat time as a scalar value - It's much more complex than that. I would suggest that you push this logic into your database, provided that you use a one for storing data? Alternatively, recent versions of PHP has a datetime object, which can be used.

Categories