Author: masak
Date: 2010-04-08 23:31:08 +0200 (Thu, 08 Apr 2010)
New Revision: 30346

[S32::Temporal] big change, based on much discussion

A number of people spent last Sunday discussing various solutions to
the Temporal module. This is the result; probably a better idea to read
the new file rather than the diff. Briefly, the Temporal you're seeing
here is a stripped-down version of CPAN's DateTime; simple, yet powerful.

Modified: docs/Perl6/Spec/S32-setting-library/Temporal.pod
--- docs/Perl6/Spec/S32-setting-library/Temporal.pod    2010-04-08 19:28:35 UTC 
(rev 30345)
+++ docs/Perl6/Spec/S32-setting-library/Temporal.pod    2010-04-08 21:31:08 UTC 
(rev 30346)
@@ -7,170 +7,218 @@
 =head1 AUTHORS
-    The authors of the related Perl 5 docs
-    Rod Adams <>
-    Larry Wall <>
-    Aaron Sherman <>
-    Mark Stosberg <>
     Carl Mäsak <>
-    Moritz Lenz <>
-    Tim Nelson <>
-    Daniel Ruoso <>
-    Dave Rolsky <>
-    Matthew (lue) <>
+    Martin Berends <>
+    (but see FOOTNOTE at bottom)
 =head1 VERSION
-    Created: 19 Mar 2009 extracted from S29-functions.pod and S16-IO.pod
+    Created: 19 Mar 2009
-    Last Modified: 2 Apr 2010
-    Version: 6
+    Last Modified: 5 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 so edit it 
there in
-the SVN repository if you would like to make changes.
+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.
-=head1 Temporal
+=head1 Time and time again
-Time is just a jumbled iTem.
+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. C<S32> has always been
+volatile for these reasons; C<S32::Temporal> doubly so.
-Temporal is divided into two parts: date and time.
+The truth is that while there are many interests to satisfy in the case of a
+C<Temporal> module, and many details to take into account, there's also the
+danger of putting too much in. Therefore, Perl 6's C<Temporal> module takes
+the C<DateTime> module on CPAN as a starting point, adapts it to the Perl 6
+OO system, and boils it down to bare essentials.
-=head2 Time
+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 is called upon as such:
+=head1 C<time>
+Returns an C<Instant> representing the current time as measured in atomic
+second since the epoch, suitable for feeding to some of the C<DateTime>
-=item$timesystem = $*CLOCK, $time = $*NOW)
+=head1 C<DateTime>
-Creates a new Time object. $timesystem is what clock you wish to use. If 
unspecified, whatever is in $*CLOCK is used. $time specifies the $time, it 
defaults to what is in $*NOW. What you enter in $time should match the format 
that $timesystem is in. $*NOW and $*CLOCK should be specified in the same 
format (i.e., if $*CLOCK is 'unixepoch', $*NOW should be something like 
-Possible (string!) values for $timesystem (and therefore $*CLOCK) are:
+A C<DateTime> object describes the time as it would appear on someone's
+calendar and someone's clock. You can create a C<DateTime> object from the
+C<Instant> returned by the C<time> function:
+    my $now = DateTime.from_epoch(time);
-=item * 12hour
+This is such a common use case, that there's a C<> constructor
+that does this for you:
-=item * 24hour (this and 12hour are essentialy the same system, but for 
simplicity they are separate)
+    my $now =;
-=item * hextime
+If you're interested in the current date but not the time, you can use
+the C<today> method instead:
-=item * unixepoch
+    my $today =;
-=item * tai
+This has the same effect as doing C<'day')>; see
+'"Set" methods' below.
+General dates can be specified through the C<new> constructor:
-If the time system you want is not up on the list, you are at the mercy of the 
implementation (which can, of course, add in rarer time systems) and/or 
available libraries and other addons. A shortcut to the time (in the default as 
defined by $*CLOCK) is through the $*TIME variable.
+    my $moonlanding = :year(1969), :month(7), :day(16),
+                                    :hour(20), :minute(17) ); # UTC time
-=item Time.convert($convertto = $*CLOCK)
+The full list of named arguments is as follows:
-returns the time converted to the time system specified in $convertto. If you 
were to call convert(), then it would default to what's in $*CLOCK
+    :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..61
+    :nanosecond defaults to 0
+    :timezone   defaults to '+0000' (UTC)
+    :formatter  defaults to an iso8601 formatter, see below
-=item Time.format($formatto)
+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
-returns the time formatted to the way specified in $formatto. If the time has 
no options for formatting (for example hextime can be either 3_A0_9 or .3A09, 
but a 24 hour clock is typically only formatted as 15:17), or $formatto is left 
blank, it is sent back without processing.
+    my $moonlanding = '1969-07-16T20:17:00Z' ); # UTC time
+The general form is C<< <date>T<time><offset> >>, with C<< <date> >> given
+as C<YYYY-MM-DD> and C<< <time> >> given as C<hh:mm:ss>.
-=head2 Date
+The final C<Z> is a short form for C<+0000>, meaning UTC time. The general
+notation for the C<< <offset> >> is C<+hhmm> or C<-hhmm>.
-Date is called in a similar fashion:
+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 1996). 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.
+If you pass in a C<:nanosecond> value greater or equal to one billion (1e9),
+it will be normalized, and the excess seconds will be transferred to the
+C<:second> value.
-=item$datesystem = $*CALENDAR, $date = $*TODAY)
+=head2 "Get" methods
-Defines a new Date object. $datesystem defines the calendar to use. If not 
specified, it defaults to what is in $*CALENDAR. $date specifies the date. If 
not specified, then the date used is the one in $*TODAY. Make sure $date is in 
the same format as specified in $datesystem. $*CALENDAR and $*TODAY should be 
specified in the same calendar (i.e. if $*CALENDAR is 'Gregorian' $*TODAY 
should be something like '12-31-10', depending on how things are formatted)
-Possible string values for $datesystem (and therefore $*CALENDAR) are:
+There are methods C<year>, C<month>, C<day>, C<hour>, C<minute>, C<second>,
+and C<nanosecond>, giving you the corresponding values of the C<DateTime>
+object. The C<day> method also has the synonym C<day_of_month>.
+The method C<week> returns two values, the I<week year> and I<week number>.
+(These are also available through the methods C<week_year> and C<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.
-=item * Gregorian
+There's a C<day_of_week> method, which returns the day of the week as a number
+1..7, with 1 being Monday and 7 being Sunday.
-=item * Julian (the predecessor of Gregorian. NOT the astronomical Julian Year)
+The C<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.
-=item * Discordian
+The C<quarter> method returns the quarter of the year, a value between 1 and 4.
+The C<day_of_quarter> method returns the day of the quarter.
+The C<day_of_year> method returns the day of the year, a value between 1 and
-There aren't that many calendar in use today (heck, Discordian is up there 
only because you can get it using ddate, a command found on almost every Linux 
distribution). If you need something different from what is on the list, you 
are at the mercy of the implementation and any available libraries/modules. You 
can shortcut to the current date in the default calendar (in $*CALENDAR), by 
using the $*DATE variable.
+The method C<fractional_second> returns the second as a real number, with the
+fractional part coming from the C<nanosecond> value. The methods
+C<millisecond>, C<microsecond>, and C<nanosecond> return the nanosecond part
+in the corresponding unit, rounded to an integer.
-=item Date.convert($convertto = $*CALENDAR)
+The following methods work as a sort of formatting methods:
-Returns the date in the format specified in $convertto (defaults to what's in 
+    $dt.ymd('-')    (also $'-'))
+    $dt.mdy('-')
+    $dt.dmy('-')
+    $dt.hms(':')    (also $dt.time(':'))
-=item Date.format($formatto)
+The single argument of each of those methods is optional, but the above shows
+the defaults: C<'-'> for dates and C<':'> for times.
-Formats the date (i.e. 4/2/10 or 2 April 2010 in Gregorian) to what's 
specified in $formatto. If unspecified, it returns the date without any 
+The C<time_zone> method returns the C<DateTime::TimeZone> object for the
+C<DateTime> object. The method C<offset> returns the offset from UTC, in
+seconds, of the C<DateTime> object according to the time zone.
+The C<formatter> method returns the formatter for the C<DateTime> object.
-=head2 Duration
+=head2 "Set" methods
-A duration is a certain length of time (i.e. from 12:00 to 14:15, the duration 
can be said to be 2:15).
+To set the the day of a C<DateTime> object to something, just assign to its
+public accessor:
+    $ = 15;
-=item$begin = 0, $end, $format)
+The same methods exists for all the values you can set in the constructor:
+C<year>, C<month>, C<day>, C<hour>, C<minute>, C<second>, C<nanosecond>,
+C<time_zone> and C<formatter>. Also, there's a C<set> method, which accepts
+all of these as named arguments, allowing several values to be set at once:
-Specifies a new Duration object. $begin is at the beginning of duration (i.e. 
4 seconds), $end is the end of the duration (i.e. 72 seconds), and $format is 
in what format $begin and $end are in. $format can be anything that either 
$*CLOCK or $*CALENDAR can be.
+    $dt.set( :year(2014), :month(12), :day(25) );
-=item Duration.convert($convertto)
+Just as with the C<new> method, validation is performed on the resulting
+values, and an exception is thrown if the result isn't a sensible date and
-returns the Duration in the format as specified by $convertto. It defaults to 
doing nothing.
+If you use the C<time_zone> public accessor to adjust the time zone, the
+local time zone is adjusted accordingly:
-=item Duration.format($formatto)
+    my $dt ='2005-02-01T15:00:00+0900');
+    say $dt.hour;     # 15
+    $dt.time_zone = '+0600';
+    say $dt.hour;     # 12
-Returns the Duration formatted as specified in $formatto. If the time given 
cannot be formatted (i.e. 13:47, which has no common alternative format), it 
returns the duration as it was entered.
+The C<truncate> method allows you to "clear" a number of time values below
+a given resolution:
+    $dt.truncate( :to<hour> ); # clears minutes, seconds, and nanoseconds
-=head2 Arithmetic
+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.
-Any sort of arithmetic between Time, Date, and Duration objects require these 
objects to give the equivalent of that object's data (13:15 or 3/4/10) in TAI 
seconds first. What's returned is a Duration object, because it can be 
formatted however you wish using Duration's convert and format.
+If you pass in C<< :to<week> >>, the C<DateTime> object is set to the Monday
+of the week in which it occurs, and the time components are all set to 0.
-=head2 Specifics on formats
+=head1 Additions
-Whenever a date/time format is added/removed to/from the spec, please update 
this listing. This listing describes how each date/time format stores 
information, and available formatting.
+Please post errors and feedback to C<perl6-language>. If you are making
+a general laundry list, please separate messages by topic. Please try to
+keep bikeshedding down.
-Formatting options are those used in the unix utility date (search for 
Date_(Unix) on wikipedia for the formatting options), mapped to the current 
date/time as best as possible.
+=head1 FOOTNOTE
+The indirect contribution of the previous authors prevents the authors of
+the current rewrite to fail to mention:
-=item Twelve Hour
-The twelve-hour format should store the data as an array, containing the hour, 
minute, second, AM/PM, and if the interpreter chooses, parts less than a 
second. The only format it can be in is 12:31:07 AM)
-=item Twenty-Four Hour
-The twenty-four-hour format is the same as 12 Hour, except for the the fact 
that AM/PM is not needed.
-=item Hextime
-Hextime should be stored as an array of strings, consisting of the hexhour, 
hexminute, and hexsecond (alternatively, it could also be held as a hex hour, 
hex maxime, hex minute, and hex second). The time can be formatted either as 
.3A02 or 3_A0_2 (if stored as maxime & hexminute, they must combine as one. i.e 
in 3_A0_2, A is the maxime, and 0 is the hexminute. If stored as 
hex-hour/minute/second, then A0 is the minute.)
-=item Unix Epoch & TAI
-Both are stored as a # of seconds, and only shown/formatted as such.
-=item Gregorian
-Gregorian ought to be stored in an array as the day, month, and year, along 
with the name of the day. Year can either be a +/- number, or you can add 
another element for AD and BC. It can be formatted in any myriad of ways, 
including: "Sunday, April 4th, 2010", or "4/2/10".
-=item Julian
-Same as Gregorian in terms of storage and formatting. (Just remember that 
Julian != Gregorian)
-=item Discordian
-Stored in an array as the year, the season, and the day of the season. 
Formatting is similar to Gregorian & Julian (see the man page for ddate for a 
list of Discordian format options)
-=head1 Additions
-Please post errors and feedback to perl6-language.  If you are making
-a general laundry list, please separate messages by topic.
+    The authors of the related Perl 5 docs
+    Rod Adams <>
+    Larry Wall <>
+    Aaron Sherman <>
+    Mark Stosberg <>
+    Carl Mäsak <>
+    Moritz Lenz <>
+    Tim Nelson <>
+    Daniel Ruoso <>
+    Dave Rolsky <>
+    Matthew (lue) <>

Reply via email to