How to separate the timezone and datetime from a string? - php

I have a string get from a text file name.
$string = "20181011000000GMT+0800"
// trying to convert it
Carbon::createFromFormat('YmdHisTO', $string)->format...
It shows me this error.
Unexpected data found. The timezone could not be found in the database
Data missing
How can i separate the datetime and timezone, if there's GMT+0800 end of the datetime string?

You can parse that format with a slight change to the format string you're using:
$string = "20181011000000GMT+0800";
Carbon::createFromFormat('YmdHisT+', $string);
The + sign tells the parser to ignore everything after the first timezone identifier (GMT). Strictly, it'll work without the + too, but I prefer to use it for clarity. Up to you though.
See https://3v4l.org/kDorn
Actually, testing this a bit more, I'm not sure the plus sign is that relevant. I think either of the timezone format characters (T and O) are simply swallowing all of the timezone information, rather than just their specific parts. DateTime's parser can be a bit of a minefield sometimes.

I would recommend using strtotime() it accepts every valid datetime format. See usage: http://nl1.php.net/manual/en/function.strtotime.php
$DateTimeString = "20181011000000GMT+0800";
$timestamp = strtotime($DateTimeString);
// trying to convert it
Carbon::createFromTimestamp($timestamp)->toDateTimeString();

Related

PHP Date and Time Format for an API request to Linnworks

IN the Linnworks API documentation and Start and End Date is required for one of the API requests. The format for this is as follows;
2018-02-19T16:57:07.0049771+00:00
I am unsure on this formatting. Is this a default formatting of some sort or would I need to construct it?
If I need to construct, I get the obvious portions;
Date;
2018-02-19
Time;
T16:57:07
But what this portion is I do not know;
0049771+00:00
Is it the Unix Time Stamp and a + for time zone?
The end part is microseconds and timezone.
If you use date("c") or $yourDateObject->format("c") it should give you a complete string in this format (ISO 8601).
This is ISO8601 format, which states:
Decimal fractions may be added to any of the three time elements.
However, a fraction may only be added to the lowest order time element
in the representation.
Considering the use of the word "may" here, I would expect that the API should allow you to specify the timestamp without any such decimal portion, assuming that is acceptable for your application. (Disclaimer -- this is a guess.)
If so, this can be had simply via:
echo date('c');
Which yields:
2018-03-20T16:24:37-04:00
Format character u(microseconds) will return 6 char long string (on php<7.1 it will be 000000).
If you need 7 char long string, just prepend 0 to the end, like this:
$dt = new DateTime();
echo $dt->format('Y-m-d\TH:i:s.u0P');
It will output something like this: 2018-03-21T08:47:01.0263140+01:00

How to format an UTC date to use the Z (Zulu) zone designator in php?

I need to display and handle UTC dates in the following format:
2013-06-28T22:15:00Z
As this format is part of the ISO8601 standard I have no trouble creating DateTime objects from strings like the one above. However I can't find a clean way (meaning no string manipulations like substr and replace, etc.) to present my DateTime object in the desired format. I tried to tweak the server and php datetime settings, with little success. I always get:
$date->format(DateTime::ISO8601); // gives 2013-06-28T22:15:00+00:00
Is there any date format or configuration setting that will give me the desired string? Or I'll have to append the 'Z' manually to a custom time format?
No, there is no special constant for the desired format. I would use:
$date->format('Y-m-d\TH:i:s\Z');
But you will have to make sure that the times you are using are really UTC to avoid interpretation errors in your application.
If you are using Carbon then the method is:
echo $dt->toIso8601ZuluString();
// 2019-02-01T03:45:27Z
In PHP 8 the format character p was added:
$timestamp = new DateTimeImmutable('2013-06-28T22:15:00Z');
echo $timestamp->format('Y-m-d\TH:i:sp');
// 2013-06-28T22:15:00Z
In order to get the UTC date in the desired format, you can use something like this:
gmdate('Y-m-d\TH:i:s\Z', $date->format('U'));
To do this with the object-oriented style date object you need to first set the timezone to UTC, and then output the date:
function dateTo8601Zulu(\DateTimeInterface $date):string {
return (clone $date)
->setTimezone(new \DateTimeZone('UTC'))
->format('Y-m-d\TH:i:s\Z');
}
Edit: clone object before changing timezone.
Since PHP 7.2 DateTimeInterface::ATOM was introduced in favor of DateTimeInterface::ISO8601, although it still lives on for backward compatability reasons.
Usage
$dateTimeObject->format(DateTimeInterface::ATOM)

How to format a PHP date in .Net DataContractJsonSerializer format?

There is a requirement to send a date inside a JSON post using PHP in this following format
\/Date(410256000000-0800)\/
How do I convert a standard dd-mm-yyyy h:i:s datetime like 01-01-2013 12:00:00 to that format in PHP? Just need to know what values correspond to what in that format, not really look for a stringify things answer.
This should do it:
$dateTime = DateTime::createFromFormat('d-m-Y H:i:s', '01-01-2013 12:00:00');
$requiredJsonFormat = sprintf(
'\/Date(%s%s)\/',
$dateTime->format('U') * 1000,
$dateTime->format('O')
);
echo $requiredJsonFormat; // prints '\/Date(1357038000000+0100)\/'
I leave it up to you to find what the formats U and O do from http://php.net/date.
An alternative would be to use PHP's DOTNET API and use the DataContractJsonSerializer class directly from PHP. However, you'd need .NET installed on the server and using PHP's DOTNET API is rather arcane.
The more interesting part is why you need this format at all. This is explained in a blogpost at http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx
But because of a strange oversight in the EcmaScript specs, there is no standard way of describing dates in JSON. […] Our current approach is using a small loophole in the JSON specs. In a JSON string literal, you may (or may not) escape some characters. Among those characters, weirdly enough, there is the slash character ('/'). […] The new format is "/Date(1198908717056)/" where the number is again the number of milliseconds since January 1st 1970 UTC […] The point is that this disambiguates a date literal from a string that looks like the same date literal, while remaining pure JSON that will be parsed by any standard JSON parser. Of course, a parser that doesn't know about this convention will just see a string, but parsers that do will be able to parse those as dates without a risk for false positives
We created a package for this: https://github.com/webapix/dot-net-json-date-formatter
It uses a similar approach than the previous answer, tested on PHP versions >= 5.6.
use DateTime;
use DateTimeZone;
use Webapix\DotNetJsonDate\Date;
$date = DateTime::createFromFormat(
'd-m-Y H:i:s',
'01-01-2013 12:00:00',
new DateTimeZone('+0000')
);
Date::toJsonDate($date); // returns '/Date(1357041600000+0000)/'

PHP Time Problem

well, I"ve got a time format of the type: 2011-02-16T01:25:50+04:00
I want to strip the +04:00 from the end of the string. How to do it?
I am converting a timestamp from mysql to ISO 8601 format using this function:
$timeagotime = date('c',strtotime($row['created_at']));
where $timeagotime contains the value: 2011-02-16T01:25:50+04:00
Refer to the documentation for php's date function: http://php.net/manual/en/function.date.php
You need to use a different format string. For instance,
date('Y-m-d',strtotime($row['created_at']));
Givens you "2011-02-16". There are a number of format strings... check out the doc.
You could use substr() to remove it, or just generate a date without it in the first place, though you couldn't use the 'c' formatting option, since that'd just add the timezone on again.
$timeagotime = substr($timeagotime, 0, 19)
$timeagotime = date('Y-m-dTG:i:s', strtotime(...));
If you absolutely don't need the end then you can use the following. Otherwise I'd suggest using a different way to generate your date from the table. PHP Date
$timeagotime = substr(date('c',strtotime($row['created_at'])), 0, 19);

PHP : Better date parser than strtotime

I'm trying to parse a string in a specific format and I'm really surprised to discover that I can't find a good function to do that.
The only one I found is strtotime and it doesn't fit as it guesses the date format. I really don't trust the "guess" part.
Moreover my string input is in a french format (dd/mm/aaaa) which it seems that it's not well understood (it parses american formats like mm/dd/aaaa).
What I'm looking for is a function that take in input a date string and a format to parse.
I could do it myself with a regexp but I can't believe that it doesn't already exist.
I found :
DateTime::createFromFormat(). But it only work with PHP 5.3 and I don't have the power to upgrade the PHP version (5.2)
strptime(). This method does what I want but is not implemented on windows platform (by the way: WTF ??)
Any suggestion ?
Unfortunately, it seems that such parsing is better done manually, by exploding the string at slashes and then switching day and month.
Check out Zend_Date, which lets you specify the format when you set a date. As well as including constants for many common formats, you can specify your own too.
$date = new Zend_Date();
$date->set('27/08/2009','DD/MM/YYYY');
The following comment from php.net on strtotime may help:
Fails for non-US dates where the
ordering is uncertain, such as
01/02/2003 - parses this as Feb 1st,
rather than Jan 2nd.
If you are parsing dates for a non-US
locale, you can flip these elements of
your date:
<?php
$y = $_POST['date'];
if (preg_match('/^\s*(\d\d?)[^\w](\d\d?)[^\w](\d{1,4}\s*$)/', $y, $match)) {
$y = $match[2] . '/' . $match[1] . '/' . $match[3];
}
echo date('d # m # Y', strtotime($y));
?>
WARNING: Above only works for dates,
and breaks for times: 12:30:01 will be
converted to 30/12/01.
I've written a class myself, I think you'll find an ok version in gadmdatecommand.php in http://sourceforge.net/projects/phpdbedittk
Regarding the comments here to just explode by '/' and swap the number, its not quite that simple. If you offer to enter dates into an input box, you may get - depending on the locality of the user and the application
1/7/2010
1.7.2010
1-7-2010
15 Jul
1 Jul 2010
1/6/8
and many more variations. I've solved this problem (at least for me successfully) by creating dateformats, each of which have
a) a regex that matches the format
b) an array mapper that matches regex brackets into date pieces (day, month, minute, am/pm)
c) an output format for date()
HTH
If you know your date format input will be English-formatted, then you can process it into a more standard date format. A simple parsing of 24/7/2007 to 2007-07-24 is trivial. Explode with the forward slash and put the parts in the right spot. I know for a fact that strtotime will parse 2007-07-24 correctly.
strptime():
Internally, this function calls the strptime() function provided by the system's C library. This function can exhibit (!) noticeably different behaviour across different operating systems. The use of date_parse_from_format(), which does not suffer from these issues, is recommended on PHP 5.3.0 and later.
http://www.php.net/manual/en/function.strptime.php

Categories