Author: masak Date: 2010-04-08 23:31:08 +0200 (Thu, 08 Apr 2010) New Revision: 30346
Modified: docs/Perl6/Spec/S32-setting-library/Temporal.pod Log: [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 <r...@rodadams.net> - Larry Wall <la...@wall.org> - Aaron Sherman <a...@ajs.com> - Mark Stosberg <m...@summersault.com> Carl Mäsak <cma...@gmail.com> - Moritz Lenz <mor...@faui2k3.org> - Tim Nelson <wayl...@wayland.id.au> - Daniel Ruoso <dan...@ruoso.com> - Dave Rolsky <auta...@urth.org> - Matthew (lue) <rnd...@gmail.com> + Martin Berends <mbere...@autoexec.demon.nl> + (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> -=over +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> +constructors. -=item Time.new($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 127666216.432) -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: -=over + my $now = DateTime.from_epoch(time); -=item * 12hour +This is such a common use case, that there's a C<DateTime.now> constructor +that does this for you: -=item * 24hour (this and 12hour are essentialy the same system, but for simplicity they are separate) + my $now = DateTime.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 = DateTime.today(); -=item * tai +This has the same effect as doing C<DateTime.now().truncate('day')>; see +'"Set" methods' below. -=back +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 = DateTime.new( :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 +be -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 = DateTime.new( '1969-07-16T20:17:00Z' ); # UTC time -=back +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. -=over +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 Date.new($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>. -=over +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. -=back +The C<day_of_year> method returns the day of the year, a value between 1 and +366. -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 $*CALENDAR) + $dt.ymd('-') (also $dt.date('-')) + $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 processing. +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. -=back +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: -=over + $dt.day = 15; -=item Duration.new($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 +time. -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 = DateTime.new('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: -=back + $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 -=over +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) - -=back - -=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 <r...@rodadams.net> + Larry Wall <la...@wall.org> + Aaron Sherman <a...@ajs.com> + Mark Stosberg <m...@summersault.com> + Carl Mäsak <cma...@gmail.com> + Moritz Lenz <mor...@faui2k3.org> + Tim Nelson <wayl...@wayland.id.au> + Daniel Ruoso <dan...@ruoso.com> + Dave Rolsky <auta...@urth.org> + Matthew (lue) <rnd...@gmail.com>