2CN4sip - Time::PT.pm (PipTime) created by Pip@CPAN.Org to define simple objects for storing instants in time. Desc: PT describes a simple object which encapsulates 10 fields: Century, Year, Month, Day, hour, minute, second, frame, jink, zone where frame is normally 1/60th-of-a-second && jink is normally 1/60th-of-a-frame. The objects describe a high-precision time- instant with fields in decending order of precision such that alphabetic listings will (typically) show time ascension && field arithmetic can be easily performed. PT objects can be added to / subtracted from Time::Frame objects to yield new specific PT instants. The common use of PT is for a simple `pt` utility to en/decode dates && times using seven (7) Base64 characters. 1st: '0A1B2C3' 2nd: 'Yd:2003,j:A7_,M:a3I' or 'f:3aL9.eP' if field name ends with d, value is read as decimal nstd of default b64. Third way is super verbose decimal strings: '15 years, 3 months, 7 weeks, 4 jinx' can use any (or none) sep but : 4th is hash Total Jinx possible for PT: 1,680,238,080,000,000 (1.7 quatrillion) JnxPTEpoch -> `pt __nWO0000` -> Midnight Jan. 1 7039 BCE PTEpoch -> `pt _nWO` -> Midnight Jan. 1 1361 CE PT members: new inits either with pt-param, expanded, or empty epoch_(seconds|frames|jinx)() methods (optional frames/jinx as floats) ptepoch_(seconds|frames|jinx)() methods (since ptEpoch (`pt _nWO` Midnight, Jan1,1361)) settle fields with options (like return new Frame object with only total secs of old) re-def frame as other than 60th-of-a-second re-def jink as other than 60th-of-a-frame eg. def f && j limits as 31.6227766016838 (sqrt(1000)) for ms jinx or just def f as 1000 for exactly ms frames allow month/year modes to be set to avg or relative My Base64 encoding uses characters: 0-9 A-Z a-z . _ since I don't like having spaces or plusses in my time strings. I need times to be easy to append to filenames for very precise, consice, time-stamp versioning. Each encoded character represents (normally) just a single date or time field. All fields are 0-based except Month && Day. The fields are: Year-2000, Month, Day, Hour, Minute, Second, Frame (60th-of-a-second) There are three (3) exceptions to the rule that each character only represents one date or time field. The bits are there so... why not? =) 0) Each 12 added to the Month adds 64 to the Year. 1) 24 added to the Hour adds 320 to the Year. 2) 31 added to the Day makes the year negative just before adding 2000. So with all this, any valid pt (of 7 b64 characters) represents a unique instant (precise down to a Frame [60th-of-a-second]) that occurred or will occur between the years 1361 && 2639 (eg. New Year's Day of each of those years would be '_nWO' && '_n1O'). These rules break down as: Hour Day Month Year YearWith2000 24-47 32-62 49-60 -639- -576 1361-1424 37-48 -575- -512 1425-1488 25-36 -511- -448 1489-1552 13-24 -447- -384 1553-1616 1-12 -383- -320 1617-1680 0-23 32-62 49-60 -319- -256 1681-1744 37-48 -255- -192 1745-1808 25-36 -191- -128 1809-1872 13-24 -127- -64 1873-1936 1-12 -63- -0 1937-2000 0-23 1-31 1-12 0- 63 2000-2063 13-24 64- 127 2064-2127 25-36 128- 191 2128-2191 37-48 192- 255 2192-2255 49-60 256- 319 2256-2319 24-47 1-31 1-12 320- 383 2320-2383 13-24 384- 447 2384-2447 25-36 448- 511 2448-2511 37-48 512- 575 2512-2575 49-60 576- 639 2576-2639 Notz: PT + Frame can become the core of a new input language which accounts for time. It could be game sequences like a fireball that can be rolled from d->df && df->f only at a certain speed ... but then also later maybe time-sensitive computer input like typematic key repeat rate but configurable... smarter? The combinatorics on the X-Box Live pswd is 8**4 == 4096 (butn: u,d,l,r,x,y,L,R) so even exhausting the search space (assuming you're too wise for a smpl likely 4-char sequence) could be finished manually in about 9 hours if you complete a test cycle each 8 seconds. Automated would need programmable circuit... plug that thang into USB && make an easy sequencer PT+Frame- based IF to perform! So cool! Could create an easy IF to setup any sort of practice scenario, programmable pad behavior, or even store replays as device inputs && feed them back in... woohoo that's fscking cool! GameOver specialty =) umm it would basically need the same IF as a fighting game tool hehe =). Don't need Math::BigInt to store pt epoch seconds (pte's) because perl's floats already have enough precision to store them. Use the fractional part of those values to store 60ths && don't use builtin timelocal functions which only accept 1970-2036 (or whatever limited) epoch seconds (only 32-bit ints or something =( ). Interaction with other Time modules: Time::Period - just have an Epoch export option && Period can use it Time::Avail - doesn't seem useful to my purposes Time::Piece - might be nice to mimic this module's object interface Time::Seconds - handy for dealing with lots of seconds but about 60ths? old 5-char pt examples: (update these when there's time) Xmpl: `pt 01` == localtime(975657600) # seconds since Epoch `pt 1L7Mu` == unpack time (Sun Jan 21 07:22:56 2001) `pt _VNxx` == localtime(1143878399) `pt pt` == unpack current pt (akin to `pt `pt``) `pt e` == localtime (eg. Thu Jan 21 07:22:56 2001) `pt e e` == current epoch seconds `pt 1L7Mu e` == convert from pt to epoch (980090576) `pt 975657600 E` == convert from Epoch seconds to pt (01) `pt Jan 21, 2001 07:22:56` -> 1L7Mu `pt Sun Jan 21 07:22:56 2001` -> 1L7Mu `pt 1L7Mu cmp FEET0` -> lt `pt FEET0 cmp 1L7Mu` -> gt `pt 2B cmp 2B` -> eq timelocal($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) NAME Time::PT - objects to store an instant in time VERSION This documentation refers to version 1.0.41M4cZH of Time::PT, which was released on Thu Jan 22 04:38:35:17 2004. SYNOPSIS use Time::PT; my $f = Time::PT->new(); print "PipTime is: $f\n"; print 'The Day-of-Week today is: ', $f->dow(), "\n"; DESCRIPTION This module has been adapted from the Time::Piece module written by Matt Sergeant && Jarkko Hietaniemi . Time::PT inherits base data structure && object methods from Time::Fields. PT was written to simplify storage && calculation of encoded, yet distinct && human-readable, time data objects. This module (Time::PT) does not replace the standard localtime && gmtime functions like Time::Piece but Time::PT objects behave almost identically to Time::Piece objects otherwise (since it was adapted from... I said that already =) ). 2DO - mk interoperable w/ Time::Seconds objects - add Time::Zone stuff to use && match zone field reasonably - flesh out constructor init data parsing && formats supported - consider epoch functions like _epoch([which epoch]) or individuals like _jinx_epoch() - mk PT->new able to create from different 'epoch' init types - fix weird 0 month && 0 day problems - replace legacy pt() with new() wrapper - What else does PT need? WHY? The reason I created PT was that I have grown so enamored with Base64 representations of everything around me that I was compelled to write a simple clock utility ( `pt` ) using Base64. This demonstrated the benefit to be gained from time objects with distinct fields && configurable precision. Thus, Time::Fields was written to be the abstract base class for: Time::Frame ( creates objects which represent spans of time ) && Time::PT ( creates objects which represent instants in time ) HOW? I've made up some silly sentences as mnemonic devices to help me remember every 4th uppercase Base64 character: Can 12 Noon MonthOfYear will be less or equal to 'C'. Goats 16 4 PM Keep 20 8 PM Oats 24 Midnight HourOfDay will be less than 'O'. Some 28 Where? 32 DayOfMonth will be less than 'W'. Cwelve Cool COW (Month Hour Day thresholds) Gixteen Guys Girls Kwenty Keep Keep Onty4 On On Swenty8 Sayin' Sayin' Sippin' Whirty2 Wassup WeeDoggies Water USAGE Many of Time::PT's methods have been patterned after the excellent Time::Piece module written by Matt Sergeant && Jarkko Hietaniemi . new(, ) Time::PT's constructor can be called as a class method to create a brand new object or as an object method to copy an existing object. Beyond that, new() can initialize PT objects 3 different ways: -1) eg. Time::PT->new('3C79jo0'); 0) 'str' => eg. Time::PT->new('str' => '0A1B2C3D4E'); 1) 'list' => eg. Time::PT->new('list' => [0, 1, 2..9]); 2) 'hash' => eg. Time::PT->new('hash' => {'jink' => 8, 'year' => 2003}) color() This is an object member which will join Base64 representations of each field that has been specified in use() && joins them with color-codes or color escape sequences with formats for varied uses. Currently available DestinationColorTypeFormats are: 'ANSI' # eg. \e[1;32m 'zsh' # eg. %{\e[1;33m%} 'HTML' # eg. 'Simp' # eg. RbobYbGbCbUbPb pt This function is the legacy procedural version of my command-line PipTime utility. It will be removed in the near future when the object methods fully replace all the old behavior && have been tested sufficiently. This function && the following ptcc() are the only functions exported when Time::PT is used. ptcc() Returns the Simp color code string appropriate for pt (PipTime) data. Format Returned color code string 'k' the background will change along with the foreground for standard time-of day elements (ie. hms on a dark blue background) 'f' color codes for the expanded pt format (eg. color codes corresponding to Sun Jan 4 12:41:48:13 2004) This function && the previous legacy pt() are the only functions exported when Time::PT is used. The following methods allow access to individual fields of Time::PT objects: $t->C or $t->century $t->Y or $t->year $t->M or $t->month $t->D or $t->day $t->h or $t->hour $t->m or $t->minute $t->s or $t->second $t->f or $t->frame $t->j or $t->jink $t->z or $t->zone Any combination of above single letters can be used as well. Following are some common useful examples: $t->hms # returns list of fields eg. [12, 34, 56] $t->hms(12, 56, 34) # sets fields: h = 12, m = 56, s = 34 $t->hmsf # [12, 34, 56, 12] $t->hmsfj # [12, 34, 56, 12, 34] $t->hmsfjz # [12, 34, 56, 12, 34, 16] $t->time # same as $t->hms $t->alltime # same as $t->hmsfjz $t->YMD # [2000, 2, 29] $t->MDY # [ 2, 29, 2000] $t->DMY # [ 29, 2, 2000] $t->CYMD # [ 20, 0, 2, 29] $t->date # same as $t->YMD $t->alldate # same as $t->CYMD $t->CYMDhmsfjz # [ 20, 0, 2, 29, 12, 13, 56, 12, 13, 16] $t->pt7 # same as $t->YMDhmsf $t->all # same as $t->CYMDhmsfjz $t->dt # same as $t->CYMDhmsfjz "$t" # same as $t->CYMDhmsfjz except only prints # fields which are "used" which by default # is the same as the $t->YMDhmsf of pt7() Method names can be in any case with the following exceptions. Special handling exists to resolve ambiguity between the Month && minute fields. If a lowercase 'm' is used adjacent to a 'y' or 'd' of either case, it is interpreted as Month. Otherwise, the case of the 'm' distinguishes Month from minute. An uppercase 'M' is ALWAYS Month. An adjacent uppercase 'H' or 'S' will not turn an uppercase 'M' into minute. Method names which need to specify Month or minute fields can also optionally specify the distinguishing vowel ('o' or 'i') instead of 'M' or 'm'. $t->ymd # same as $t->YMD $t->dmy # same as $t->DMY $t->MmMm # Month minute Month minute $t->HMS # hour Month second! NOT same as $t->hms $t->yod # same as $t->YMD $t->chmod # Century hour minute Month Day $t->FooIsMyJoy # frame Month Month minute second Month Year # jink Month Year After importing this module, when you use localtime or gmtime in a scalar context, you DO NOT get a special Time::PT object like you would when using Time::Piece. This module relies on a new() constructor instead. The following methods are available on Time::PT objects though && remain as similar to Time::Piece functionality as makes sense. $t->frm # also as $t->frame && $t->subsecond $t->sec # also available as $t->second $t->min # also available as $t->minute $t->hour # 24 hour $t->mday # also available as $t->day_of_month $t->mon # 1 = January $t->_mon # 0 = January $t->monname # Feb $t->month # same as $t->mon # *NOTE* The above definition ( of $t->month() ) is # different from the Time::Piece interface which defines # month() the same as monname() instead of mon(). $t->fullmonth # February $t->year # based at 0 (year 0 AD is, of course 1 BC) $t->_year # year minus 1900 $t->yy # 2 digit year $t->wday # 1 = Sunday $t->_wday # 0 = Sunday $t->day_of_week # 0 = Sunday $t->wdayname # Tue $t->day # same as mday # *NOTE* Similar to month(), I've defined day() # differently from Time::Piece which makes it the same # as wdayname() instead of mday(). $t->fullday # Tuesday $t->yday # also available as $t->day_of_year, 0 = Jan 01 $t->isdst # also available as $t->daylight_savings The following functions return a list of the named fields. The return value can be joined with any desirable delimiter like: join(':', $t->hms); join($t->time_separator, $t->hms); but the functions also can take a list of parameters to update the corresponding named fields like: $t->YMD( 2003, 12, 8 ) # assigns new date of December 8th, 2003 to $t Following are some useful functions && comments of sample return values: $t->hms # [12, 34, 56] $t->hmsf # [12, 34, 56, 12] $t->time # same as $t->hmsf $t->ymd # [2000, 2, 29] $t->date # same as $t->ymd $t->mdy # [ 2, 29, 2000] $t->dmy # [29, 2, 2000] $t->datetime # 2000-02-29T12:34:56 (ISO 8601) $t->expand # Tue Feb 29 12:34:56:12 2000 $t->cdate # same as $t->expand $t->compress # 02TCYuC "$t" # same as $t->compress $t->is_leap_year # true if it is $t->month_last_day # 28-31 $t->time_separator($s) # set the default separator (default ":") $t->date_separator($s) # set the default separator (default "-") $t->day_list(@days) # set the default weekdays $t->mon_list(@days) # set the default months Local Locales Both wdayname() && monname() can accept the same list parameter as day_list() && mon_list() respectively for temporary help with simple localization. my @days = ( 'Yom Rishone', 'Yom Shayni', 'Yom Shlishi', 'Yom Revi\'i', 'Yom Khahmishi', 'Yom Hashishi', 'Shabbat' ); my $hebrew_day = pt->wdayname(@days); # pt->monname() can be used similarly To update the global lists, use: Time::PT::day_list(@days); && Time::PT::mon_list(@months); Calculations PT object strings (both in normal initialization && printing) grow left-to-right starting from the Year to specify whatever precision you need while Frame objects grow right-to-left from the frame field. It's possible to use simple addition and subtraction of objects: use Time::Frame; my $cur_pt = Time::PT->new();# Dhmsf my $one_week = Time::Frame->new('70000'); my $one_week_ago = $cur_pt - $one_week; If a calculation is done with a raw string parameter instead of an instantiated object, the most likely appropriate object constructor is called on it. These init strings must adhere to the implied 'str' format for auto-creating objects; I aim to support a much wider array of operations && to interoperate with Time::Piece && Time::Seconds someday but not yet. my $cur_pt = Time::PT->new();# Dhmsf my $half_hour_from_now = $cur_pt + 'U00'; The following are valid (where $t0 and $t1 are Time::PT objects && $f is a Time::Frame object): $t0 - $t1; # returns Time::Frame object $t0 - '63'; # returns Time::PT object $t0 + $f; # returns Time::PT object Comparisons All normal numerical && string comparisons should work reasonably on Time::PT objects: "<", ">", "<=", ">=", "<=>", "==" && "!=" "lt", "gt", "le", "ge", "cmp", "eq" and "ne" YYYY-MM-DDThh:mm:ss The ISO 8601 standard defines the date format to be YYYY-MM-DD, and the time format to be hh:mm:ss (24 hour clock), and if combined, they should be concatenated with date first and with a capital 'T' in front of the time. Week Number The ISO 8601 standard specifies that weeks begin on Monday and the first week of the year is the one that includes both January 4th and the first Thursday of the year. In other words, if the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of the final week of the prior year. Week numbers range from 1 to 53. NOTES Whenever individual Time::PT attributes are going to be printed or an entire object can be printed with multi-colors, the following mapping should be employed whenever possible: D Century -> DarkRed A Year -> Red T Month -> Orange E Day -> Yellow hour -> Green t minute -> Cyan i second -> Blue m frame -> Purple e jink -> DarkPurple zone -> Grey or White Please see the color() member function in the USAGE section. There's some weird behavior for PipTimes created with a zero month or day field since both are 1-based. I aim to fix all these bugs but be warned that this issue may be causing math errors for a bit. I hope you find Time::PT useful. Please feel free to e-mail me any suggestions || coding tips || notes of appreciation ("app-ree-see-ay-shun"). Thank you. TTFN. CHANGES Revision history for Perl extension Time::PT: - 1.0.41M4cZH Thu Jan 22 04:38:35:17 2004 * added Time::Frame::total_frames method, moved pt, fpt, && lspt into bin/ for packaging as EXE_FILES - 1.0.418BGcv Thu Jan 8 11:16:38:57 2004 * added HOW? POD section for mnemonics, created Time::Fields::_field_colors (centralized base class color codes) && updated Frame && PT _color_fields, moved Curses::Simp::ptCC into Time::PT::ptcc for PipTime-specific Simp Color Codes - 1.0.3CVL3V4 Wed Dec 31 21:03:31:04 2003 * changed PREREQ to not have lib files from this pkg - 1.0.3CQ8ibf Fri Dec 26 08:44:37:41 2003 * fixed typo && hardcoded path in VERSION_FROM of gen'd Makefile.PL - 1.0.3CNNQHc Tue Dec 23 23:26:17:38 2003 * combined Fields, Frame, && PT into one pkg - 1.0.3CCA2VC Fri Dec 12 10:02:31:12 2003 * removed indenting from POD NAME section - 1.0.3CBIQv7 Thu Dec 11 18:26:57:07 2003 * updated test.pl to use normal comments - 1.0.3CB7Vxh Thu Dec 11 07:31:59:43 2003 * added HTML color option && prepared for release - 1.0.3CA8ipi Wed Dec 10 08:44:51:44 2003 * built class to inherit from Time::Fields && mimic Time::Piece - 1.0.37VG26k Thu Jul 31 16:02:06:46 2003 * original version INSTALL Please run: `perl -MCPAN -e "install Time::PT"` or uncompress the package && run the standard: `perl Makefile.PL; make; make test; make install` FILES Time::PT requires: Carp to allow errors to croak() from calling sub Math::BaseCnv to handle simple number-base conversion Time::DayOfWeek also stores global day && month names Time::DaysInMonth Time::Fields to provide underlying object structure Time::Frame to represent spans of time Time::PT uses (if available): Time::HiRes to provide subsecond time precision Time::Local to turn epoch seconds back into a real date Time::Zone not utilized yet SEE ALSO Time::Frame LICENSE Most source code should be Free! Code I have lawful authority over is && shall be! Copyright: (c) 2003, Pip Stuart. All rights reserved. Copyleft : I license this software under the GNU General Public License (version 2). Please consult the Free Software Foundation (http://www.fsf.org) for important information about your freedom. AUTHOR Pip Stuart