stt.fun 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #import std
  2. #import nat
  3. #import int
  4. #comment -[
  5. This module contains two functions for converting between natural
  6. numbers expressing times in seconds since midnight January 1, 1970 and
  7. strings of the form 'Fri Mar 18 1:58:31 2005 +0100'. The time zone
  8. abbreviation is ignored, but time zones can be specified as +0500,
  9. etc.. Days of the week are output correctly but ignored in the input.
  10. Fields can be written in any order but must be separated by spaces.
  11. Commas are optional.
  12. Copyright (C) 2007-2009 Dennis Furey]-
  13. #library+
  14. one_time = 'Fri Mar 18 01:58:31 UTC 2005'
  15. #library-
  16. months = block3 'JanFebMarAprMayJunJulAugSepOctNovDec'
  17. #optimize+
  18. mlen = # the number of days in a given month in the range 0..4799, with 0 corresponding to January 1970
  19. -: ^(~&,division\12; 1?=r(@l ||28! -&~&itB,~&hZthPB,~<{130,230,330},29!&-,{3,5,8,10}?<r/30! 31!))* iota 4800
  20. mdiv = @NiX ^= zleq?r(^|/successor difference@rlX,~&lrrPX)^/~&l ^|/mlen ~&
  21. # seconds and slots use a simpler algorithm for the first 128 years, during which leap years happen every 4 years
  22. seconds = # takes a list like <2009,'Aug',13,20,27,37>
  23. -+
  24. sum^|\~& division\4800; sum^|(product/12622780800,~&)^|/~& product/86400+ zleq/1536?(
  25. iota; sum:-0+ mlen*,
  26. division\48; sum^|/(product/1461) -: num ^NiC(~&h,~&ar^& ^rlfPrlart3XRC/~& sum@alrhPX) mlen* iota 48),
  27. ^(sum@hthPX,~&tth)^|C/(product/12+ difference\1970) ^|lrNCC(
  28. -:@rlXS (^T/num --+ (num^~ (*+ *)^~(~&K30K31piK26,~&K31K30piK26) letters)) months,
  29. sum:-0+ product*p/<86400,3600,60,1>+ ^|C/predecessor ~&)+-
  30. slots = # takes a time in seconds to a list like <2009,'Aug',13,20,27,37>
  31. division\12622780800; ^C(sum/1970+ sum^/~&rh product/400+ ~&l,~&rt)^|/~& -+
  32. ^|T\~& division\12; ^|lrNCC/~& -: num months,
  33. ^|T\~& ^|lrNCC(~&,successor)+ zleq/46752?/mdiv division\1461; ^(sum@lrlPX,~&rr)^|\mdiv product/48,
  34. division\86400; ^|C/~& division\3600; ^|lrlrNCCPC/~& division\60+-
  35. #library+
  36. time_to_string =
  37. -+
  38. ^|(~&,%nP*=); ^|T/(^|T/~& :/` ) :/` + ^T\~&h --' UTC '+ @t ^|T(~&t?/~& :/` ,:/` + mat`:+ * ~&t?/~& :/`0),
  39. ^lrth2XrhttPCPX\slots quotient\86400; remainder\7; -: num block3'ThuFriSatSunMonTueWed'+-
  40. string_to_time = # fields are allowed in any order; time zone abbreviations and day of week are ignored
  41. guard\<'bad date format'>! ','%=' '; sep` ; seconds^T(
  42. <.eql/;15; ~&i&& %np,~&h+ *~ \/-= months,leql\;3; ~&i&& %np>,
  43. ^C(sum@lrhPX,~&rt)^/(-&~&,@hyy %zp@iNC+ `+?=h\~& ~&t&-+ *~ eql/31&& ~&ihB-='+-') %np*iNCS+ sep`:@ihB+ ~&w/;`:)