This page was generated by Text::SmartLinks v0.01 at 2010-06-24 20:02:25 GMT.
(syn r31436)
  [ Index of Synopses ]

TITLE

DRAFT: Synopsis 32: Setting Library - Temporal

AUTHORS

    Carl Mäsak <cmasak@gmail.com>
    Martin Berends <mberends@autoexec.demon.nl>
    Moritz Lenz <moritz@faui2k3.org>
    (and others named in FOOTNOTE at bottom)

VERSION

    Created: 19 Mar 2009
    Last Modified: 8 Apr 2010
    Version: 7

The document is a draft.

If you read the HTML version, it is generated from the Pod in the pugs repository under /docs/Perl6/Spec/S32-setting-library/Temporal.pod -- if you would like to make changes to the document, that's the place to look.

Time and time again

Two chief aspects of a Perl 6 synopsis seem to contribute to it having some extra volatility: how far it sits from the rest of the data model of the language, and how everyday the topic in question is. S32 has always been volatile for these reasons; S32::Temporal doubly so.

The truth is that while there are many interests to satisfy in the case of a Temporal module, and many details to take into account, there's also the danger of putting too much in. Therefore, Perl 6's Temporal module takes the DateTime module on CPAN as a starting point, adapts it to the Perl 6 OO system, and boils it down to bare essentials.

One of the unfortunate traditions that Perl 6 aims to break is that of having a set of "core" modules which could better serve the community on CPAN than in the Perl core. For this reason, this module doesn't handle all the world's time zones, locales, date formatters or calendars. Instead, it handles a number of "natural" operations well enough for most people to be happy, and shows how those who want more than that can load a module, or roll their own variants. Put differently, the below are the aspects of time that are felt to be stable enough to belong in the core.

time

Returns an Instant representing the current time as measured in atomic seconds since the Unix epoch, suitable for feeding to some of the DateTime constructors.

DateTime

A DateTime object describes the time as it would appear on someone's calendar and someone's clock. You can create a DateTime object from the Instant returned by the time function:

    my $now = DateTime.from-epoch(time);

This is such a common use case, that there's a DateTime.now constructor that does this for you:

    my $now = DateTime.now();

General dates can be specified through the new constructor:

    my $moonlanding = DateTime.new( :year(1969), :month(7), :day(16),
                                    :hour(20), :minute(17) ); # UTC time

The full list of named arguments is as follows:

    :year       required
    :month      defaults to 1   range 1..12
    :day        defaults to 1   range 1..31
    :hour       defaults to 0   range 0..23
    :minute     defaults to 0   range 0..59
    :second     defaults to 0   range 0.0..^62.0
    :timezone   defaults to '+0000' (UTC)
    :formatter  defaults to an iso8601 formatter, see below

Another multi exists with Date :date instead of :year, :month and :day (and the same defaults as listed above).

A shorter way to send in date and time information to is providing a single string with a full ISO8601 date and time. The example from above would then be

    my $moonlanding = DateTime.new( '1969-07-16T20:17:00Z' ); # UTC time

The general form is [date]T[time][offset], with [date] given as YYYY-MM-DD and [time] given as hh:mm:ss.

The final Z is a short form for +0000, meaning UTC time. The general notation for the <offset> is +hhmm or -hhmm.

With all the above constructors, if you attempt to pass in values that are outside of the ranges specified in the list above, you'll get an exception. An exception will also be thrown if the particular day doesn't exist in that month (for example April 31st) or in that non-leap year (for example February 29th 2006). By default, no such checking is done against leap seconds. This class also explicitly does not check against ambiguous or invalid local times caused by Daylight Saving Time.

"Get" methods

There are methods year, month, day, hour, minute, and second, giving you the corresponding values of the DateTime object. The day method also has the synonym day-of-month.

The method week returns two values, the week year and week number. (These are also available through the methods week-year and week-number, respectively.) The first week of the year is defined by ISO as the one which contains the fourth day of January. Thus, dates early in January often end up in the last week of the prior year, and similarly, the final few days of December may be placed in the first week of the next year.

There's a day-of-week method, which returns the day of the week as a number 1..7, with 1 being Monday and 7 being Sunday.

The weekday-of-month method returns a number 1..5 indicating the number of times a particular weekday has occurred so far during that month, the day itself included. For example, June 9, 2003 is the second Monday of the month, and so this method returns 2 for that day.

The quarter method returns the quarter of the year, a value between 1 and 4. The day-of-quarter method returns the day of the quarter.

The day-of-year method returns the day of the year, a value between 1 and 366.

The method whole-second returns the second truncated to an integer.

The following methods work as a sort of formatting methods:

    $dt.ymd('-')    (also $dt.date('-'))
    $dt.mdy('-')
    $dt.dmy('-')
    $dt.hms(':')    (also $dt.time(':'))

The single argument of each of those methods is optional, but the above shows the defaults: '-' for dates and ':' for times.

The Date method returns a Date object, and is the same as Date.new(|$dt.ymd).

The timezone method returns the DateTime::TimeZone object for the DateTime object. The method offset returns the offset from UTC, in seconds, of the DateTime object according to the time zone.

The formatter method returns the formatter for the DateTime object.

"Set" methods

To set the the day of a DateTime object to something, just assign to its public accessor:

    $dt.day = 15;

The same methods exists for all the values you can set in the constructor: year, month, day, hour, minute, second, timezone and formatter. Also, there's a set method, which accepts all of these as named arguments, allowing several values to be set at once:

    $dt.set( :year(2014), :month(12), :day(25) );

Just as with the new method, validation is performed on the resulting values, and an exception is thrown if the result isn't a sensible date and time.

If you use the timezone public accessor to adjust the time zone, the local time zone is adjusted accordingly:

    my $dt = DateTime.new('2005-02-01T15:00:00+0900');
    say $dt.hour;     # 15
    $dt.timezone = '+0600';
    say $dt.hour;     # 12

The truncate method allows you to "clear" a number of time values below a given resolution:

    $dt.truncate( :to<hour> ); # clears minutes and seconds

The time units are "cleared" in the sense that they are set to their inherent defaults: 1 for months and days, 0 for the time components.

If you pass in :to<week>, the DateTime object is set to the Monday of the week in which it occurs, and the time components are all set to 0.

Date

Date objects are immutable and represent a day without a time component. They allow easier manipulation by assuming that integers always mean days.

Days, Months and days of week are 1-based.

Constructors

    Date.today();               # today's date
    Date.new(DateTime.now);     # same
    Date.new('2010-12-24');     # YYYY-MM-DD format
    Date.new(:year(2010), :month(12), :day(24));
    Date.new(2010, 12, 24);

The constructors die with a helpful error message if month or day are out of range.

Accessors

The following accessors are pretty obvious, and are defined by example only. See the test suite for more formal definitions.

    my $d = Date.new('2010-12-24');
    $d.year             # 2010
    $d.month            # 12
    $d.day              # 24
    $d.day-of-week      # 5     # Friday
    $d.is-leap-year     # Bool::False
    $d.days-in-month    # 31
    $d.Str              # '2010-12-24'

Arithmetics

    $d.succ                     # Date.new('2010-12-25')
    $d.pred                     # Date.new('2010-12-23')
    $d - Date.new('1984-03-02') # 9793      # (difference in days)
    $d - 42                     # Date.new('2010-11-12')
    $d + 3                      # Date.new('2010-12-27')
    3  + $d                     # Date.new('2010-12-27')

Additions

Please post errors and feedback to perl6-language. If you are making a general laundry list, please separate messages by topic. Please try to keep bikeshedding down.

FOOTNOTE

The authors of the current rewrite want to mention, with thanks, the indirect contribution made by the previous authors:

    The authors of the related Perl 5 docs
    Rod Adams <rod@rodadams.net>
    Larry Wall <larry@wall.org>
    Aaron Sherman <ajs@ajs.com>
    Mark Stosberg <mark@summersault.com>
    Carl Mäsak <cmasak@gmail.com>
    Moritz Lenz <moritz@faui2k3.org>
    Tim Nelson <wayland@wayland.id.au>
    Daniel Ruoso <daniel@ruoso.com>
    Dave Rolsky <autarch@urth.org>
    Matthew (lue) <rnddim@gmail.com>
[ Top ]   [ Index of Synopses ]