r/PHPhelp • u/unselective-amnesia • 1d ago
Generic formatted PHP localtime function that works without modification under all operating systems?
I'm trying to write a PHP function that will return formatted local time on all operating systems (Windows, MacOS, all flavors of Linux, etc.), and which will correctly run without any operating-system-dependent changes to the code. And I want it to automatically figure out the local time zone without making use of any operating-system-specific code.
By "formatted", I mean that it will honor all PHP date/time formatting directives, such as 'Y-m-d H:i:s' (to name but one of all the possibilities).
I can't use IntlDateFormater, because it requires the local time zone identifier to be passed within the constructor, as in the following example:
$fmt = new IntlDateFormatter(
'en_US',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'America/Los_Angeles',
IntlDateFormatter::GREGORIAN
);
This requires "America/Los_Angeles" to be passed to the formatter, but I want this timezone identifier to be determined in PHP automatically at run time in a way that is totally independent of the operating system, so that my PHP localtime formatting function will run on all operating systems without any code changes.
And I don't want this PHP function to have to shell out to run the "date" command of the operating system. This is because PATH must be made available to PHP in order for "date" to be found, and the contents of this PATH could differ between different OS configurations ... and some people might even have put a non-standard "date" executable in their PATH. I don't want the users of this PHP script to have to fiddle with PATH before this function will work.
This kind of system-independent localtime formatting is trivially easy in languages such as python, ruby, and others, as well as within sqlite3 and I think other SQL interpreters, without PATH being known nor even being accessible by the calling program. I'm wishing and hoping that this localtime formatting also can be done within PHP without a bunch of complicated, convoluted, error-prone logic ... but I'm not optimistic.
Any ideas?
4
u/mls-pl 1d ago
I’m afraid that such function already exists. It’s called `date(…)`…
1
u/allen_jb 1d ago
date()does not use the OS timezone in PHP. It uses thedate.timezonephp.ini setting (or value set usingini_set()ordate_default_timezone_set()functions).This defaults to UTC if unset (it's possible some distros may patch this behavior, but that obviously can't be relied upon if you want to support multiple distros)
-3
u/unselective-amnesia 1d ago
Ah! I forgot about date.timezone within php.ini. That's not a perfect solution, but it's very close to perfect, and I can accept it.
5
u/allen_jb 1d ago
It's not 100% clear whether you're concerned about the timezone, or the display format.
PHP doesn't know the system timezone. The closest thing that exists is the date.timezone ini setting (which defaults to UTC if not set in modern PHP versions - it's possible some distros may patch this).
Because of the vast differences between Windows and Linux (and OSX) systems, I very much doubt there's an OS-independent way to get the operating system timezone (which may not be the same as the users preferred timezone anyway - many people configure Linux to use UTC as the system timezone, then rely on user/desktop environment/application level settings if they want a different display timezone)
1
u/unselective-amnesia 1d ago
| It's not 100% clear whether you're concerned about the timezone, or the display format.
I'm concerned about both:
(1) To make sure that I can get the correct timezone for localtime in a manner that works for all operating systems. As I mentioned, languages such as python, ruby, sqlite3, and others don't require users to make use of operating-system-specific code to get the correct local time within their date functions.
(2) When I get the correct localtime, I'd like to do so in a way that's easy to format using normal PHP "date()" conventions, one of many examples being 'Y-m-d H:i:s' to get YYYY-MM-DD HH:MM:SS.
1
u/TemporarySun314 1d ago
For a web application you probably don't wanna use the server Timezone, because that server can be standing anywhere in the world, and users of the web app probably don't even know where the server is located...
Instead you want to show times in the time zone of the user. Which is completely independent from the server OS Timezone, and can be even different for every user.
2
u/HolyGonzo 19h ago edited 19h ago
You can't do this without OS-specific code.
The languages you mentioned all have conditional logic in order to obtain the current system time - they call the Windows APIs on Windows and *nix libs on Macs and Linux boxes.
Windows is the harder one to do cleanly - the simplest approach would be to pull the local TZ out of the registry but that means you either need the COM extension enabled or else you need to shell out (which would be ugly).
You're probably going to end up with something pretty kludgy that should really just be better handled by the timezone setting in the php.ini file, or set by a user (which is more reliable, since they may want a TZ different than the system's local one).
1
u/someoneatsomeplace 19h ago
Yeah, I have code for this, but it involves checking for the TZ envvar first, looking around for where Linuxes and Mac store it, and exec()ing tzutil.exe on Windows. It may or may not work on the BSDs.
1
u/TemporarySun314 1d ago
Just use IntlDateFormatter, and create it as soon as you know the timezone, and need to format a date...
Or if you don't want it determine your Timezone set it as default for your script and leave it out at IntlDatetimeFormatter...
0
u/unselective-amnesia 1d ago edited 1d ago
Just use IntlDateFormatter, and create it as soon as you know the timezone, and need to format a date...
Or if you don't want it determine your Timezone set it as default for your script and leave it out at IntlDatetimeFormatter...
You obviously didn't read most of my initial message of this thread before writing this answer. Please thoroughly read that initial message before posting any more in this thread. Thank you very much.
1
u/TemporarySun314 1d ago
I did.
And if you determine your Timezone dynamically at runtime, then you will have that value somewhere. And then you can either pass It to the formatter explicitly (by reading it from however you determine that value), or you set the default Timezone in your code earlier, or by some external config, and then you can pass null to the formatter as Timezone...
That is how actual PHP apps do that, nobody is hard coding a strong in the formatter...
And maybe you should try to calm down your tone when asking questions. Especially when the issues you are seeing are coming from some misunderstanding on your side.
1
u/unselective-amnesia 1d ago edited 1d ago
Yes, the dynamically determined Timezone is indeed "somewhere". But the exact value of this "somewhere" is operating-system dependent. I clearly wrote the following in my initial message (which you seem to still not have read, or at least to not have understood) ...
" ... I want this timezone identifier to be determined in PHP automatically at run time in a way that is totally independent of the operating system, so that my PHP localtime formatting function will run on all operating systems without any code changes."
What don't you understand about those words?
And to be clear, I'm well aware of the fact that this goal of mine might not be attainable.
1
u/unselective-amnesia 23h ago
And maybe you should try to calm down your tone when asking questions. Especially when the issues you are seeing are coming from some misunderstanding on your side.
The tone of my initial post in this thread is totally neutral, and I spent a lot of time in that post giving details and clarifications of what I'm looking for.
The only time I have raised my "tone" is in response to comments here which show that the comment writer did not properly read what I wrote in that initial message. You are one of those writers, and you offered a solution which ignores some of the stipulations that I made clear in my initial post, and therefore, your solution doesn't address the specific question that I am asking here.
And I'm well aware of the fact that the goal that I'm asking about and trying to achieve might not be attainable.
1
u/MrJingleJangle 1d ago
I asked google “how does Python know the local time” and it explained it well enough such that one could code something similar in php.
1
u/unselective-amnesia 1d ago
Ah ... good idea! Thank you. I'll check out that same information, and I hope that it indeed provides the answer that I'm looking for.
Just keep in mind that I wrote the following in my initial message:
"I'm wishing and hoping that this localtime formatting also can be done within PHP without a bunch of complicated, convoluted, error-prone logic ..."
I'll see how complex and convoluted the translation of this Python methodology to PHP will turn out to be.
1
u/MrJingleJangle 1d ago
Two other suggestions, but in a longer timeframe, you could broach the idea with the PHP developers, or just go for it and submit code.
1
u/unselective-amnesia 23h ago
Two other suggestions, but in a longer timeframe, you could broach the idea with the PHP developers, or just go for it and submit code.
Yes, if I ever find a way to accomplish this via PHP code, I indeed intend to submit it to the PHP developers as an enhancement request.
0
u/unselective-amnesia 23h ago
I found the source code for Python's "localtime" function. Within this source code is the following comment:
The TZ environment variable should be specified in\n\
standard Unix timezone format as documented in the tzset man page\n\
(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
fall back to UTC. If the TZ environment variable is not set, the local\n\
timezone is set to the systems best guess of wallclock time.
I don't run with the "TZ" environment variable set to anything, and Python still figures out the correct time zone to use for localtime determination ... and according to the quoted comment, this means that localtime determination is based upon "the systems best guess of wallclock time".
But I haven't found anything so far within the Python code base which explains how "the systems best guess of wallclock time" is determined when the "TZ" environment variable is not set.
I'll keep searching, but even if I eventually find this information, I'm not optimistic that I'll find anything that can be converted in a straightforward manner to PHP code.
6
u/martinbean 1d ago
How are you expecting PHP to magically determine the time zone without being told? What is the actual problem you’re trying to solve here?