Categories
PHP

Handle date and time beautifully with PHP

Handle date and time beautifully with PHP and display it correctly in your Web application.

Date and time is usually composed of year, month, day, hour, minute, second, and of course time zone. We will see in what follows how to create, modify, and display date and time correctly in the context of proper Internationalization (i18n) and Localization (l10n).

Notes:

  • The techniques used by the developer to determine and apply the appropriate locale are outside the scope of this article.
  • The exercise is left to the reader to try the code written on this page in order to witness the results obtained with the techniques shown.

Manipulating Date & Time

DateTime objects can be created without parameters to capture the current clock settings for your computer/server including the local timezone setting as follows:

  1. $now = new DateTime();

The constructor may also be used to parse standard-formatted date-time strings as follows:

  1. $now = new DateTime('2022-11-08 15:52 GMT-5');

We can convert the time from one timezone to another by setting a new timezone on the same object as follows:

  1. $now->setTimeZone(new DateTimeZone('America/Edmonton'));

Refer to the Wikipedia List of tz database time zones page for a full listing of the timezone strings and their meanings. You may find a complete listing of PHP-supported timezone strings by running the following PHP command:

  1. DateTimeZone::listIdentifiers();

Time can be added or subtracted from the DateTime object using the add and sub methods and new DateInterval objects as follows:

  1. $now->add(new DateInterval('P1Y2M3D'));
  2. $now->sub(new DateInterval('P1YT3H2M1S'));

In the example above, 1 year, 2 months, and 3 days are added to $now and then 1 year, 3 hours, 2 minutes, and 1 second are removed. Alternately, the DateTime::modify method may be used as follows to add 1 day and 3 seconds as well as to remove 1 hour:

  1. $now->modify('+1 day -1 hour +3 seconds');

The date and time in this object can also be returned as a string to then be echoed to output as follows:

  1. echo $now->format('l, F j, Y, H:i:s T');

This is great, however, the format method does not use locales. All output is in English. Refer to the PHP.net reference on DateTime, DateInterval, and DateTimeZone for any details that you may be wondering about.

In the following section we will see how we can simultaneously output the Date and Time information in a different locale (language) and a different timezone.

Using IntlDateFormatter to Output Localized Dates and Times

IntlDateFormatter is part of the Intl extension of PHP and must be loaded directly in the php.ini file. This is done by ensuring the “extension=intl” line is not commented (not prepended by “;”) as follows:

  1. extension=intl

Once this type of change in the configuration is done, Apache must be restarted so that php runs with the fresh configuration.

Output of Formatted Date & Time

The IntlDateFormatter class, as the name implies, is used to correctly format dates, internalionalized. To be used, first build a new formatter object as follows:

  1. $fmt = new IntlDateFormatter(
  2.     'en_US',//locale string
  3.     IntlDateFormatter::FULL,//date format
  4.     IntlDateFormatter::FULL,//time format
  5.     'America/Montreal',//timezone string
  6.     IntlDateFormatter::GREGORIAN//calendar type
  7. );

Where

  • the locale string may come from a $_SESSION[‘locale’] variable (set for the user)
  • the date format can be set to any constant IntlDateFormatter::SHORT, MEDIUM, LONG, FULL, and other values giving results that are increasingly long and that you should test. See the documentation for full details.
  • the time format can be set to any of the same constants as previously listed.
  • the timezone string as supported by the DateTimeZone class and explained above. This string may come from a $_SESSION[‘timezone’] variable (set for the user).
  • the calendar type will be either IntlDateFormatter::GREGORIAN or IntlDateFormatter::TRADITIONAL. Traditional, or non-Gregorian calendars need to be specified in the locale string. For example, “cn@calendar=CHINESE”.

An example using a chinese calendar is as follows:

  1. $fmt = new IntlDateFormatter(
  2.     'cn@calendar=CHINESE',
  3.     IntlDateFormatter::FULL,
  4.     IntlDateFormatter::FULL,
  5.     'Asia/Hong_Kong',
  6.     IntlDateFormatter::TRADITIONAL
  7. );

One may also specify a custom format string as an additional parameter, following the constants for ISO 8601 Date Output. For example,

  1. $fmt = new IntlDateFormatter(
  2.     'en_US',
  3.     IntlDateFormatter::FULL,
  4.     IntlDateFormatter::FULL,
  5.     'America/Montreal',
  6.     IntlDateFormatter::GREGORIAN,
  7.     'MMMM d, Y'
  8. );

and

  1. $fmt = new IntlDateFormatter(
  2.     'fr@calendar=CHINESE',
  3.     IntlDateFormatter::FULL,
  4.     IntlDateFormatter::FULL,
  5.     'Asia/Hong_Kong',
  6.     IntlDateFormatter::TRADITIONAL,
  7.     'MMMM d, Y'
  8. );

The new, last, parameter is a string that should be subject to internationalization (i18n) and localization (l10n) procedures.

With our IntlDateFormatter object, we can format DateTime objects for output as defined in the formatter parameters. One command is required, as follows:

  1. $now = new DateTime();//our current date and time
  2. echo $fmt->format($now->getTimestamp());//output in format

Conclusion

To handle date and time beautifully with PHP is simple with the help of a few classes:

The techniques shown in this article are correct to complete the internationalization (i18n) of dates and times on a Web application. The formats used for output remain a development and possibly localisation (l10n) decision. The techniques used by the developer to determine and apply the appropriate locale were outside the scope of this article.

Categories
Apache

Apache Virtual Hosts

Configuring Apache Standalone and XAMPP

When running a server such as Apache standalone or as part of XAMPP, this server is configured as the single listener to at least one network port. For example, by default, Apache will listen to ports 80 and 443, the HTTP and HTTPS default ports. No other server can be listeners to the same ports on the same computer. This means that if you need to host two different Web applications on the same server computer, then you will nut be able to use two different servers.

Apache has a mechanism to cater to this type of situation: virtual hosts. By this mechanism, we can configure multiple Web applications in different folders and on different domain names (or subdomains).

To set up virtual hosts on Apache you will only need to follow 3 steps:

  1. Store the Web application to host in a location accessible to your Apache instance.
  2. Edit the hosts file to add the wanted domains/subdomains.
  3. Add the virtual host configurations to Apache configuration files.

1. Store the Web Application

Place the Web application in the file system by creating a folder and placing your code there. I recommend placing your Web application under the xampp folder, in a subfolder created by your git client – because your Web application code is managed in a git repository, right?

For our example, we will add 2 Web applications in the following folders under the xampp folder: SocialApp and Marketplace.

Make a note of where you have stored your Web applications.

2. Edit the hosts File

Depending on your operating system, you may find the hosts file in one of a few places (check for your exact OS):

  1. In the Windows OS, it is typically located under C:\Windows\System32\drivers\etc\hosts
  2. In Linux distributions, you may find it at /etc/hosts
  3. In MacOS, you may find it at /private/etc/hosts

To edit this file, use an account with administrative privileges in your OS. Under Windows, you may open a text editor such as notepad as administrator by right clicking the application icon and selecting “Open as administrator”. Under Linux and MacOS, you should invoke your editor with sudo, for example.

In our example we will route from 2 subdomains: socialapp.localhost and marketplace.localhost. To perform this change, we will add the 2 following lines to the hosts file:

  1. 127.0.0.1    socialapp.localhost
  2. 127.0.0.1    marketplace.localhost

Thanks to those 2 lines, requests to these addresses will be forwarded to 127.0.0.1, the loopback IP address. General information on the hosts file may be found on Wikipedia.

3. Add the Virtual Host Configurations

Apache Configuration in XAMPP

If you are using XAMPP installed for example in the c:\xampp folder, then open c:\xampp\apache\conf\extra\httpd-vhosts.conf file and add the following at the end of the file:

  1. <virtualhost *:80="">
  2.     ServerAdmin webmaster@email.com
  3.     DocumentRoot "C:/xampp/socialapp"
  4.     ServerName socialapp.localhost
  5.     ErrorLog "socialapp.log"
  6.     CustomLog "socialapp-access.log" common
  7.     <directory "C:/xampp/socialapp">
  8.         AllowOverride All
  9.         Require all granted
  10.     </directory>
  11. </virtualhost>
  12.  
  13. <virtualhost *:80="">
  14.     ServerAdmin webmaster@email.com
  15.     DocumentRoot "C:/xampp/marketplace"
  16.     ServerName marketplace.localhost
  17.     ErrorLog "marketplace.log"
  18.     CustomLog "marketplace-access.log" common
  19.     <directory "C:/xampp/marketplace">
  20.         AllowOverride All
  21.         Require all granted
  22.     </directory>
  23. </virtualhost>
  24.  
  25. <virtualhost *:80="">
  26.     ServerAdmin webmaster@email.com
  27.     DocumentRoot "C:/xampp/htdocs"
  28.     ServerName localhost
  29.     ErrorLog "localhost.log"
  30.     CustomLog "localhost-access.log" common
  31.     <directory "C:/xampp/htdocs">
  32.         AllowOverride All
  33.         Require all granted
  34.     </directory>
  35. </virtualhost>

Notice the entry for localhost that is at the end. Without this entry, access to the htdocs document root for localhost may be broken, even if it is defined elsewhere. Not all instructions are required for this example to be functional. The instructions have the following use:

  • ServerAdmin: (Optional) set the value of $_SERVER[‘SERVER_ADMIN’]
  • DocumentRoot: specify the root folder for this Web application
  • ServerName: specify the domain name for this Web application
  • ErrorLog: (Optional) set the file where errors are logged for this Web application
  • CustomLog: (Optional) set the file where all non-error events are logged for this Web application. The common format will be used to write messages.
  • <Directory tag>: To set the correct root folder access parameters, repeat the document root here.
  • AllowOverride All: Allow all directived in .htaccess
  • Require all granted: All IP addresses may access the Web application

Once these changes are made, Apache must be restarted for changes to take effect. First test the configuration by running

  1. \xampp\apache\bin\httpd -t

Once the output for this reads “Syntax OK”, you are ready to restart Apache. For more information on which options to select and for which reasons, you may consult Apache documentation.

Standalone Apache Configuration

If instead of using XAMPP, you are using Apache standalone, you should create one configuration file per virtual host and place these in the /etc/apache2/sites-available folder. For our example, we will build 2 files.

The first file is /etc/apache2/sites-available/socialapp.conf:

  1. <virtualhost *:80="">
  2.     ServerAdmin webmaster@email.com
  3.     DocumentRoot "C:/xampp/socialapp"
  4.     ServerName socialapp.localhost
  5.     ErrorLog "socialapp.log"
  6.     CustomLog "socialapp-access.log" common
  7.     <directory "C:/xampp/socialapp">
  8.         AllowOverride All
  9.         Require all granted
  10.     </directory>
  11. </virtualhost>

The second file is /etc/apache2/sites-available/marketplace.conf:

  1. <virtualhost *:80="">
  2.     ServerAdmin webmaster@email.com
  3.     DocumentRoot "C:/xampp/marketplace"
  4.     ServerName marketplace.localhost
  5.     ErrorLog "marketplace.log"
  6.     CustomLog "marketplace-access.log" common
  7.     <directory "C:/xampp/marketplace">
  8.         AllowOverride All
  9.         Require all granted
  10.     </directory>
  11. </virtualhost>

To enable configuration changes, run the following commands at yout command line:

  1. sudo a2ensite socialapp
  2. sudo a2ensite marketplace

The above creates the symbolic links between the /etc/apache2/sites-enabled/ folder and the /etc/apache2/sites-available/ configuration files. To ensure the Apache has read all its configuration files, we reload it as follows:

  1. sudo /etc/init.d/apache2 reload

Conclusion

The above instructions apply to many cases but not all installations were considered. If you have a common installation that is not covered in this post, let me know in the comments below.