Skip to content

Microtime

Mistralys edited this page Oct 5, 2023 · 12 revisions

Microtime is an extension of the regular DateTime class, to add support for dates that contain nanoseconds. It also adds a number of utility methods that the vanilla class lacks.

Nanosecond conversion

In general, Microtime will behave exactly like PHP's vanilla DateTime class. If a date contains nanoseconds however, this value is reduced to milliseconds to avoid DateTime parsing errors. Internally, the original DateTime continues to be used to parse date strings.

The nanoseconds can be retrieved using the getNanoseconds() method.

NOTE: Nanoseconds aren't available in PHP as of PHP8.2. The support for them was implemented to be able to parse dates that come from systems that do support them, such as Java.

Usage

The Microtime class is meant as a drop-in replacement of the DateTime class, and since it extends the former, will work even in instanceof DateTime calls.

To create a new instance, there are some handy factory methods:

Create from the current time

This creates a microtime instance for the current time at execution. It allows specifying a time zone, and defaults to the global default time zone on the server.

use AppUtils;

$micro = Microtime::createNow();

This is functionally identical to doing this:

$micro = new Microtime();

However, it has better performance, as it bypasses a number of checks that the constructor uses.

Create from a date string

Date strings are interpreted natively by DateTime. To access the nanosecond information, Microtime offers the getNanoseconds() method:

use AppUtils;

$date = Microtime::createFromString('2021-10-22 19:08:22.333666999');

// Outputs "999"
echo $date->getNanoseconds();

Create from a DateTime instance

use AppUtils;

$vanilla = new DateTime();
$micro = Microtime::createFromDate($vanilla);

Create from a Microtime instance

Calling createFromDate() on a Microtime instance creates a copy of it. The copy inherits the exact time, as well as the time zone. Functionally, it is the same as cloning the instance.

use AppUtils;

$first = Microtime::createNow();
$copy = Microtime::createFromDate($first);

Formatting dates

Format character constants

The DateFormatChars class contains constants for all available date formatting characters, as listed in the offical DateTime documentation. They're named to easily find the needed format, and include complete documentation for each.

The constant names include suffixes to qualify the kind of numeric value returned:

  • _LZ with leading zeros
  • _ZB zero-based number

Some formats can combine both, for example: DateFormatChars::TIME_24_ZB_LZ. This is the 24-based hour, zero-based, with leading zeros.

Examples

use AppUtils;
use AppUtils\Microtime\DateFormatChars;

$micro = Microtime::createNow();

$month = $micro->format(DateFormatChars::MONTH_NAME_LONG);
$hour = $micro->format(DateFormatChars::TIME_12_LZ);

Adding nanoseconds

The Microtime class adds a custom format character to insert the date's nanoseconds, if any. It is available in the constant DateFormatChars::TIME_NANOSECONDS. Using the constant is the preferred way to insert it, as its syntax may change in the future.

use AppUtils;
use AppUtils\Microtime\DateFormatChars;

$micro = Microtime::createFromString('2021-10-22 19:08:22.333666999');

// Outputs "999"
echo $micro->format(DateFormatChars::TIME_NANOSECONDS);

Time Zone utilities

Additional information

The existing DateTime time zone handling is very complete, and no changes have been made to it. However, the getTimezoneInfo() method returns an instance of the TimeZoneInfo utility class, which has methods to access more detailed time zone information.

This example prints all the available time zone information:

use AppUtils\Microtime;

$microtime = new Microtime('2023-10-01T11:45:00.001863219 Europe/Paris');
$info = $microtime->getTimezoneInfo();

print_r($info->toArray());

Output:

array(
   [name] => Europe/Paris
   [offset] => +02:00
   [value] => 7200
   [hours] => 2
   [minutes] => 0
   [seconds] => 7200
   [sign] => +
   [negative] => false 
)

A note on numeric offsets

Because there can be many time zone names within the same time offset, the name detected will possibly not be the expected one. For example, the time offset +02:00 matches Europe/Paris, Europe/Berlin, Europe/Helsinki and more.

NOTE: This isn't specific to Microtime, it is a general date formatting drawback.

It is recommended to use time zone names / identifiers whenever possible, to avoid this issue.

Persistent names

It is possible to work with reliable, persistent time zone names when working with date information programmatically. The NamedTimeZoneInfo class exists specifically for this use case. Instead of getAnyName(), it offers the getName() method, as the returned name can be guaranteed.

An instance of a named time zone can be created like this:

use AppUtils\Microtime\TimeZones\TimeZoneInfo;

// create() also works with an identifier, but this
// method is more explicit in the returned type.
$zone = TimeZoneInfo::createFromName('Europe/Paris');

// Outputs "+02:00"
echo $zone->toOffsetString();

// Outputs "Europe/Paris"
echo $zone->getName();

Such an instance will always retain the name it was created with, even if the Microtime instance is cloned.

NOTE: It is only possible to persist the time zone name in a date string when using the identifier. With a time offset, it gets lost.

New here?

Have a look at the overview for a list of all helper classes available in the package.

Table of contents

Find the current page in the collapsible "Pages" list above, and expand the page, to view a table of contents.

Clone this wiki locally