User:Ric Sherlock/Extend Dates Project/DatesAdd Script
Jump to navigation
Jump to search
This is my attempt at extending the current dates.ijs script.
Example Use
Dates and Day Number
load '~Projects/utils/datesadd.ijs' ]now=: 6!:0 '' 2009 9 10 12 31 35.399 toDayNumber now 76588.5219375 J0Date_rgsdates_ + toDayNumber now 2455085.52194 toJulian toDayNumber now 2455085.52194 toDayNumber 3# ,: now 76588.5219375 76588.5219375 76588.5219375 1 toDayNumber 20090907.133031267 76585.5628619 1 toDayNumber 3# 20090907.133031267 76585.5628619 76585.5628619 76585.5628619 toDateTime toDayNumber now 2009 9 10 12 31 35.399 1 toDateTime toDayNumber now 20090910.1231
Formating Dates
fmtDate toDayNumber now September 10, 2009 'DDDD, D MMMM YYYY' fmtDate toDayNumber now Thursday, 10 September 2009 '\Day: D, \Month: M, Year: YY' fmtDate toDayNumber now Day: 10, Month: 9, Year: 09 'DDD, MMM DD, YYYY' fmtDate toDayNumber now Thu, Sep 10, 2009 'DD/MM/YYYY' fmtDate toDayNumber now 10/09/2009 'D/M/YY' fmtDate toDayNumber now 10/9/09
Formating Times
fmtTime 0 60 60#. _3{. now 12:31:35 pm 'hh:mm:ss' fmtTime 0 60 60#. _3{. now 12:31:35 fmtTime 65101.201 16542.081 85421.246 ┌──────────┬──────────┬───────────┐ │6:05:01 pm│4:35:42 am│11:43:41 pm│ └──────────┴──────────┴───────────┘ 'Ti\me\s: hh\\mm\\ss' fmtTime 65101.201 16542.081 85421.246 ┌───────────────┬───────────────┬───────────────┐ │Times: 18\05\01│Times: 04\35\42│Times: 23\43\41│ └───────────────┴───────────────┴───────────────┘ 'hh:mm:ss:ccc' fmtTime 65101.201 16542.081 85421.246 ┌────────────┬────────────┬────────────┐ │18:05:01:201│04:35:42:081│23:43:41:246│ └────────────┴────────────┴────────────┘
Script
Intro
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Script for extending the dates.ijs system script. NB. Ric Sherlock, 2009 09 09 NB. Some of the verbs in this script were derived from NB. APL+Win functions written by Davin Church. require 'dates numeric strings dll' coclass 'rgsdates' NB. ========================================================= NB. Existing Verbs: NB. fmtTime - custom string representations of times NB. fmtDate - custom string representations of dates NB. toDateTime - extend todate to handle times too NB. toDayNumber - extend todayno to handle times too NB. toJdayno - convert Julian dayno to J dayno NB. toJulian - convert J dayno to Julian dayno NB. getTimeZoneInfo - retrieves time zone info on Windows NB. ========================================================= NB. TO DO... NB. * Convert to J Project NB. * Create test suite NB. * Add following verbs: NB.*getDateTime v Extend getdate to handle converting date strings with time NB.*fmtDateTime v Formats combined date and time strings NB.*getDateTimeDiff v dayno y - dayno x in <YYYY MM DD hh mm ss.sss> format NB. result: numeric time difference of x-y in <YYYY MM DD hh mm ss.sss> format NB. y is: start date,time as DayNumber NB. x is: end date,time as DayNumber NB. could extend to accept <YYYY MM DD hh mm ss.sss> format as inputs NB.*fmtTimeDiff v Formated time difference NB. y is: time difference in <YYYY MM DD hh mm ss.sss> format NB. x is: format string NB. eg: 'Y year\s, M \months DDD days' fmtTimeDiff y NB. eg: 'D day\s' fmtTimeDiff y NB. Handle part units for smallest specified unit in format string: NB. Truncate, round, decimal NB. How to specify? NB. -additional option to format string eg: NB. [format string[;0 or 1 or 2]] fmtTimeDiff y NB. -or part of format string NB. * decimal: YYY, MMM, DDD, hhh, mmm, sss NB. * round (to nearest unit): YY, MM, DD, hh, mm, ss NB. * truncate (only complete units): Y, M, D, h, m, s
Utility Verbs
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Utility verbs NB.*escaped v process an escaped string NB. result: 2-item list of boxed mask & string: NB. 0{:: boolean mask of non-escaped characters NB. 1{:: string with escape character compressed out NB. y is: An escaped string NB. x is: character used to escape string NB. eg: '\' escaped '\Date is: D\\MM\\YYYY' escaped=: 3 : 0 '\' escaped y NB. default escape char : mskesc=. y = x mskfo=. 2 < /\ 0&, mskesc NB. 1st occurences of x mskesc=. mskesc ([ ~: *.) 0,}: mskfo NB. unescaped 1st occurences of x mskunescaped=. -. 0,}: mskesc NB. unescaped characters (-.mskesc)&# &.> mskunescaped;y NB. compress out unescaped x ) fmt=: 8!:0
Constants
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Constants J0Date=: 2378497 NB. add to J's dayno to get Julian dayno NB. Note that the start of a Julian day is noon so for an NB. accurate representation of a Julian day/time combination NB. 2378496.5 should be added instead. MS0Date=: 36522 NB. add to Microsoft date to get a J dayno. NB. Note that the first date supported by Microsoft Excel is 1900 1 1 NB. but dates between 1900 1 1 and 1900 1 28 will not convert properly NB. because Excel incorrectly denotes 1900 as a leap year, NB. http://support.microsoft.com/kb/214326 Linux0DateTime=: 62091 NB. add to Linux-style date to get a J dayno WKDAYS=: ;:'Sunday Monday Tuesday Wednesday Thursday Friday Saturday' MONTHS=: ''; ;:'January February March April May June July August September October November December'
Dates and Day Numbers
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Verbs for converting between dates and daynumbers NB.*toDayNumber v Extends verb "todayno" to handle time NB. eg: toDayNumber 6!:0 '' NB. result: numeric array as J daynos, decimals represent time NB. y is: numeric array in date/time format specified by x NB. x is: optional boolean specifying input format. Default 0. NB. 0 : date/time format <yyyy mm dd hh mm ss.sss> NB. 1 : date/time format <yyyymmdd.hhmmss.sss> NB. Dates before 1800 1 1 are not supported toDayNumber=: 3 : 0 0 toDayNumber y : ymd=. y if. x do. NB. form <yyyymmdd.hhmmss> hms=. 0 100 100 #: 1e_2 round 1e6 * 1||ymd ymd=. 0 100 100 #: <.ymd else. NB. form <yyyy mm dd hh mm ss.sss> hms=. 3({."1) 3}."1 ymd ymd=. 3{."1 |ymd end. hms=. 86400 %~ 0 60 60 #. hms NB. to proportion of a day dayn=. 0 todayno ymd dayn+hms ) NB.*toDateTime v Extends verb "todate" to handle time NB. eg: 1 toDateTime toDayNumber 6!:0 '' NB. result: numeric array in date/time format specified by x NB. y is: array of J day numbers NB. x is: optional boolean specifying output format. Default 0. NB. 0 : date/time format <yyyy mm dd hh mm ss.sss> NB. 1 : date/time format <yyyymmdd.hhmmss.sss> NB. Dates before 1800 1 1 are not supported toDateTime=: 3 : 0 0 toDateTime y : dayno=. y hms=. 1e_3 round 86400 * 1||dayno NB. get any decimal component dayno=. <.|dayno NB. drop any decimal ymd=. x todate dayno NB. get date component from todate if. x do. NB. yyyymmdd.hhmmsssss hms=. 1e_6 * 0 100 100#. 0 60 60#: hms NB. convert to 0.hhmmsssss ymd=. ymd + hms else. NB. yyyy mm dd hh mm ss.sss hms=. 0 60 60 #: hms NB. convert to hh mm ss.sss ymd=. ymd ,"1 hms end. ymd ) NB.*toJulian v converts J day number to Julian day number NB. eg: toJulian tDayNumber 6!:0 '' NB. Dates before 1800 1 1 are not supported NB. Add another 0.5 to get true Julian Day number where noon is NB. regarded as the "start" of the day. toJulian=: +&J0Date NB.*fromJulian v converts Julian day number to J day number NB. eg: fromJulian toJulian tDayNumber 6!:0 '' NB. Dates before 1800 1 1 are not supported toJdayno=: -&J0Date
Formatting Dates and Times
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Verbs for formating string reprentations of Dates and Times NB.*fmtDate v Format a date in a given format NB. eg: '\Date is: DDDD, D MMM, YYYY' fmtDate toDayNumber 6!:0'' NB. result: formated date string (or array of boxed, formated date strings) NB. y is: numeric array of dates given as Day Numbers NB. x is: optional format string specifing format of result NB. Use the following codes to specify the date format: NB. D: 1 DD: 01 DDD: Sun DDDD: Sunday NB. M: 1 MM: 01 MMM: Jan MMMM: January NB. YY: 09 YYYY: 2009 NB. To display any of the letters (DMY) that are codes, NB. "escape" them with '\' fmtDate=: 3 : 0 'MMMM D, YYYY' fmtDate y : codes=. ;:'D DD DDD DDDD M MM MMM MMMM YY YYYY' pic=. x 'unesc pic'=. '\' escaped pic pic=. (1 , 2 ~:/\unesc *. pic e. 'DMY') <;.1 pic NB. Cut into tokens var=. pic e. codes NB. mark sections as vars ymd=. |: todate <.,y t=. 2{ymd NB. Days values=. ('';'r<0>2.0') fmt"0 1 t t=. (7|3+<.,y){WKDAYS NB. Day names values=. values,(3&{.&.> ,: ]) t t=. 1{ymd NB. Months values=. values, ('';'r<0>2.0') fmt"0 1 t t=. (0>.t){MONTHS NB. Month names values=. values, (3&{.&.> ,: ]) t t=. 0{ymd NB. Years values=. values, (2&}.&.> ,: ]) fmt t res=. <@;"1 (|:(codes i. var#pic){values) (I. var)}"1 pic if. 0=#$y do. res=. ,>res else. res=. ($y)$ res end. res ) NB.*fmtTime v Format a time (in seconds) in a given format. NB. eg: 'Ti\me i\s: hh:mm:ss' fmtTime 86400 * 1|toDayNumber 6!:0 '' NB. result: formated time string (or array of boxed, formated time strings) NB. y is: numeric array of times given as time in seconds since start of the day NB. x is: optional format string specifing format of result NB. Use the following codes to specify the date format: NB. days ("d"), hours ("h"), minutes ("m"), seconds ("s"), NB. fractions of a second ("c"), or AM/PM designator ("p"): NB. d: 1 h: 1 m: 1 s: 1 c: 1 p: a NB. hh: 01 mm: 01 ss: 01 cc: 01 pp: am NB. sss: 1.2 ccc: 001 NB. If no "p" designator is present, 24 hour format is used. NB. To display any of the letters (DMY) that are codes, NB. "escape" them with '\' fmtTime=: 3 : 0 'h:mm:ss pp' fmtTime y : codes=. ;:'d h hh m mm s ss sss c cc ccc p pp' pic=. x 'unesc pic'=. '\' escaped pic dcp=. 'dcp' e. pic NB. are days, millisecs, am/pm present pic=. (1 , 2 ~:/\unesc *. pic e. 'dhmscp') <;.1 pic NB. Cut into tokens var=. pic e. codes NB. mark sections as vars dhms=. |:(0,(24*0{dcp),60 60) #: <. 0 >. , y NB. to lists of D,H,M,:S ccc=. 1e_3 round 1 | 0 >. , y NB. milliseconds values=. ,:fmt 0{dhms NB. Days t=. (1{dhms) (] + 12&*@] | -) 2{dcp NB. Hours, 12/24 hour formats values=. values,('';'r<0>2.0') fmt"0 1 t t=. 2{dhms NB. Minutes values=. values,('';'r<0>2.0') fmt"0 1 t t=. 3{dhms NB. Seconds values=. values,('';'r<0>2.0') fmt"0 1 t values=. values, fmt t+ccc NB. sss t=. 100 10 1 round"0 1 ccc * 1000 NB. c, cc, ccc values=. values, 1 2 3 {.&.> 'r<0>3.0' fmt t t=. (12<:24|1{dhms){ ;:'am pm' NB. am/pm values=. values,(1&{.&.> ,: ]) t res=. <@;"1 (|:(codes i. var#pic){values) (I. var)}"1 pic if. 0=#$y do. res=. ,>res else. res=. ($y)$ res end. res )
Time Zone Information
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Verbs for working with time zones NB.*getTimeZoneInfo v function to return Windows time zone info NB. result: 3-item list of boxed info NB. 0{:: Daylight saving status (0 unknown, 1 standarddate, 2 daylightdate) NB. 1{:: Bias (offset of local zone from UTC in minutes) NB. 2{:: 2 by 3 boxed table: Standard,Daylight by Name,StartDate,Bias NB. eg: getTimeZoneInfo '' getTimeZoneInfo=: 3 : 0 'tzstatus tzinfo'=. 'kernel32 GetTimeZoneInformation i *i'&cd <(,43#0) NB. read TIME_ZONE_INFORMATION structure tzinfo=. (1 (<:+/\ 1 16 4 1 16 4 1)}43#0) <;.2 tzinfo NB. 4 byte J integers tzbias=. 0{:: tzinfo tzinfo=. _3]\ }. tzinfo NB. Standard info ,: Daylight info 'name date bias'=. i. 3 NB. column labels for tzinfo tmp=. (6&u:)@(2&ic)&.> name {"1 tzinfo NB. read names as unicode text tmp=. (0{a.)&taketo&.> tmp NB. take to first NUL tzinfo=. tmp (<a:;name)}tzinfo NB. amend TZ names tmp=. _1&ic@(2&ic)&.> date{"1 tzinfo NB. read SYSTEMTIME structures tzinfo=. tmp (<a:;date)}tzinfo NB. amend TZ dates tzstatus;tzbias;<tzinfo )
Export and Testing
[{{#file: "datesadd.ijs"}} Download script: datesadd.ijs ]
NB. ========================================================= NB. Export to z locale fmtTime_z_ =: fmtTime_rgsdates_ fmtDate_z_ =: fmtDate_rgsdates_ toDayNumber_z_ =: toDayNumber_rgsdates_ toDateTime_z_ =: toDateTime_rgsdates_ toJulian_z_ =: toJulian_rgsdates_ toJdayno_z_=: toJdayno_rgsdates_ NB. ========================================================= NB. Example usage and Testing Note 'Examples/Tests' ]now=: 6!:0 '' toDayNumber now J0Date_rgsdates_ + toDayNumber now toJulian toDayNumber now (1e_10 > ] - toDateTime@toJdayno@toJulian@toDayNumber) now toDayNumber 3# ,: now 1 dJulian 20090907.133031267 1 toDayNumber 20090907.133031267 1 toDayNumber 3# 20090907.133031267 toDateTime toDayNumber now 1 toDateTime toDayNumber now assert (toDayNumber now)(0.01 > |@:-) 1 toDayNumber 1&toDateTime toDayNumber now fmtDate toDayNumber now 'DDDD, D MMMM YYYY' fmtDate toDayNumber now '\Day: D, \Month: M, Year: YY' fmtDate toDayNumber now 'DDD, MMM DD, YYYY' fmtDate toDayNumber now 'DD/MM/YYYY' fmtDate toDayNumber now 'D/M/YY' fmtDate toDayNumber now fmtTime 0 60 60#. _3{. now 'hh:mm:ss' fmtTime 0 60 60#. _3{. now fmtTime 65101.201 16542.081 85421.246 'Ti\me\s: hh\\mm\\ss' fmtTime 65101.201 16542.081 85421.246 'hh:mm:ss:ccc' fmtTime 65101.201 16542.081 85421.246 require '~Projects/utils/dcdates.ijs' 'h:m:s:c' (fmtTime -: tSpell) 65101.201 16542.081 85421.246 16542.081 'h:m:s:c' (fmtTime -: tSpell) 65101.201 )