The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Image::Synchronize::Timestamp - a timestamp class

SYNOPSIS

Create/Parse

  $t = Image::Synchronize::Timestamp->new($text);
  $t2 = $t->new($text2);         # $t2 and $t are unrelated

Or create from the number of seconds since the epoch

  $t = Image::Synchronize::Timestamp->new(6000);

Here are examples of the recognized text formats:

  '2010:06:27 17:44:12+03:00': Exif date format, with timezone offset
  '2010-06-27 17:44:12+03:00': '-' as date separator
  '2010-06-27T17:44:12+03:00': 'T' as date/time separator: ISO 8601
  '2010-06-27T17:44:12+03:00:00': with timezone seconds, too
  '2010:06:27 17:50:00'      : no timezone offset
  '2010:06:27 17:50'         : fewer time components
  '2010:06:27 17+03'         : 17+03 means the same as 17:00+03:00
  '17:44:12+03:00'           : no date
  '17'                       : same as 17:00:00
  '-17:44:12+03:00'          : signed time
  '+17:44:12+03:00'

Assignment/clone:

  $t->clone;                    # assigns a clone
  $t2 = $t; # copies *reference*; $t and $t2 refer to the same object

Stringify

  $t = Image::Synchronize::Timestamp->new('2010-06-27T17:44:12+03:00');
  print "$t";             # (Exif) format;  2010:06:27 17:44:12+03:00
  print $t->stringify;    # same as previous
  print $t->display_iso;  # ISO8601 format: 2010-06-27T17:44:12+03:00
  print $t->display_utc;  # ISO in UTC:     2010-06-27T14:44:12Z
  print $t->display_time; # no date:        +354905:44:12+03:00
  print $t->date;         # Exif date (UTC) 2010:06:27
  print $t->time;         # Exif time (UTC) 14:44:12

Query

Number of non-leap seconds since the epoch

  $time_local = $t->time_local;  # in local timezone
  $time_utc   = $t->time_utc;    # in UTC

Timezone offset in seconds relative to UTC

  $offset = $t->timezone_offset;

Get timezone offset for local system at given instant

  $offset = $t->local_timezone_offset;

Check for presence of parts

  $bool = $t->has_timezone_offset;
  $bool = $t->is_empty;
  $bool = $t->has_date;

Check type

  Image::Synchronize::Timestamp->istypeof($t); # true
  Image::Synchronize::Timestamp->istypeof(3);  # false
  $t->istypeof(3);              # same as previous

Combine

  $t = Image::Synchronize::Timestamp->new('17:44:12+03:00');
  $t2 = $t + 30;                # 17:44:42+03:00
  $t2 = 30 + $t;                # same as previous
  $t3 = $t + $t2;               # ERROR: cannot add two timestamps

  $t2 += 100;                   # shift forward by 100 seconds

  $d = $t2 - $t;                #  30
  $t2 = $t - 20;                #  17:43:52+03:00
  $t3 = -$t;                    # -17:44:12+03:00

  $t3 -= 100;                   # shift backward by 100 seconds

Compare

  $t1 = Image::Synchronize::Timestamp->new('+17:44:12+03:00');
  $t2 = Image::Synchronize::Timestamp->new('+15:44:12+01:00');
  $t3 = Image::Synchronize::Timestamp->new('+17:00:00+03:00');

The following five are true

  $t1 == $t2;                   # same instant, also eq
  $t3 < $t1;                    # also <=, le, lt
  $t2 >= $t3;                   # also >, gt, ge
  $t3 != $t2;                   # not the same instant, also ne
  $t1->identical($t1);          # same clock time and timezone

  $t1 == $t2;            # true: same instant
  $t1->identical($t2);   # false: not same clock time and timezone

Three-way compare

  $t1 <=> $t2;                  # 0: same instant
  $t1 <=> $t3;                  # >0: first one is later
  $t3 <=> $t1;                  # <0: first one is earlier

Modify

  $t->set_from_text($text);     # replace old value
  $t->adjust_timezone_offset($offset); # shift to new timezone
  $t->adjust_to_local_timezone; # of local system at given instant
  $t->adjust_to_utc;
  $t->set_timezone_offset($offset); # keep clock time, replace timezone
  $t->remove_timezone;
  $t->adjust_nodate;            # reinterpret without date
  $t->adjust_todate;            # reinterpret with date

SUBROUTINES/METHODS

new

  $t = Image::Synchronize::Timestamp->new;
  $t = Image::Synchronize::Timestamp->new($value);
  $t2 = $t->new($value);

Construct a new instance. If $value is a number, then it is taken to represent the number of seconds since the epoch, in an undefined timezone. If $value is defined but is not a number, then it is parsed as a timestamp in text format. See "set_from_text" for details of the supported formats.

If $value is specified but no timestamp can be extracted from it, then returns undef. If $value is not specified, then returns an empty instance that can be filled using "set_from_text".

clone

  $t->clone;

Creates a clone of $t. The clone is a "deep copy" so modifying any part of the clone does not affect any part of the original.

Calling clone explicitly is useful if you need to modify the clone and want to leave the original unchanged. For example,

  $t2 = $t->clone->set_timezone(0); # does not modify $t
  $t3 = $t->set_timezone(0);        # modifies $t

stringify

  $text = $t->stringify;
  $text = "$t";

Returns a text version of $t, in Exif format, i.e., using a colon : as separator in the date, time, and timezone parts. Only the time part is always present, the date and timezone parts are only included when present.

The date part looks like '2000:01:02', showing year, month, and day. The time part looks like '03:04:05', showing hour, minute, and second. The timezone part looks like '+06:00', showing signed hour, minute, and (if it is not zero) seconds. The date and time part are separated by one space character. The time and timezone part are not separated.

A full timestamp looks like '2000:01:02 03:04:05+06:00'. This example is for a timezone where the clock time is 6 hours greater than UTC.

If $t is empty (created via "new" or "set_from_text" with no argument), then $t->stringify returns undef, and "$t" returns ''.

display_iso

  $text = $t->display_iso;

Returns a text representation of the timestamp in ISO 8601 format, if the timestamp includes a date, for example 2001-02-23T14:47:22+01:00 for a timestamp representing 14 hours 47 minutes 22 seconds (= 22 seconds past 2:47 pm) on February 23rd of the year 2001.

If the timestamp does not include a date, then returns the same as "display_time", of which the format is not part of ISO 8601.

Is like "stringify" but uses a hyphen - instead of a colon : as separator in the date part, and uses a capital letter T instead of a space as a separator between the date and time part.

If $t is empty (created via "new" or "set_from_text" with no argument), then returns undef.

display_utc

  $text = $t->display_utc;

Returns a text version of $t, in UTC in ISO 8601 format, if the timestamp includes a date. The returned text is like '2000-01-02T03:04:05Z', showing the year, month, day, hour, minute, and second. If $t includes timezone information, then the text version represents the UTC date/time that represents the same instant of time as the original clock date/time in the specified timezone. If $t has no timezone information then it is assumed to be in UTC already.

If the timestamp does not include a date, then returns the same as "display_time", of which the format is not part of ISO 8601.

Is like "display_iso" but uses capital letter Z for the timezone part.

If $t is empty (created via "new" or "set_from_text" with no argument), then returns undef.

Example:

  $t = Image::Synchronize::Timestamp->new('2001-02-03 04:05:06+02:00');
  $text = $t->display_utc;              # '2001-02-03T02:05:06Z'

display_time

  $text = $t->display_time

Returns a text version of $t as a signed time value. The returned text is like '+03:04:05-06:07', showing the signed time (hour, minute, second) since the epoch in the associated timezone, followed by the designation of that timezone. The hour number is not restricted to be less than 24, and can be negative. The example is for a time that is 3 hours 4 minutes 5 seconds since the epoch in a timezone that is 6 hours and 7 minutes earlier than UTC.

This method is useful for timestamps without dates. If $t was created with a date part, then the displayed number of hours is likely to be very large.

Examples:

  $t = Image::Synchronize::Timestamp->new('01:02+03');
  $text = $t->display_time;     # '+01:02:00+03:00'
  $text = "$t";                 # '1970:01:01 01:02:00+03:00'

  $t = Image::Synchronize::Timestamp->new('2001-02-03T04:05');
  $text = $t->display_time; # '+272548:05'
                            # 272548 hours 5 minutes since epoch
  $text = $t->date;

Returns the date part of timestamp $t in Exif format, similar to '2020:08:23'. If $t has a timezone offset, then the date part of a clone adjusted to UTC is returned. If $t has no timezone offset, then the date part of the local time is returned.

  $text = $t->time;

Returns the time part of timestamp $t in Exif format, similar to '11:21:53'. If $t has a timezone offset, then the time part of a clone adjusted to UTC is returned. If $t has no timezone offset, then the time part of the local time is returned.

time_local

  $seconds = $t->time_local;

Returns the number of non-leap seconds since the epoch in the timezone associated with the timestamp, or undef if the timestamp is empty.

time_local returns the same value for two timestamps with the same clock time but different timezone offsets.

Examples:

  $t1 = Image::Synchronize::Timestamp->new('2001-02-03T04:05:06');
  $t2 = $t1->clone->set_timezone(3600); # sets timezone to +01:00

  print $t1->time_local;         # prints 981173106
  print $t2->time_local;         # prints the same

time_utc

  $seconds = $t->time_utc;

Returns the number of non-leap seconds since the epoch in UTC, or undef if the timestamp is empty or has no timezone offset.

time_utc returns different values for two timestamps with the same clock time but different timezone offsets.

Examples:

  $t1 = Image::Synchronize::Timestamp->new('2001-02-03T04:05:06');
  $t2 = $t1->clone->set_timezone_offset(3600); # timezone +01:00
  $t3 = $t1->clone->set_timezone_offset(0);    # timezone UTC = 00:00

  print $t1->time_utc;         # undefined
  print $t2->time_utc;         # 981169506
  print $t3->time_utc;         # 981173106

timezone_offset

  $seconds = $t->timezone_offset;

Returns the timezone offset from UTC in seconds, or undef if no timezone offset is known.

local_timezone_offset

  $seconds = $t->local_timezone_offset

Returns the difference between the local timezone and UTC, in seconds, for the instant of time represented by $t.

If $t has no timezone offset, then it is assumed to be in UTC.

The local timezone is the timezone that is valid at the specified time $t for the system where the current process runs.

For example, if the process runs on a system that believes it is located in Amsterdam, then $t->local_timezone_offset returns 3600 for dates/times $t when standard time (UTC+1) is in effect in Amsterdam, and returns 7200 for dates/times $t when daylight savings time (UTC+2) is in effect in Amsterdam.

has_timezone_offset

  $bool = $t->has_timezone_offset;

Returns a true value if timestamp $t has a timezone offset, and a false value otherwise.

  $bool = $t->is_empty;

Returns a true value if the date/time part of $t is not defined, and a false value otherwise.

  $bool = $t->has_date;

Returns a true value if $t has a date, and a false value otherwise.

istypeof

  $ok = Image::Synchronize::Timestamp->istypeof($item);

  $t = Image::Synchronize::Timestamp->new('02:03');
  $ok = $t->istypeof($item);    # queries $item, not $t

Returns a true value if $item is an instance of (a subclass of) Image::Synchronize::Timestamp, and a false value otherwise, including when $item is not an object.

+

  # $t is an Image::Synchronize::Timestamp
  $sum = $t + $seconds;
  $sum = $seconds + $t;

Returns the timestamp that is $seconds later than timestamp $t. $seconds must be a scalar number.

-

  # $t1, $t2 are Image::Synchronize::Timestamp
  $seconds = $t2 - $t1;         # difference

  $t3 = $t2 - $seconds;         # shift

  $t3 = -$t2;                   # negative

  $t3 = $seconds - $t2;         # shift negative

The first form returns the difference in seconds between the two timestamps $t2 and $t1. If at least one of the two does not have a timezone offset, then both timestamps are assumed to be in the same timezone. If both have a timezone offset, then the difference between the timezone offsets is taken into account.

The second form shifts the timestamp back in time by the specified number of $seconds, which must be a number.

The third form produces the opposite of the timestamp. The time part (the number of seconds since the epoch in the timezone) is multiplied by -1, but the timezone offset (if any) remains the same. This form is mostly useful if the timestamp has no date part.

The fourth form is equivalent to $t3 = (-$t2) + $seconds: produce the negative of $t2 and then shift it to the future by the indicated number of $seconds.

<=>

  $order = $t1 <=> $t2;

Returns -1, zero, or +1 depending on whether timestamp $t1 indicates an earlier, equal, or later instant of time than timestamp $t2. If at least one of the two timestamps has no timezone, then both are assumed to be in the same timezone. The empty timestamp compares less than any defined timestamp, and compares equal to itself.

The following binary comparison operators are likewise available:

       < <= == => >  !=
  cmp lt le eq ge gt ne

identical

  $bool = $t1->identical($t2);

Returns a true value if the two timestamps are identical, and a false value otherwise. The two timestamps are identical if the date/time part and the timezone offset part are identical in both. This method returns false for two timestamps that indicate the same instant of time but have different timezone parts.

set_from_text

  $t->set_from_text($text);

Sets $t to the instant of time expressed by text $text, discarding any previous contents of $t.

The text must specify at least a time, and optionally also a date and a timezone offset.

The date must consist of three numbers (year, month, day) separated by either a colon : or a dash -. The time must consist of from one to three numbers (hour, minute, second) separated by a colon :. The date and time must be separated by a single whitespace or a capital T.

An offset from UTC may be specified, as from one to three numbers, of which the first one must be signed and represents hours, and the remaining ones (if specified) must be separated from the previous by a colon :, and represent minutes and seconds.

These formats include the format of Exif timestamps, for example '2010:06:27 17:44:12+03:00:00' or '2010:06:27 17:50:00', and also the ISO 8601 formats '2010-06-27T17:44:12+03:00' or '2010-06-27T17:50:00'.

The example timestamps with timezone offset represent June 27th of the year 2010, at 44 minutes and 12 seconds past 5 o'clock in the afternoon, in a timezone where the clock reads 3 hours later than UTC. The corresponding UTC time is 14:44:12.

If the text cannot be parsed as a timestamp, then the Image::Synchronize::Timestamp is left without contents.

Returns $t.

adjust_timezone_offset

  $t->adjust_timezone_offset($offset);

Adjusts the timezone offset of $t to <$offset>, if $t is not empty.

If $t already had a timezone offset, then its clock time is adjusted so it refers to the same instant of time as before, but now relative to the new timezone.

If $offset is undef, then the timezone of $t becomes undefined.

Returns the object.

adjust_to_local_timezone

  $t->adjust_to_local_timezone

Adjusts the timezone of timestamp $t to the local timezone appropriate for the local system at the indicated instant of time.

If $t already had a timezone offset, then adjusts the clock time so it refers to the same instant of time as before but now relative to the local timezone.

Returns the adjusted $t.

adjust_to_utc

  $t->adjust_to_utc

Adjusts the timezone of timestamp $t to UTC, if $t is not an empty timestamp.

If $t already had a timezone offset, then adjusts the clock time so it refers to the same instant of time as before but now relative to UTC.

Returns the adjusted $t.

set_timezone_offset

  $t->set_timezone_offset($offset);

Sets the timezone offset of $t to <$offset>, discarding the previous timezone offset if any. The clock time is not adjusted.

If $offset is undef, then the timezone of $t becomes undefined.

Returns the object.

remove_timezone

  $t->remove_timezone

Removes the timezone offset from timestamp $t. The clock time remains the same.

Returns the modified $t.

adjust_nodate

  $t->adjust_nodate;

If timestamp $t has a date, then remove that date by changing $t to the no-date form. The offset from the epoch in seconds is instead interpreted as an offset from an unspecified zero point that is not associated with a particular date.

A timestamp with no date gets stringified to an optionally signed timestamp consisting of hours, minutes, and seconds, optionally with a timezone offset. The number of hours in the timestamp may be much greater than 24.

adjust_todate

  $t->adjust_todate;

If timestamp $t has no date, then add a date by changing $t to the with-date form. The offset from an unspecified zero point not associated with any particular date is instead interpreted as the offset from the epoch.

AUTHOR

Louis Strous <LS@quae.nl>

LICENSE AND COPYRIGHT

Copyright (c) 2016-2020 Louis Strous.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

4 POD Errors

The following errors were encountered while parsing the POD:

Around line 330:

Unknown directive: =head

Around line 347:

Unknown directive: =head

Around line 476:

Unknown directive: =head

Around line 490:

Unknown directive: =head