Converting source text to time with timezone adjustment - php

I have a file of raw text/xml information that lists events occurring on the current day. The start time for each event is expressed in 00:00:00 24-hour format and is based on the Europe/London timezone. What I want to do is convert each event start time found in the file so that it is expressed in 'g:i A' format and is based on the America/New_York timezone.
Playing around, the following code works just fine if I define the source string as a single instance:
//output will be 3:45 PM
$src_tm = '19:45:00';
$src_tz = new DateTimeZone('Europe/London');
$dest_tz = new DateTimeZone('America/New_York');
$tm = new DateTime($src_tm, $src_tz);
$tm->setTimeZone($dest_tz);
$dest_tm = $tm->format('g:i A');
echo $dest_dt;
However as I said above, I want to do this for each instance in the file. I've come up with the following regex to identify each instance: '/\d+:\d+:00/' but I am having extreme difficulty making things work using the regex with preg_replace and DateTime. What do I need to do to ensure that each start time in the file is identified and converted to 'g:i A' and America/New_York?

I would suggest not using regular expressions to manipulate the XML file. This could be error-prone.
Instead, look into something like SimpleXML for parsing the XML file into a object graph whose nodes you can query and manipulate safely. Once you are done updating the date formats and timezones in each of the relevant nodes, you can save the object graph back into the file as an XML string.

Matt was correct on UTC rather than Europe/London. Thank you for pointing it out. And yes, there is no need for assigning to a particular date in my case, as the information I am using is refreshed daily. So the default to the current date is all I need.
With that said, I was able to get things right after reading about preg_replace_callback. Worked a charm!
//adjust event start time for America/New York
$input = preg_replace_callback('/\\d{2}:\\d{2}:\\d{2}/', 'replace_timestamp', $info);
function replace_timestamp($matches)
{
$source_tz = new DateTimeZone('UTC');
$destination_tz = new DateTimeZone('America/New_York');
$time = new Datetime($matches[0], $source_tz);
$time->setTimeZone($destination_tz);
return $time->format('g:i A');
}

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');

Convert timestamp coming from SQL database to String

I am saving the timestamp in SQL as bigint(20). The number is correct and in android or https://www.epochconverter.com it works fine.
However I am not able to create a date-string based on the timestamp received from database.
First of all, the timestamp seems to come from database as a String, so I can't just say echo date("d.m.Y, $timestamp). The result is the famous 31.12.1969.
So I tried echo date("d.m.Y, strtotime($timestamp)). However, even though strtotime is said to be able to convert almost everything to a timestamp, a simple String containing a timestamp is not possible. Results still remained on the last day of Brian Adams probably favorite year.
Some progress I made by casting the $timestamp to a float value like so: echo date("d.m.Y", floatval($timestamp));. However, now things got really confusing for me. I seemed to have successfully converted my timestamp, however, date() gave me the dates around 02.09.52299.
The timestamps I am using are timestamps of current time, e.g. 1588489252657, which currently leads to the date 23.03.52307.
So all I want is to come to a date based on the timestamp 1588489252657 to see the 03.05.2020 on my screen.
Thanks for any advice!
<?php
$timestamp = 1588489252657; // Timestamp in Milliseconds
$seconds = round($timestamp/1000, 0); // Timestamp Rounded to Seconds
$date = new DateTime(); // Create PHP DateTime Object
$date->setTimestamp($seconds); // Set the Timestamp
echo $date->format('Y-m-d H:i:s'); // Specify the Required Format
The answers are pretty much in the comment sections. But I have shared this answer since this is another approach in OOP fashion. You can leverage the power of PHP's DateTime Class.
PHP Official Documentation For DateTime Class Link Below:
PHP DateTime Class
You have to transform the timestamp to seconds first.
$timestamp = 1588489252657;
$dateInUnixSeconds = round($timestamp / 1000, 0);
$date = \DateTimeImmutable::createFromFormat('U', (string) $dateInUnixSeconds);
echo $date->format('d.m.Y');
PS:
I recommend you to use the \DateTimeImmutable object to avoid mutability problems.
https://github.com/Chemaclass/php-best-practices/blob/master/technical-skills/immutability.md

Time format conversion

I need to convert a specific date format into local time (Europe/Sarajevo), I have the time in this format 2013-02-17T15:00:00Z which I don't really understand and this is why I don't know how to convert it to the Europe/Sarajevo time, who knows maybe it is already Sarajevo time, I don't know...
OK I can parse it and remove the T and Z and get a time but these letters mean something, probably they affect the result time...
The result time is for example 2013-02-17 18:00:00, probably there will be a difference due to the letters T and Z which are probably time offset.
Use DateTime. It's much better for working with timezones:
$datetime = new DateTime('2013-02-17T15:00:00Z');
$datetime->setTimeZone(new DateTimeZone('Europe/Sarajevo'));
echo $datetime->format('c');
Reference
DateTime
DateTimeZone
See it in action
You can use php date function like this
$date = '2013-02-17T15:00:00Z';
echo date('Y-m-d H:i:s',strtotime($date));
See the Manual

Trying to convert from seconds to date

Okay so I have an array of results from a table, we have a start and end time we are retrieving. the start/end time would look something like this:
1345497551
Now I'm trying to convert this to a real time, for instance 1345497551 might become 2012/05/09 17:23:12 or something. I've found a few things but none seem to work correctly. one solution I tried, according to what someone was saying on another question on here, was
$createdate = date('H:i:s',$numberofsecs);
where $numberofsecs was the time pulled in from the array. but this only ever outputs 17:00:00 repeatedly for every time we had available for testing.
How can I go about making this work correctly?
Assuming that that's a standard unix timestamp string (seconds since midnight 1/1/1970), then you should be able to use date as you mentioned, but just modify the format string:
echo date('Y/m/d H:i:s', $numberofsecs);
The example you mention where you were always getting 17:00:00 could have been because your test cases were all only datestamps, encoded as timestamps, and having an offset from GMT . . .
I have tried below code:
$ts = 1345497551;
$date = new DateTime("#$ts");
echo $date->format('U = Y-m-d H:i:s');
output : 1345497551 = 2012-08-20 21:19:11

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));

Categories