Author: ruoso
Date: 2009-09-09 04:26:50 +0200 (Wed, 09 Sep 2009)
New Revision: 28208

Modified:
   docs/Perl6/Spec/S32-setting-library/Temporal.pod
Log:
[spec-S32-Temporal] Complete rewrite of Temporal.pod taking into account today 
IRC talks, TAI time, alternative calendars, time-zone information and, most 
importantly, the perl 5 DateTime API

Modified: docs/Perl6/Spec/S32-setting-library/Temporal.pod
===================================================================
--- docs/Perl6/Spec/S32-setting-library/Temporal.pod    2009-09-08 16:22:13 UTC 
(rev 28207)
+++ docs/Perl6/Spec/S32-setting-library/Temporal.pod    2009-09-09 02:26:50 UTC 
(rev 28208)
@@ -21,8 +21,8 @@
 =head1 VERSION
 
     Created: 19 Mar 2009 extracted from S29-functions.pod and S16-IO.pod
-    Last Modified: 23 Feb 2009
-    Version: 3
+    Last Modified: 8 Sep 2009
+    Version: 4
 
 The document is a draft.
 
@@ -30,169 +30,216 @@
 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.
 
-=head2 Time
+=head1 Current Time
 
+The epoch used in Perl 6 to represent time instants is the
+International Atomic Time - TAI - which is independent of calendars,
+timezones as well as leap seconds. Of course Perl can't go beyond the
+machine to get a real TAI value, but it should perform any
+platform-specific transformation to give you the most precise value it
+can for the TAI.
+
+ our Rat sub time()
+
+Returns a TAI epoch value for the current time.
+
+=head1 Roles
+
+=head2 Calendar
+
+Every DateTime needs to follow the rules of a given calendar. The
+default is the Gregorian calendar, but several other calendars exist
+in the real world.
+
+The current default calendar is stored in $*CALENDAR.
+
 =over
 
-=item gmtime
+=item method calendartime($epoch = time(), *%options)
+=item multi calendartime($epoch = time(), $calendar = $*CALENDAR, *%options)
 
- our Temporal::DateTime multi gmtime ( Num $epoch )
- our Temporal::DateTime multi gmtime ( Rat $epoch = time() )
+Returns a DateTime object in the current calendar for the given TAI
+epoch time. Each calendar type might accept different options.
 
-Identical to:
+Note that simply changing the current calendar is not magically going
+to make any code portable to different calendars. The code using it
+should either use only the methods in the generic Calendar and
+DateTime roles, or special case for the known Calendars.
 
- Time::localtime(:$time,:tz<GMT>)
+=item method formatter is rw
 
-=item localtime
+The default formatter object used for DateTime objects in this
+calendar.
 
- our Temporal::DateTime multi localtime ( Num $epoch )
- our Temporal::DateTime multi localtime ( Rat $epoch = time() )
+=back
 
-These functions take an epoch value and return a C<Temporal::DateTime>
-object. For C<localtime> the time zone is taken from the local
-system. For C<gmtime> the time zone is aways UTC.
+=head2 Calendar::TimeZoneObservant
 
-If no time is provided, the current time is used.
+This is a generic role used to identify all calendars that observe the
+time zones. Not all calendars are time-zone observants. One way or
+another, two multi subs will be available that depend on a time-zone
+observant calendar. They will fail if you try to call them with a
+non-tz calendar.
 
-=item time
+This role also implies that the calendartime method might receive a
+time-zone named parameter.
 
- our Rat time()
+=over
 
-Returns an epoch value for the current time.
+=item method gmtime($epoch = time(), *%options )
+=item multi gmtime($epoch = time(), $calendar = $*CALENDAR, *%options)
 
+Returns a DateTime object in the GMT timezone, considering $epoch to
+be TAI. Same as:
+
+ calendartime($epoch, $calendar, :time-zone('GMT'))
+
+=item method localtime($epoch = time(), *%options )
+=item multi localtime($epoch = time(), $calendar = $*CALENDAR, *%options)
+
+Returns a DateTime object in the local timezone taken from the system,
+considering $epoch to be TAI. Same as:
+
+ calendartime($epoch, $calendar, :time-zone('local'))
+
 =back
 
-=head1 Roles
+=head2 DateTime
 
-The intent behind these classes is to provide an absolutely minimal,
-but still useful, set of core behavior. The assumption is that the
-core will ship with a simple set of classes so that C<gmtime> and
-C<localtime> have something to return.
+The generic DateTime role specifies the basic operations that should
+be possible independent of the Calendar being used, and are,
+therefore, considerably restricted.
 
-=head2 Temporal::Date
+In order to make it easier to deal with the most common scenario, the
+contructor of the bare DateTime type will delegate to
+Gregorian::DateTime.
 
-You probably want to use the Temporal::DateTime object instead.
+It defines the following attributes.
 
-    role Temporal::Date {
-        my subset Month of Int where { 1 <= $^a <= 12 };
-        my subset Day of Int where { 1 <= $^a <= 31 };
-        my subset DayOfWeek of Int where { 1 <= $^a <= 7 };
+=over
 
-        has Int   $.year;
-        has Month $.month = 1;
-        has Day   $.day = 1;
+=item formatter
 
-        # This can be cached internally, but it's a calculated value,
-        # not an attribute.
-        our DayOfWeek method day-of-week ();
+The object that will stringify this specific object.
 
-        # These always return the long English names
-        our Str method month-name () ; # "January"
-        our Str method day-name ();   # "Tuesday"
+=item calendar
 
-        # returns the date formatted in ISO8601 style - 2008-01-25
-        our Str method iso8601 () {
-            [ self.year, self.month, self.date ].join('-');
-        }
+Returns the calendar that governs this datetime.
 
-        method Str { self.iso8601 };
+=back
 
-        multi method infix:{'<=>'} (Temporal::Date $self, Temporal::Date 
$other) {
-            $self.year <=> $other.year
-            ||
-            $self.month <=> $other.month
-            ||
-            $self.day <=> $other.day;
-        }
-    }
+And the following methods
 
-Example:
+=over
 
-$date = Date.new( :year(2008), :month(1), :day(25) );
-$date.month(); # 1
+=item tai
 
-=head2 Temporal::Time
+Returns the TAI value for this specific datetime, usefull for
+inter-calendar comparison and conversion.
 
-You probably want to use the Temporal::DateTime object instead.
+=back
 
-    role Temporal::Time {
-        my subset Hour   of Int where { 0 <= $^a <= 23 };
-        my subset Minute of Int where { 0 <= $^a <= 59 };
-        my subset Second of Num where { 0 <= $^a <= 60 };
+=head2 Duration
 
-        has Hour   $.hour = 0;
-        has Minute $.minute = 0;
-        has Second $.second = 0;
+Duration objects describe an amount of time, it's the fundamental type
+for DateTime math. It is also very calendar-dependent, in a way that
+only a very fundamental data is seen here.
 
-        our Str method iso8601 ()
-            { [ self.hour, self.minute, self.second ].join(':') }
+As with DateTime, to make the most common case easier, this type
+delegates the constructor to Gregorian::Duration.
 
-        method Str { self.iso8601() };
+The following method is implemented by all Duration objects.
 
-        multi method infix:{'<=>'} (Temporal::Time $self, Temporal::Time 
$other) {
-            $self.hour <=> $other.hour
-            ||
-            $self.minute <=> $other.minute
-            ||
-            $self.second <=> $other.second
-        }
-    }
+=item tai
 
-=head2 Temporal::TimeZone::Observance
+Returns the amount of TAI seconds described in this duration. Note
+that usually you shouldn't be doing math with the result of .tai for
+different datetime and duration objects. The result of .tai might also
+be an estimated value for Duration types that depend on an anchor date
+(i.e.: 1 month).
 
-role    Temporal::TimeZone::Observance {
-        my subset Offset of Int where { -86400 < $^a < 86400 };
+=head2 TimeZone
 
-        has Offset $.offset;
-        has Bool   $.isdst;
-        has Str    $.abbreviation; # CST, AST
+This is the base for the entire time-zone database with the complete
+information about daylight-saving-time and other variations that can
+happen.
 
-        # The ISO8601 standard does not allow for offsets with
-        # sub-minute resolutions. In real-world practice, this is not
-        # an issue.
-        our Str method iso8601 {
-            my $hours = self.offset.abs / 3600;
-            my $minutes = self.offset.abs % 3600;
+This should be a straight port from perl 5 DateTime::TimeZone module.
 
-            return self.offset < 0 ?? '-' :: '+'
-                   ~ $hours.fmt('%02d')
-                   ~ $minutes.truncate.fmt('%02d');
-        }
+=head2 TimeRange
 
-        method Str { self.iso8601 }
-}
+This object represents a given period of time, it might be composed
+by:
 
-This is called an I<observance> because it represents the state of a
-time zone for a given instant. A real Temporal::TimeZone role would
-return an observance when given a particular datetime.
+=over
 
-We don't specify a proper C<Temporal::TimeZone> role because time
-zones are messy and complex. The system libraries are able to give us
-sufficient information to create an observance for a time, but are not
-able to give us proper time zone information.
+=item Start and end DateTime
+=item Start DateTime and Duration
+=item Duration and end DateTime
 
-=head2 Temporal::DateTime
+=back
 
-    role Temporal::DateTime {
-        has Temporal::Date $!date handles <year month day day-of-week>;
-        has Temporal::Time $!time handles <hour minute second 
fractional-second>;
-        has Temporal::TimeZone::Observance $!timezone handles <offset isdst>;
+It might also contain a "step" Duration, which should allow iterating
+a set of values within the range. A TimeRange might be obtained with
+the infix:<..> operator and optionally using a :by adverb to indicate
+the step.
 
-        our Str method iso8601 () {
-            self.date.iso8601 ~ 'T' ~ self.time.iso8601 ~ 
self.timezone.iso8601;
-        }
+For instance
 
-        method Str { self.iso8601 }
+  $datetime .. $duration :by($step_duration)
+  $datetime ^.. $datetime :by($step_duration)
+  $duration ..^ $datetime :by($step_duration)
 
-        # This involves a whole bunch of code - see Perl 5's
-        # Time::Local
-        our Num method epoch { ... }
+=head2 Gregorian::Calendar
 
-        method Int { self.epoch.truncate }
+Also known as the "civil" calendar. This is the calendar used in most
+of the world, specially in the western countries.
 
-        method Num { self.epoch }
-    }
+=head2 Gregorian::DateTime
 
+The gregorian DateTime declares the following additional attributes.
+
+=over
+
+=item year
+
+=item month
+
+=item day
+
+=item minute
+
+=item second
+
+=item nanosecond
+
+=item time-zone
+
+=back
+
+=head2 Gregorian::Duration
+
+The gregorian Duration declares the following attributes.
+
+=over
+
+=item year
+
+=item month
+
+=item day
+
+=item minute
+
+=item second
+
+=item nanosecond
+
+=item time-zone
+
+=back
+
+
 =head1 Additions
 
 Please post errors and feedback to perl6-language.  If you are making

Reply via email to